Salome HOME
refs #1340 part.2
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Tool.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include <HYDROGUI_Tool.h>
20 #include <HYDROData_Document.h>
21 #include <HYDROData_Iterator.h>
22 #include <HYDROData_Profile.h>
23 #include <TCollection_ExtendedString.hxx>
24 #include <TCollection_HAsciiString.hxx>
25 #include <TCollection_HExtendedString.hxx>
26 #include <Image_PixMap.hxx>
27 #include <QDir>
28 #include <QDockWidget>
29 #include <QFile>
30 #include <QFileInfo>
31 #include <QLocale>
32 #include <QStringList>
33 #include <QTextCodec>
34 #include <QWidget>
35
36 // Definition of this id allows to use 'latin1' (Qt alias for 'ISO-8859-1')
37 // encoding instead of default 'System'
38 #define USE_LATIN1_ENCODING
39
40 // #define DEB_GROUPS 1
41
42 QString HYDROGUI_Tool::ToQString( const TCollection_AsciiString& src )
43 {
44 #ifdef USE_LATIN1_ENCODING
45   QTextCodec* codec = QTextCodec::codecForName( "latin1" ); // alias for ISO-8859-1
46 #else
47   QTextCodec* codec = QTextCodec::codecForLocale();
48 #endif
49   QString res;
50   if ( !src.IsEmpty() )
51     res = codec ? codec->toUnicode( (char*)src.ToCString(), src.Length() ) :
52       QString( (char*)src.ToCString() );
53   return res;
54 }
55
56 QString HYDROGUI_Tool::ToQString( const TCollection_ExtendedString& src )
57 {
58   return QString( (QChar*)src.ToExtString(), src.Length() );
59 }
60
61 QString HYDROGUI_Tool::ToQString( const Handle(TCollection_HAsciiString)& src )
62 {
63   if( src.IsNull() )
64     return QString();
65   else
66     return ToQString( src->String() );
67 }
68
69 QString HYDROGUI_Tool::ToQString( const Handle(TCollection_HExtendedString)& src )
70 {
71   if( src.IsNull() )
72     return QString();
73   return ToQString( src->String() );
74 }
75
76 TCollection_AsciiString HYDROGUI_Tool::ToAsciiString( const QString& src )
77 {
78   TCollection_AsciiString res;
79   if( !src.isNull() )
80   {
81 #ifdef USE_LATIN1_ENCODING
82     QTextCodec* codec = QTextCodec::codecForName( "latin1" ); // alias for ISO-8859-1
83 #else
84     QTextCodec* codec = QTextCodec::codecForLocale();
85 #endif
86     if( codec )
87     {
88       QByteArray str = codec->fromUnicode( src );
89       res = TCollection_AsciiString( (Standard_CString)str.constData() );
90     }
91     else
92       res = TCollection_AsciiString( src.toLatin1().data() );
93   }
94   return res;
95 }
96
97 TCollection_ExtendedString HYDROGUI_Tool::ToExtString( const QString& src )
98 {
99   if( src.isEmpty() )
100     return TCollection_ExtendedString();
101
102   Standard_Integer len = src.length();
103   Standard_ExtString extStr = new Standard_ExtCharacter[ ( len + 1 ) * 2 ];
104   memcpy( (void*)extStr, src.unicode(), len * 2 );
105   ((short*)extStr)[ len ] = 0;
106
107   TCollection_ExtendedString trg( extStr );
108   delete [] extStr;
109   return trg;
110 }
111
112 Handle(TCollection_HAsciiString) HYDROGUI_Tool::ToHAsciiString( const QString& src )
113 {
114   return new TCollection_HAsciiString( ToAsciiString( src ) );
115 }
116
117 Handle(TCollection_HExtendedString) HYDROGUI_Tool::ToHExtString( const QString& src )
118 {
119   return new TCollection_HExtendedString( ToExtString( src ) );
120 }
121
122 QString HYDROGUI_Tool::GetTempDir( const bool theToCreate )
123 {
124   QString aRes;
125
126   char* tmpdir = getenv ( "HYDRO_TMP_DIR" );
127   if ( tmpdir )
128   {
129     // try to create folder if it does not exist
130     QFileInfo fi( tmpdir );
131     if ( !fi.exists() && theToCreate )
132     {
133       if ( QDir().mkdir( tmpdir ) )
134         QFile::setPermissions( tmpdir, (QFile::Permissions)0x4FFFF );
135        QFileInfo fi( tmpdir );
136        if ( !fi.exists() || !fi.isWritable() )
137          tmpdir = 0;
138     }
139   }
140   if ( !tmpdir )
141     tmpdir = getenv ( "TEMP" );
142   if ( !tmpdir )
143     tmpdir = getenv ( "TMP" );
144   if ( !tmpdir )
145   {
146 #ifdef WNT
147     tmpdir = "C:\\";
148 #else
149     tmpdir = strdup( "/tmp" );
150 #endif
151   }
152   aRes = tmpdir;
153   
154   QFileInfo fi( aRes );
155   if ( !fi.exists() || !fi.isWritable() )
156     aRes = QString::null;
157
158   return aRes;
159 }
160
161 void HYDROGUI_Tool::GetObjectReferences( const Handle(HYDROData_Entity)& theObj,
162                                          HYDROData_SequenceOfObjects& theRefObjects,
163                                          QStringList& theRefNames )
164 {
165   if( theObj.IsNull() )
166     return;
167
168   HYDROData_SequenceOfObjects anAllRefObjects = theObj->GetAllReferenceObjects();
169   theRefObjects.Append( anAllRefObjects );
170
171   for( int i = 1, n = anAllRefObjects.Length(); i <= n; ++i )
172   {
173     Handle(HYDROData_Entity) aRefObj = theRefObjects.Value( i );
174     if( aRefObj.IsNull() || aRefObj->IsRemoved() )
175       continue;
176
177     QString aRefObjectName = aRefObj->GetName();
178     if( theRefNames.contains( aRefObjectName ) )
179       continue;
180
181     theRefObjects.Append( aRefObj );
182     theRefNames.append( aRefObjectName );
183
184     GetObjectReferences( aRefObj, theRefObjects, theRefNames );
185   }
186 }
187
188 HYDROData_SequenceOfObjects HYDROGUI_Tool::GetObjectBackReferences( const Handle(HYDROData_Entity)& theObj )
189 {
190   if( theObj.IsNull() )
191     return HYDROData_SequenceOfObjects();
192
193   QString anObjName = theObj->GetName();
194
195   Handle(HYDROData_Document) aDoc = HYDROData_Document::Document( theObj->Label() );
196   QMap<QString,HYDROData_SequenceOfObjects> aMapOfBackRefs =
197     GetObjectsBackReferences( aDoc, QStringList() << anObjName );
198
199   return aMapOfBackRefs[ anObjName ];
200 }
201
202 QMap<QString,HYDROData_SequenceOfObjects> HYDROGUI_Tool::GetObjectsBackReferences(
203   const Handle(HYDROData_Document)& theDocument, const QStringList& theObjectNames )
204 {
205   QMap<QString,HYDROData_SequenceOfObjects> aResMap;
206
207   if( theObjectNames.isEmpty() )
208     return aResMap;
209
210   if( theDocument.IsNull() )
211     return aResMap;
212
213   HYDROData_Iterator anIterator( theDocument );
214   for( ; anIterator.More(); anIterator.Next() )
215   {
216     Handle(HYDROData_Entity) anObject = anIterator.Current();
217     if( anObject.IsNull() || anObject->IsRemoved() )
218       continue;
219
220     QString anObjectName = anObject->GetName();
221     if ( theObjectNames.contains( anObjectName ) )
222       continue;
223
224     HYDROData_SequenceOfObjects aRefObjects = anObject->GetAllReferenceObjects();
225     for ( int i = 1, n = aRefObjects.Length(); i <= n; ++i )
226     {
227       Handle(HYDROData_Entity) aRefObject = aRefObjects.Value( i );
228       if( aRefObject.IsNull() || aRefObject->IsRemoved() )
229         continue;
230
231       QString aRefObjectName = aRefObject->GetName();
232       if ( !theObjectNames.contains( aRefObjectName ) )
233         continue;
234
235       aResMap[ aRefObjectName ].Append( anObject );
236     }
237   }
238
239   return aResMap;
240 }
241
242 QDockWidget* HYDROGUI_Tool::WindowDock( QWidget* wid )
243 {
244   if ( !wid )
245     return 0;
246
247   QDockWidget* dock = 0;
248   QWidget* w = wid->parentWidget();
249   while ( w && !dock )
250   {
251     dock = ::qobject_cast<QDockWidget*>( w );
252     w = w->parentWidget();
253   }
254   return dock;
255 }
256
257 QStringList HYDROGUI_Tool::FindExistingObjectsNames( const Handle(HYDROData_Document)& theDoc, 
258                                                      const ObjectKind theObjectKind,
259                                                      bool isCheckValidProfile )
260 {
261   QStringList aNames;
262
263   HYDROData_Iterator anIter( theDoc, theObjectKind );
264   for ( ; anIter.More(); anIter.Next() ) {
265     Handle(HYDROData_Entity) anObject = anIter.Current();
266
267     bool isOK = !anObject.IsNull();
268     
269     if( isOK && isCheckValidProfile )
270     {
271       Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( anObject );
272       if( !aProfile.IsNull() && !aProfile->IsValid() )
273         isOK = false;
274     }
275       
276     if( isOK )
277       aNames.append( anObject->GetName() );
278   }
279
280   return aNames;
281 }
282
283 QString HYDROGUI_Tool::GetCoordinateString( const double theNumber, bool isInLocale )
284 {
285   if( isInLocale )
286   {
287     static QLocale aLocale( QLocale::English, QLocale::France );
288     return aLocale.toString( theNumber, 'f', 2 );
289   }
290   else
291     return QString::number( theNumber, 'f', 2 );
292 }
293
294 Handle(Image_PixMap) HYDROGUI_Tool::Pixmap( const QImage& theImage )
295 {
296     Handle(Image_PixMap) pix;
297     if ( theImage.isNull() || theImage.format() == QImage::Format_Invalid )
298         return pix;
299
300     Handle(Image_PixMap) tmpPix = new Image_PixMap();
301     tmpPix->SetTopDown( false );
302     QImage anImage = theImage.mirrored();
303     if ( !anImage.hasAlphaChannel() && anImage.allGray() )
304     {
305         tmpPix->InitTrash( Image_PixMap::ImgGray, anImage.width(), anImage.height(), anImage.width() );
306         for ( int r = 0; r < anImage.height(); r++ )
307         {
308             Standard_Byte* aRowData = tmpPix->ChangeRow( anImage.height() - r - 1 );
309             for  ( int p = 0; p < anImage.width(); p++ )
310                 aRowData[p] = qRed( anImage.pixel( p, r ) );
311         }
312     }
313     else
314     {
315         Image_PixMap::ImgFormat aFormat;
316         if ( anImage.hasAlphaChannel() )
317         {
318           if ( anImage.format() != QImage::Format_RGBA8888 )
319                 anImage = anImage.convertToFormat( QImage::Format_RGBA8888 );
320             aFormat = Image_PixMap::ImgRGBA;
321         }
322         else
323         {
324             if ( anImage.format() != QImage::Format_RGB888 )
325                 anImage = anImage.convertToFormat( QImage::Format_RGB888 );
326             aFormat = Image_PixMap::ImgRGB;
327         }
328
329         tmpPix->InitWrapper( aFormat, (Standard_Byte*)anImage.bits(), anImage.width(), anImage.height(), anImage.bytesPerLine() );
330     }
331
332     if ( !tmpPix.IsNull() )
333     {
334         pix = new Image_PixMap();
335         pix->InitCopy( *tmpPix.operator->() );
336         pix->SetTopDown( tmpPix->IsTopDown() );
337     }
338
339     return pix;
340 }
341