From ea0e59786cb4e499b04db796089edef906b5598d Mon Sep 17 00:00:00 2001 From: san Date: Mon, 6 Feb 2006 13:21:10 +0000 Subject: [PATCH] Modifications from BR_L_2_3_5 branch (except HDF persistance for LightApp!) --- src/GLViewer/GLViewer_Drawer.cxx | 253 ++++++++++++++++---------- src/GLViewer/GLViewer_Drawer.h | 64 ++++++- src/GLViewer/GLViewer_Object.h | 2 +- src/GLViewer/GLViewer_ViewPort.cxx | 2 +- src/GLViewer/GLViewer_Viewer2d.cxx | 2 + src/GLViewer/GLViewer_Viewer2d.h | 5 + src/LightApp/LightApp_Application.cxx | 2 + src/LightApp/LightApp_Driver.cxx | 34 +++- src/LightApp/LightApp_Driver.h | 16 +- src/LightApp/LightApp_Study.cxx | 20 +- src/LightApp/Makefile.in | 8 +- src/Plot2d/Plot2d_ViewFrame.cxx | 22 +-- src/Plot2d/resources/Plot2d_msg_en.po | 9 + src/STD/STD_Application.cxx | 22 +-- src/SUIT/SUIT_Application.h | 4 +- 15 files changed, 312 insertions(+), 153 deletions(-) diff --git a/src/GLViewer/GLViewer_Drawer.cxx b/src/GLViewer/GLViewer_Drawer.cxx index 3ebadab54..9a0f3ef6b 100644 --- a/src/GLViewer/GLViewer_Drawer.cxx +++ b/src/GLViewer/GLViewer_Drawer.cxx @@ -39,15 +39,14 @@ #include #define TEXT_GAP 5 +// Two texture components for texmapped fonts: luminance and alpha +#define NB_TEX_COMP 2 +// A font is split into rows each containing 32 characters +#define TEX_ROW_LEN 32 +// Gap in pixels between two character rows in a font texture +#define TEX_ROW_GAP 2 -GLboolean TFLoaded = GL_FALSE; - -GLdouble modelMatrix[16], projMatrix[16]; -GLint viewport[4]; -GLdouble winx, winy, winz; -GLint status; - -GLViewer_TexFont* staticGlFont; +GLfloat modelMatrix[16]; //================================================================ // Class : GLViewer_TexFont @@ -77,24 +76,14 @@ void GLViewer_TexFont::clearTextBases() // Purpose : //======================================================================= GLViewer_TexFont::GLViewer_TexFont() +: myMaxRowWidth( 0 ), myFontHeight( 0 ) { myQFont = QFont::defaultFont(); - QFontMetrics aFM( myQFont ); - myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1]; - myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1]; mySeparator = 2; - for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ ) - { - myWidths[ k - FirstSymbolNumber ] = aFM.width( k ); - myPositions[ k - FirstSymbolNumber ] = aWidth; - aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator; - } - - myTexFontWidth = 0; - myTexFontHeight = 0; myIsResizeable = false; - //myMinMagFilter = GL_NEAREST; - myMinMagFilter = GL_LINEAR_ATTENUATION ; + myMinMagFilter = GL_LINEAR; + + init(); } //====================================================================== @@ -102,24 +91,14 @@ GLViewer_TexFont::GLViewer_TexFont() // Purpose : //======================================================================= GLViewer_TexFont::GLViewer_TexFont( QFont* theFont, int theSeparator, bool theIsResizeable, GLuint theMinMagFilter ) +: myMaxRowWidth( 0 ), myFontHeight( 0 ) { myQFont = *theFont; - QFontMetrics aFM( myQFont ); - myWidths = new int[LastSymbolNumber - FirstSymbolNumber+1]; - myPositions = new int[LastSymbolNumber - FirstSymbolNumber+1]; mySeparator = theSeparator; - for( int k = FirstSymbolNumber, aWidth = 0; k <= LastSymbolNumber; k++ ) - { - myWidths[ k - FirstSymbolNumber ] = aFM.width( k ); - myPositions[ k - FirstSymbolNumber ] = aWidth; - aWidth += myWidths[ k - FirstSymbolNumber ] + 2;//mySeparator; - } - - myTexFontWidth = 0; - myTexFontHeight = 0; myIsResizeable = theIsResizeable; myMinMagFilter = theMinMagFilter; - + + init(); } //====================================================================== @@ -131,17 +110,56 @@ GLViewer_TexFont::~GLViewer_TexFont() delete[] myWidths; delete[] myPositions; } + +//====================================================================== +// Function: init +// Purpose : +//======================================================================= +void GLViewer_TexFont::init() +{ + myNbSymbols = LastSymbolNumber - FirstSymbolNumber + 1; + + // It is unsafe to draw all characters in a single row - + // this leads to problems on some graphic cards with small GL_MAX_TEXTURE_SIZE. + // So splitting the characters into rows each containing 32 characters (or less). + // Assuming contant height of each row (64 pixels) to simplify texture mapping. + // However, this can be improved if necessary. + QFontMetrics aFM( myQFont ); + myFontHeight = aFM.height(); + + myWidths = new int[myNbSymbols]; + myPositions = new int[myNbSymbols]; + + for( int i = 0, k = FirstSymbolNumber, aWidth = 0; i < myNbSymbols; i++, k++ ) + { + // is it time to start a new row? + if ( !( i % TEX_ROW_LEN ) ) + { + if( aWidth > myMaxRowWidth ) + myMaxRowWidth = aWidth; + aWidth = 0; + } + myWidths[i] = aFM.width( k ); + myPositions[i] = aWidth; + aWidth += myWidths[i] + 2; + } + + myTexFontWidth = 0; + myTexFontHeight = 0; +} //====================================================================== // Function: generateTexture // Purpose : //======================================================================= -void GLViewer_TexFont::generateTexture() +bool GLViewer_TexFont::generateTexture() { - QFontMetrics aFM( myQFont ); - GLViewer_TexFindId aFindFont; - aFindFont.myFontString = myQFont.toString(); + aFindFont.myFontFamily = myQFont.family();//myQFont.toString(); + aFindFont.myIsBold = myQFont.bold(); + aFindFont.myIsItal = myQFont.italic(); + aFindFont.myIsUndl = myQFont.underline(); + aFindFont.myPointSize = myQFont.pointSize(); aFindFont.myViewPortId = (int)QGLContext::currentContext(); if( TexFontBase.contains( aFindFont ) ) @@ -153,34 +171,51 @@ void GLViewer_TexFont::generateTexture() } else { - QString aStr; - int pixelsWidth = 0; - int pixelsHight = aFM.height(); - myTexFontWidth = 64; + // Adding some pixels to have a gap between rows + int aRowPixelHeight = myFontHeight + TEX_ROW_GAP; + int aDescent = QFontMetrics( myQFont ).descent(); + + int aNumRows = myNbSymbols / TEX_ROW_LEN; + if ( myNbSymbols % TEX_ROW_LEN ) + aNumRows++; + int pixelsHight = aNumRows * aRowPixelHeight; + + myTexFontWidth = 64; myTexFontHeight = 64; - - pixelsWidth = myWidths[LastSymbolNumber - FirstSymbolNumber] + - myPositions[LastSymbolNumber - FirstSymbolNumber]; - while( myTexFontWidth < pixelsWidth ) - myTexFontWidth = myTexFontWidth * 2; + while( myTexFontWidth < myMaxRowWidth ) + myTexFontWidth <<= 1; while( myTexFontHeight < pixelsHight ) - myTexFontHeight = myTexFontHeight * 2; + myTexFontHeight <<= 1; + + // Checking whether the texture dimensions for the requested font + // do not exceed the maximum size supported by the OpenGL implementation + int maxSize; + glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxSize ); + if ( myTexFontWidth > maxSize || myTexFontHeight > maxSize ) + return false; QPixmap aPixmap( myTexFontWidth, myTexFontHeight ); aPixmap.fill( QColor( 0, 0, 0) ); QPainter aPainter( &aPixmap ); aPainter.setFont( myQFont ); - for( int l = 0/*, gap = 0*/; l < LastSymbolNumber - FirstSymbolNumber; l++ ) + int row; + for( int l = 0; l < myNbSymbols; l++ ) { + row = l / TEX_ROW_LEN; QString aLetter; aLetter += (char)(FirstSymbolNumber + l); aPainter.setPen( QColor( 255,255,255) ); - aPainter.drawText ( myPositions[l], pixelsHight, aLetter ); + aPainter.drawText( myPositions[l], ( row + 1 ) * aRowPixelHeight - aDescent, aLetter ); } QImage aImage = aPixmap.convertToImage(); - char* pixels = new char[myTexFontWidth * myTexFontHeight * 2]; + + //int qqq = 0; + //if (qqq) + // aImage.save("w:\\work\\CATHARE\\texture.png", "PNG"); + + char* pixels = new char[myTexFontWidth * myTexFontHeight * NB_TEX_COMP]; for( int i = 0; i < myTexFontHeight; i++ ) { @@ -192,13 +227,13 @@ void GLViewer_TexFont::generateTexture() if( aRed != 0 || aGreen != 0 || aBlue != 0 ) { - pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte)( (aRed + aGreen + aBlue)/3 ); - pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 255; + pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP] = (GLubyte)( (aRed + aGreen + aBlue)/3 ); + pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP + 1]= (GLubyte) 255; } else { - pixels[i * myTexFontWidth * 2 + j * 2] = (GLubyte) 0; - pixels[i * myTexFontWidth * 2 + j * 2 + 1]= (GLubyte) 0; + pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP] = (GLubyte) 0; + pixels[i * myTexFontWidth * NB_TEX_COMP + j * NB_TEX_COMP + 1]= (GLubyte) 0; } } } @@ -206,11 +241,8 @@ void GLViewer_TexFont::generateTexture() glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, &myTexFont); glBindTexture(GL_TEXTURE_2D, myTexFont); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myMinMagFilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myMinMagFilter); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, @@ -230,33 +262,35 @@ void GLViewer_TexFont::generateTexture() TexFontBase.insert( aFindFont, aTexture ); } + return true; } //====================================================================== // Function: drawString // Purpose : //======================================================================= -void GLViewer_TexFont::drawString( QString theStr, GLdouble theX , GLdouble theY ) +void GLViewer_TexFont::drawString( QString theStr, GLdouble theX , GLdouble theY, GLfloat theScale ) { - double aXScale = 1., aYScale = 1.; - // store attributes - glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT ); + // Adding some pixels to have a gap between rows + int aRowPixelHeight = myFontHeight + TEX_ROW_GAP; + float aXScale = 1.f, aYScale = 1.f; if ( !myIsResizeable ) { - glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix); + glGetFloatv (GL_MODELVIEW_MATRIX, modelMatrix); aXScale = modelMatrix[0]; - aYScale = modelMatrix[5]; + aYScale = modelMatrix[5]; + } + else if ( theScale > 0.f ) + { + aXScale = aXScale / theScale; + aYScale = aYScale / theScale; } - glEnable(GL_TEXTURE_2D); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myMinMagFilter); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myMinMagFilter); + // store attributes + glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT ); + glEnable(GL_TEXTURE_2D); glPixelTransferi(GL_MAP_COLOR, 0); glAlphaFunc(GL_GEQUAL, 0.05F); @@ -266,27 +300,31 @@ void GLViewer_TexFont::drawString( QString theStr, GLdouble theX , GLdouble theY glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glBindTexture(GL_TEXTURE_2D, myTexFont); - glBegin(GL_QUADS); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - theY = theY - ( myTexFontHeight - QFontMetrics( myQFont ).height() ) / aYScale; + glBegin(GL_QUADS); - double aLettBegin, aLettEnd, aDY = ( myTexFontHeight - 1 ) / aYScale, aDX; + float aLettBeginS, aLettEndS, aLettBeginT, aLettEndT; + float aDY = ( aRowPixelHeight - 1 ) / aYScale, aDX; char aLetter; - int aLettIndex; + int aLettIndex, row; for( int i = 0; i < theStr.length(); i++ ) { aLetter = theStr.data()[i]; aLettIndex = (int)aLetter - FirstSymbolNumber; + row = aLettIndex / TEX_ROW_LEN; - aLettBegin = (double)myPositions[aLettIndex] / ( (double)myTexFontWidth - 1. ); - aLettEnd = aLettBegin + ( (double)myWidths[aLettIndex] - 1. ) / ( (double)myTexFontWidth - 1. ); + aLettBeginS = (float)myPositions[aLettIndex] / ( (float)myTexFontWidth - 1.f ); + aLettEndS = aLettBeginS + ( (float)myWidths[aLettIndex] - 1.f ) / ( (float)myTexFontWidth - 1.f ); + aLettBeginT = ( myTexFontHeight - ( row + 1 ) * aRowPixelHeight ) / ( (float)myTexFontHeight - 1.f ); + aLettEndT = aLettBeginT + ( (float)aRowPixelHeight - 1.f ) / ( (float)myTexFontHeight - 1.f ); - aDX = ( (double)myWidths[aLettIndex] - 1. ) / aXScale; + aDX = ( (float)myWidths[aLettIndex] - 1.f ) / aXScale; - glTexCoord2d( aLettBegin, 0.0 ); glVertex3d( theX, theY, 1.0 ); - glTexCoord2d( aLettBegin, 1.0 ); glVertex3d( theX, theY + aDY, 1.0 ); - glTexCoord2d( aLettEnd, 1.0 ); glVertex3d( theX + aDX, theY + aDY, 1.0 ); - glTexCoord2d( aLettEnd, 0.0 ); glVertex3d( theX + aDX, theY, 1.0 ); + glTexCoord2f( aLettBeginS, aLettBeginT ); glVertex3f( theX, theY, 1.f ); + glTexCoord2f( aLettBeginS, aLettEndT ); glVertex3f( theX, theY + aDY, 1.f ); + glTexCoord2f( aLettEndS, aLettEndT ); glVertex3f( theX + aDX, theY + aDY, 1.f ); + glTexCoord2f( aLettEndS, aLettBeginT ); glVertex3f( theX + aDX, theY, 1.f ); theX += aDX + mySeparator / aXScale; } @@ -326,10 +364,16 @@ int GLViewer_TexFont::getStringHeight() //! function for generation list base for bitmap fonts static GLuint displayListBase( QFont* theFont ) { + if ( !theFont ) + return 0; GLuint aList = 0; //static QMap fontCache; GLViewer_TexFindId aFindFont; - aFindFont.myFontString = theFont->toString(); + aFindFont.myFontFamily = theFont->family();//theFont->toString(); + aFindFont.myIsBold = theFont->bold(); + aFindFont.myIsItal = theFont->italic(); + aFindFont.myIsUndl = theFont->underline(); + aFindFont.myPointSize = theFont->pointSize(); #ifdef WIN32 HGLRC ctx = ::wglGetCurrentContext(); @@ -394,16 +438,17 @@ static GLuint displayListBase( QFont* theFont ) //glXUseXFont( (Font)(theFont->handle()), 0, 256, listBase ); int aFontCont = 0; - char** xFontList = XListFonts( aDisp, aFindFont.myFontString.data(), 1, &aFontCont ); + QString aFontDef = theFont->toString(); + char** xFontList = XListFonts( aDisp, aFontDef.latin1()/*aFindFont.myFontString.data()*/, 1, &aFontCont ); if( !theFont->handle() ) { #ifdef _DEBUG_ - printf( "Can't load font %s. loading default font....\n", aFindFont.myFontString.data() ); + printf( "Can't load font %s. loading default font....\n", aFontDef.latin1()/*aFindFont.myFontString.data()*/ ); #endif QString aFontMask ("-*-*-*-r-*-*-"); - aFontMask += aFindFont.myFontString.section( ',', 1, 1 ); + aFontMask += aFontDef/*aFindFont.myFontString*/.section( ',', 1, 1 ); #ifdef _DEBUG_ - printf( "Height of Default font: %s\n", aFindFont.myFontString.section( ',', 1, 1 ).data() ); + printf( "Height of Default font: %s\n", aFontDef/*aFindFont.myFontString*/.section( ',', 1, 1 ).data() ); #endif aFontMask += "-*-*-*-m-*-*-*"; xFontList = XListFonts( aDisp, aFontMask.data()/*"-*-*-*-r-*-*-12-*-*-*-m-*-*-*"*/, 1, &aFontCont ); @@ -447,6 +492,7 @@ GLViewer_Drawer::GLViewer_Drawer() myObjectType = "GLViewer_Object"; myPriority = 0; myTextFormat = DTF_BITMAP; + myTextScale = 0.125; } //====================================================================== @@ -718,8 +764,14 @@ void GLViewer_Drawer::drawText( const QString& text, GLfloat xPos, GLfloat yPos, if( theFormat != DTF_BITMAP ) { GLViewer_TexFont aTexFont( theFont, theSeparator, theFormat == DTF_TEXTURE_SCALABLE, GL_LINEAR ); - aTexFont.generateTexture(); - aTexFont.drawString( text, xPos, yPos ); + // Font texture was not found or generated --> cannot draw text + if ( !aTexFont.generateTexture() ) + return; + + if ( theFormat == DTF_TEXTURE_SCALABLE ) + aTexFont.drawString( text, xPos, yPos, textScale() ); + else + aTexFont.drawString( text, xPos, yPos ); } else { @@ -760,9 +812,11 @@ void GLViewer_Drawer::drawGLText( QString text, float x, float y, if( smallFont ) aFont.setPointSize( aFont.pointSize() * 0.8 ); + GLfloat scale = textScale() > 0. ? textScale() : 1.; + QFontMetrics aFontMetrics( aFont ); - float width = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.width( text ) : aFontMetrics.width( text ) / myXScale; - float height = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.height() : aFontMetrics.height() / myYScale; + float width = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.width( text ) * scale : aFontMetrics.width( text ) / myXScale; + float height = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.height() * scale : aFontMetrics.height() / myYScale; float gap = 5 / myXScale; switch( hPosition ) @@ -784,6 +838,21 @@ void GLViewer_Drawer::drawGLText( QString text, float x, float y, drawText( text, x, y, color, &aFont, 2, myTextFormat ); } +//====================================================================== +// Function: textRect +// Purpose : +//======================================================================= +GLViewer_Rect GLViewer_Drawer::textRect( const QString& text ) const +{ + GLfloat scale = textScale() > 0. ? textScale() : 1.; + + QFontMetrics aFontMetrics( myFont ); + float width = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.width( text ) * scale : aFontMetrics.width( text ); + float height = myTextFormat == DTF_TEXTURE_SCALABLE ? aFontMetrics.height() * scale : aFontMetrics.height(); + + return GLViewer_Rect( 0, width, height, 0 ); +} + //====================================================================== // Function: drawRectangle // Purpose : diff --git a/src/GLViewer/GLViewer_Drawer.h b/src/GLViewer/GLViewer_Drawer.h index d773d3bd2..4b66e7b20 100644 --- a/src/GLViewer/GLViewer_Drawer.h +++ b/src/GLViewer/GLViewer_Drawer.h @@ -68,15 +68,33 @@ struct GLVIEWER_API GLViewer_TexIdStored */ struct GLVIEWER_API GLViewer_TexFindId { - //! Font description - QString myFontString; + //! Font family description + QString myFontFamily; + //! Bold parameter + bool myIsBold; + //! Italic parameter + bool myIsItal; + //! Underline parameter + bool myIsUndl; + //! Font Size + int myPointSize; //! View POrt ID int myViewPortId; //! Overloaded operator for using struct as MAP key bool operator < (const GLViewer_TexFindId theStruct) const { - if ( myViewPortId != theStruct.myViewPortId ) return myViewPortId < theStruct.myViewPortId; - else return myFontString < theStruct.myFontString; + if ( myViewPortId != theStruct.myViewPortId ) + return myViewPortId < theStruct.myViewPortId; + else if ( myPointSize != theStruct.myPointSize ) + return myPointSize < theStruct.myPointSize; + else if ( myIsBold != theStruct.myIsBold ) + return myIsBold < theStruct.myIsBold; + else if ( myIsItal != theStruct.myIsItal ) + return myIsItal < theStruct.myIsItal; + else if ( myIsUndl != theStruct.myIsUndl ) + return myIsUndl < theStruct.myIsUndl; + else + return myFontFamily < theStruct.myFontFamily; } }; @@ -111,9 +129,12 @@ public: ~GLViewer_TexFont(); //! Generating font texture - void generateTexture(); + bool generateTexture(); //! Drawing string theStr in point with coords theX and theY - void drawString( QString theStr, GLdouble theX = 0.0, GLdouble theY = 0.0 ); + void drawString( QString theStr, + GLdouble theX = 0.0, + GLdouble theY = 0.0, + GLfloat theScale = 1.0 ); //! Returns separator between letters int getSeparator(){ return mySeparator; } @@ -132,8 +153,14 @@ public: static QMap TexFontBase; //! Map for strorage generated bitmaps fonts static QMap BitmapFontCache; + +private: + //! Initializes font parameters + void init(); -protected: +private: + //! Number of characters in the font texture + int myNbSymbols; //! Array of letter width int* myWidths; //! Array of letter positions in texture @@ -152,6 +179,10 @@ protected: bool myIsResizeable; //! Min/mag filter GLuint myMinMagFilter; + //! Font height + int myFontHeight; + //! Diagnostic information + int myMaxRowWidth; }; /*************************************************************************** @@ -360,11 +391,24 @@ public: /*! *\param format - the default text displaying format */ - inline void setTextFormat( DisplayTextFormat format ) { myTextFormat = format; } + inline void setTextFormat( const DisplayTextFormat format ) { myTextFormat = format; } //! Returns a default text displaying format used by drawGLText method inline DisplayTextFormat textFormat() const { return myTextFormat; } + //! Sets a text string displaying scale factor (used only with text format DTF_TEXTURE_SCALABLE) + /*! + *\param factor - scale factor + */ + inline void setTextScale( const GLfloat factor ) { myTextScale = factor; } + + //! Returns a text string displaying scale factor + inline GLfloat textScale() const { return myTextScale; } + + //! Returns a rectangle of text (without viewer scale) + GLViewer_Rect textRect( const QString& ) const; + + //! Draw rectangle with predefined color static void drawRectangle( GLViewer_Rect* theRect, QColor = Qt::black ); @@ -405,6 +449,10 @@ protected: QFont myFont; //! Default text displaying format for drawGLText() method DisplayTextFormat myTextFormat; + + //! Scale factor for text string draw, by default 0.125 + //! (used only with text format DTF_TEXTURE_SCALABLE) + GLfloat myTextScale; }; #ifdef WNT diff --git a/src/GLViewer/GLViewer_Object.h b/src/GLViewer/GLViewer_Object.h index 39c9d9883..6cd21b294 100644 --- a/src/GLViewer/GLViewer_Object.h +++ b/src/GLViewer/GLViewer_Object.h @@ -185,7 +185,7 @@ public: virtual bool finishMove() { return true; } //! Returns visible object status - bool getVisible() const { return myIsVisible; } + virtual bool getVisible() const { return myIsVisible; } //! Installs visible object status virtual void setVisible( bool theStatus ) { myIsVisible = theStatus; } diff --git a/src/GLViewer/GLViewer_ViewPort.cxx b/src/GLViewer/GLViewer_ViewPort.cxx index 973342f84..78767afa1 100644 --- a/src/GLViewer/GLViewer_ViewPort.cxx +++ b/src/GLViewer/GLViewer_ViewPort.cxx @@ -31,7 +31,7 @@ //#include -#if !defined WNT +#if !(defined WNT) && !(defined QT_CLEAN_NAMESPACE) #define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */ #endif diff --git a/src/GLViewer/GLViewer_Viewer2d.cxx b/src/GLViewer/GLViewer_Viewer2d.cxx index c7a1d297d..f98f5e2ae 100644 --- a/src/GLViewer/GLViewer_Viewer2d.cxx +++ b/src/GLViewer/GLViewer_Viewer2d.cxx @@ -969,6 +969,8 @@ void GLViewer_Viewer2d::startOperations( QWheelEvent* e ) update = anObject->updateZoom( zoomIn ) || update; } + emit wheelZoomChange( zoomIn ); + if( update ) updateAll(); } diff --git a/src/GLViewer/GLViewer_Viewer2d.h b/src/GLViewer/GLViewer_Viewer2d.h index 94a5bd254..21840335f 100644 --- a/src/GLViewer/GLViewer_Viewer2d.h +++ b/src/GLViewer/GLViewer_Viewer2d.h @@ -180,6 +180,11 @@ public: //! Repaints view \param theView. If \param theView = NULL repaints all views. void repaintView( GLViewer_ViewFrame* theView = NULL, bool makeCurrent = false ); +signals: + //! Signal needs for optimum recompute of zoom depending objects + //! Warning: use recompute without update viewer + void wheelZoomChange( bool ); + public slots: //void onSketchDelObject(); //void onSketchUndoLast(); diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 50f5fe543..ca93892ff 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -1210,6 +1210,8 @@ void LightApp_Application::onDesktopActivated() QString LightApp_Application::getFileFilter() const { return "(*.bin)"; + // HDF persistence not yet completed - to be uncommented later + //return "(*.hdf)"; } /*! Gets file name*/ diff --git a/src/LightApp/LightApp_Driver.cxx b/src/LightApp/LightApp_Driver.cxx index 5b56e03b7..122890390 100644 --- a/src/LightApp/LightApp_Driver.cxx +++ b/src/LightApp/LightApp_Driver.cxx @@ -38,6 +38,7 @@ /*! Constructor.*/ LightApp_Driver::LightApp_Driver() +: myIsTemp( false ) { } @@ -354,6 +355,10 @@ LightApp_Driver::ListOfFiles LightApp_Driver::PutStreamToFiles( const unsigned c // Create a temporary directory for the component's data files std::string aDir = GetTmpDir(); + // Remember that the files are in a temporary location that should be deleted + // when a study is closed + SetIsTemporary( true ); + //Get a temporary directory for saving a file TCollection_AsciiString aTmpDir(const_cast(aDir.c_str())); @@ -430,9 +435,17 @@ void LightApp_Driver::RemoveFiles( const ListOfFiles& theFiles, const bool IsDir if(IsDirDeleted) { OSD_Path aPath(aDirName); OSD_Directory aDir(aPath); - OSD_FileIterator anIterator(aPath, '*'); - - if(aDir.Exists() && !anIterator.More()) aDir.Remove(); + // san -- Using a special code block below is essential - it ensures that + // OSD_FileIterator instance is destroyed by the moment when + // OSD_Directory::Remove() is called. + // Otherwise, the directory remains locked (at least on Windows) + // by the iterator and cannot be removed. + { + OSD_FileIterator anIterator(aPath, '*'); + if(!aDir.Exists() || anIterator.More()) + return; + } + aDir.Remove(); } } @@ -461,9 +474,13 @@ void LightApp_Driver::ClearDriverContents() for ( it = myMap.begin(); it != myMap.end(); ++it ) { const char* aModuleName = const_cast(it->first.c_str()); - RemoveTemporaryFiles( aModuleName, false ); + // If the driver contains temporary files - + // remove them along with the temporary directory + RemoveTemporaryFiles( aModuleName, IsTemporary() ); } - myMap.clear(); + myMap.clear(); + // Reset the "temporary" flag + SetIsTemporary( false ); } //============================================================================ @@ -523,7 +540,12 @@ std::string LightApp_Driver::GetTmpDir() aDir = OSD_Directory(aPath); } - OSD_Protection aProtection(OSD_RW, OSD_RWX, OSD_RX, OSD_RX); +#ifdef WIN32 + // Workaround for OSD_Protection bug on Windows + OSD_Protection aProtection(OSD_RWXD, OSD_RWXD, OSD_RWXD, OSD_RWXD); +#else + OSD_Protection aProtection(OSD_RX, OSD_RWXD, OSD_RX, OSD_RX); +#endif aDir.Build(aProtection); myTmpDir = aTmpDir.ToCString(); diff --git a/src/LightApp/LightApp_Driver.h b/src/LightApp/LightApp_Driver.h index 022ce16ec..f995ce27d 100644 --- a/src/LightApp/LightApp_Driver.h +++ b/src/LightApp/LightApp_Driver.h @@ -40,9 +40,9 @@ public: typedef std::vector ListOfFiles; - bool SaveDatasInFile (const char* theFileName, bool isMultiFile ); - bool ReadDatasFromFile (const char* theFileName, bool isMultiFile ); - virtual std::string GetTmpDir (const char* theURL, const bool isMultiFile); + virtual bool SaveDatasInFile (const char* theFileName, bool isMultiFile); + virtual bool ReadDatasFromFile (const char* theFileName, bool isMultiFile); + virtual std::string GetTmpDir (const char* theURL, const bool isMultiFile); ListOfFiles GetListOfFiles (const char* theModuleName); virtual void SetListOfFiles (const char* theModuleName, const ListOfFiles theListOfFiles); @@ -51,7 +51,7 @@ public: virtual void ClearDriverContents(); -private: +protected: void PutFilesToStream(const std::string& theModuleName, unsigned char*& theBuffer, long& theBufferSize, bool theNamesOnly = false); ListOfFiles PutStreamToFiles(const unsigned char* theBuffer, @@ -60,10 +60,16 @@ private: std::string GetTmpDir(); std::string GetDirFromPath(const std::string& thePath); -private: + void SetIsTemporary( bool theFlag ) { myIsTemp = theFlag; } + bool IsTemporary() const { return myIsTemp; } + +protected: typedef std::map MapOfListOfFiles; MapOfListOfFiles myMap; std::string myTmpDir; + +private: + bool myIsTemp; }; #endif diff --git a/src/LightApp/LightApp_Study.cxx b/src/LightApp/LightApp_Study.cxx index b32f4945e..a2e5e4ba9 100644 --- a/src/LightApp/LightApp_Study.cxx +++ b/src/LightApp/LightApp_Study.cxx @@ -23,7 +23,8 @@ #include "LightApp_DataModel.h" #include "LightApp_DataObject.h" #include "LightApp_RootObject.h" -#include "LightApp_Driver.h" +// HDF persistence not yet completed +//#include "LightApp_HDFDriver.h" #include "SUIT_ResourceMgr.h" #include "SUIT_DataObjectIterator.h" @@ -50,6 +51,8 @@ LightApp_Study::LightApp_Study( SUIT_Application* app ) : CAM_Study( app ) { + // HDF persistence not yet completed + //myDriver = new LightApp_HDFDriver(); myDriver = new LightApp_Driver(); } @@ -229,16 +232,14 @@ bool LightApp_Study::saveDocument() //================================================================ void LightApp_Study::closeDocument(bool permanently) { - // Remove temporary files - ModelList aList; - dataModels( aList ); - myDriver->ClearDriverContents(); - // Inform everybody that this study is going to close when it's most safe to, // i.e. in the very beginning emit closed( this ); CAM_Study::closeDocument(permanently); + + // Remove temporary files + myDriver->ClearDriverContents(); } //================================================================ @@ -323,8 +324,8 @@ bool LightApp_Study::isSaved() const } //======================================================================= -// name : saveModuleData -/*! Purpose : Create SComponent for module, necessary for SalomeApp study */ +// name : addComponent +/*! Purpose : Create SComponent for module, necessary for SalomeApp study */ //======================================================================= void LightApp_Study::addComponent(const CAM_DataModel* dm) { @@ -463,7 +464,7 @@ void LightApp_Study::RemoveTemporaryFiles (const char* theModuleName, const bool } //================================================================ -// Function : RemoveTemporaryFiles +// Function : components /*! Purpose : to be used by modules*/ //================================================================ void LightApp_Study::components( QStringList& comp ) const @@ -477,4 +478,3 @@ void LightApp_Study::components( QStringList& comp ) const comp.append( obj->entry() ); } } - diff --git a/src/LightApp/Makefile.in b/src/LightApp/Makefile.in index 092b071f7..20610162c 100755 --- a/src/LightApp/Makefile.in +++ b/src/LightApp/Makefile.in @@ -22,6 +22,7 @@ EXPORT_HEADERS= LightApp.h \ LightApp_Dialog.h \ LightApp_Displayer.h \ LightApp_Driver.h \ +# LightApp_HDFDriver.h \ LightApp_GLSelector.h \ LightApp_Module.h \ LightApp_ModuleDlg.h \ @@ -58,6 +59,7 @@ LIB_SRC= LightApp_AboutDlg.cxx \ LightApp_Dialog.cxx \ LightApp_Displayer.cxx \ LightApp_Driver.cxx \ +# LightApp_HDFDriver.cxx \ LightApp_GLSelector.cxx \ LightApp_Module.cxx \ LightApp_ModuleDlg.cxx \ @@ -105,9 +107,11 @@ RESOURCES_FILES = icon_about.png \ LightApp.ini \ LightApp.xml -CPPFLAGS+=$(PYTHON_INCLUDES) $(QT_INCLUDES) $(QWT_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) +CPPFLAGS+=$(PYTHON_INCLUDES) $(QT_INCLUDES) $(QWT_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) + #$(HDF5_INCLUDES) LDFLAGS+=$(PYTHON_LIBS) $(QT_MT_LIBS) -LIBS+= -lsuit -lstd -lCAM -lObjBrowser -lLogWindow $(CAS_KERNEL) -lGLViewer -lOCCViewer -lVTKViewer -lSalomeObject -lSOCC -lSVTK -lSPlot2d -lSUPERVGraph -lPyInterp -lPythonConsole +LIBS+= -lsuit -lstd -lCAM -lObjBrowser -lLogWindow $(CAS_KERNEL) -lGLViewer -lOCCViewer -lVTKViewer -lSalomeObject -lSOCC -lSVTK -lSPlot2d -lSUPERVGraph -lPyInterp -lPythonConsole + #$(HDF5_LIBS) -lSalomeHDFPersistCopy @CONCLUDE@ diff --git a/src/Plot2d/Plot2d_ViewFrame.cxx b/src/Plot2d/Plot2d_ViewFrame.cxx index 67933dbae..30a25e808 100755 --- a/src/Plot2d/Plot2d_ViewFrame.cxx +++ b/src/Plot2d/Plot2d_ViewFrame.cxx @@ -593,6 +593,7 @@ void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update ) { if ( !curve ) return; + // san -- Protection against QwtCurve bug in Qwt 0.4.x: // it crashes if switched to X/Y logarithmic mode, when one or more points have // non-positive X/Y coordinate @@ -601,7 +602,6 @@ void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update ) if ( myYMode && curve->getMinY() <= 0. ) setVerScaleMode( 0, false ); - if ( hasCurve( curve ) ) { updateCurve( curve, update ); } @@ -1330,10 +1330,8 @@ void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update ) } myXMode = mode; - if ( myXMode == 0 ) // linear - myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false ); - else // logarithmic - myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, true ); + + myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, myXMode != 0 ); if ( update ) fitAll(); @@ -1353,16 +1351,10 @@ void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update ) } myYMode = mode; - if ( myYMode == 0 ) { // linear - myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false ); - if (mySecondY) - myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false ); - } - else { // logarithmic - myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, true ); - if (mySecondY) - myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, true ); - } + myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, myYMode != 0 ); + if (mySecondY) + myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, myYMode != 0 ); + if ( update ) fitAll(); emit vpModeVerChanged(); diff --git a/src/Plot2d/resources/Plot2d_msg_en.po b/src/Plot2d/resources/Plot2d_msg_en.po index a646152b5..055cd5f4c 100755 --- a/src/Plot2d/resources/Plot2d_msg_en.po +++ b/src/Plot2d/resources/Plot2d_msg_en.po @@ -150,6 +150,15 @@ msgstr "Error" msgid "BUT_OK" msgstr "Ok" +msgid "WARNING" +msgstr "Warning" + +msgid "WRN_XLOG_NOT_ALLOWED" +msgstr "Some points with non-positive abscissa values have been detected.\nLogarithmic scale for abscissa axis is not allowed." + +msgid "WRN_YLOG_NOT_ALLOWED" +msgstr "Some points with non-positive ordinate values have been detected.\nLogarithmic scale for ordinate axis is not allowed." + # ------------------------------------ # Plot2d_SetupViewDlg # ------------------------------------ diff --git a/src/STD/STD_Application.cxx b/src/STD/STD_Application.cxx index 3e955e6c9..a3ab1739e 100755 --- a/src/STD/STD_Application.cxx +++ b/src/STD/STD_Application.cxx @@ -93,7 +93,17 @@ void STD_Application::closeApplication() { if ( desktop() ) savePreferences(); + SUIT_Study* study = activeStudy(); + + if ( study ){ + study->closeDocument(); + + setActiveStudy( 0 ); + delete study; + } + setDesktop( 0 ); + SUIT_Application::closeApplication(); } @@ -112,18 +122,6 @@ void STD_Application::onDesktopClosing( SUIT_Desktop*, QCloseEvent* e ) return; } - SUIT_Study* study = activeStudy(); - - if ( study ) - study->closeDocument(); - - setActiveStudy( 0 ); - delete study; - - savePreferences(); - - setDesktop( 0 ); - closeApplication(); } diff --git a/src/SUIT/SUIT_Application.h b/src/SUIT/SUIT_Application.h index 43f6f29ed..b630177e6 100755 --- a/src/SUIT/SUIT_Application.h +++ b/src/SUIT/SUIT_Application.h @@ -56,10 +56,12 @@ public: //! Returns main widget (Desktop) of the application (if it exists) virtual SUIT_Desktop* desktop(); - /*! Returns FALSE if applic ation can not be closed (because of non saved data for example). + /*! Returns FALSE if application can not be closed (because of non saved data for example). This method called by SUIT_Session whin closing of application was requested. */ virtual bool isPossibleToClose(); + /*! Performs some finalization of life cycle of this application. + For instance, the application can force its documents(s) to close. */ virtual void closeApplication(); //! Returns active Study. If Application supports wirking with several studies this method should be redefined -- 2.39.2