fix compile against newer giflib
[rofl0r-obeditor.git] / src / common__tools.cpp
blob9f923a4b9f0a7c9d926d3d285a4793feb809deb5
1 #include <wx/wxprec.h>
2 #ifndef WX_PRECOMP
3 #include <wx/wx.h>
4 #endif
6 #include <wx/file.h>
8 #include "common__tools.h"
9 #include "common__mod.h"
10 #include "ob_editor.h"
11 #include "entity__globals.h"
12 #include "images__MyPalette.h"
14 using namespace std;
15 extern wxString curr_entity_filename;
18 /**\internal*****************
19 * SOME GLOBALS
20 * **************************
22 wxConfigBase *config;
23 wxFileName dirRessources;
24 wxImage *noImg;
29 /**\internal*****************
30 * Miscellanious facilities
31 * **************************
34 bool Frame_RestorePrevCoord( wxWindow* it, const wxString& _name )
36 int last_x, last_y, last_width, last_height;
37 bool b_ok = true;
38 b_ok = config->Read(wxT("/")+ _name + wxT("/last_x"), &last_x, 20) && b_ok;
39 b_ok = config->Read(wxT("/")+ _name + wxT("/last_y"), &last_y, 20) && b_ok;
40 b_ok = config->Read(wxT("/")+ _name + wxT("/last_width"), &last_width, 400) && b_ok;
41 b_ok = config->Read(wxT("/")+ _name + wxT("/last_height"), &last_height, 200) && b_ok;
43 it->SetSize(last_width,last_height);
44 it->Move( last_x,last_y );
45 return b_ok;
49 void Frame_SaveCoord( wxWindow* it, const wxString& name )
51 int _width, _height;
52 it->GetSize( &_width, &_height );
53 wxPoint _position = it->GetScreenPosition();
55 bool b_ok = true;
56 b_ok = config->Write(wxT("/")+ name + wxT("/last_x"), _position.x ) && b_ok;
57 b_ok = config->Write(wxT("/")+ name + wxT("/last_y"), _position.y ) && b_ok;
58 b_ok = config->Write(wxT("/")+ name + wxT("/last_width"), _width ) && b_ok;
59 b_ok = config->Write(wxT("/")+ name + wxT("/last_height"), _height ) && b_ok;
61 if( ! b_ok )
62 wxMessageBox(wxT("Cannot save Coords for window ") + name,
63 wxT("ProPlem"), wxOK | wxICON_INFORMATION, it );
67 void Frame_DestroySavedCoord( const wxString& _name )
69 config->DeleteEntry(wxT("/")+ _name + wxT("/last_x"));
70 config->DeleteEntry(wxT("/")+ _name + wxT("/last_y"));
71 config->DeleteEntry(wxT("/")+ _name + wxT("/last_width"));
72 config->DeleteEntry(wxT("/")+ _name + wxT("/last_height"));
74 return;
78 //****************************************************
80 void ClearMenu( wxMenu* menu )
82 if( menu == NULL || menu->GetMenuItemCount() <= 0 )
83 return;
85 wxMenuItem *t = menu->FindItemByPosition( 0 );
86 while( 1 )
88 menu->Delete( t );
89 if( menu->GetMenuItemCount() <= 0 )
90 break;
91 else
92 t = menu->FindItemByPosition( 0 );
96 void OpenInExternalEditor( wxWindow* parent, const wxString& filePath )
98 // Get the editor from the config
99 wxString editor_path;
100 if( ! config->Read( wxT("/startFrame/editor_program"), &editor_path ) )
102 wxMessageBox(wxT("Did you correctly set the editor in the start window ??"),
103 wxT("ProPlem"), wxOK | wxICON_EXCLAMATION, parent );
104 return;
107 if( ! wxFileName(editor_path).FileExists() )
109 wxMessageBox(wxT("Unable to find ")+ editor_path +wxT(" ??"),
110 wxT("ProPlem"), wxOK | wxICON_EXCLAMATION, parent );
111 return;
114 if( ! wxFileName(filePath).FileExists() )
116 wxMessageBox(wxT("Unable to open the file \n\n")+ filePath,
117 wxT("ProPlem"), wxOK | wxICON_EXCLAMATION, parent );
118 return;
121 // Launch the editor
122 wxExecute( wxT("\"") + editor_path + wxT("\" \"") + filePath + wxT("\"") );
127 //****************************************************
129 void EnableItemsMenu( wxMenu* menu, bool b_enable )
131 if( menu == NULL || menu->GetMenuItemCount() <= 0 )
132 return;
134 wxMenuItemList itemsList = menu->GetMenuItems();
135 wxMenuItemList::iterator iter;
136 for (iter = itemsList.begin(); iter != itemsList.end(); ++iter)
138 wxMenuItem *current = *iter;
139 current->Enable( b_enable );
146 //********************************
147 /**\internal*****************
148 * Images facilities
149 * **************************
152 wxColour MeltColor(wxColour _c0, wxColour _c1 )
154 float _fact = 1;
155 if( _c1.Red() != 0 )
156 _fact = 1 + (float) _c0.Red() / (float) _c1.Red();
157 int _r = ( _c1.Red() - _c0.Red() ) + _c0.Red() * _fact;
158 if( _r >= 256 ) _r = 255;
160 _fact = 1;
161 if( _c1.Green() != 0 )
162 _fact = 1 + (float) _c0.Green() / (float) _c1.Green();
163 int _g = ( _c1.Green() - _c0.Green() ) + _c0.Green() * _fact;
164 if( _g >= 256 ) _g = 255;
166 _fact = 1;
167 if( _c1.Blue() != 0 )
168 _fact = 1 + (float) _c0.Blue() / (float) _c1.Blue();
169 int _b = ( _c1.Blue() - _c0.Blue() ) + _c0.Blue() * _fact;
170 if( _b >= 256 ) _b = 255;
172 return wxColour( _r, _g, _b );
176 Image_Holder::Image_Holder()
178 img = NULL;
179 png_or_gif = NULL;
183 Image_Holder::~Image_Holder()
185 RemoveImages();
189 int Image_Holder::Get_ColorIndex( const int x, const int y )
191 if( Get_GIF_or_PNG() == NULL )
192 return -1;
194 return png_or_gif->GetIndex( x, y );
198 void Image_Holder::RemoveImages()
200 if( img != NULL )
201 delete img;
202 img = NULL;
204 if( png_or_gif != NULL )
205 delete png_or_gif;
206 png_or_gif = NULL;
210 wxImage* Image_Holder::GetImage()
212 if( img != NULL )
213 return img;
215 wxString _path = GetFileName().GetFullPath();
216 if( ! wxFileName(_path).FileExists() )
217 return NULL;
219 if( IsFileEmpty( _path))
220 return NULL;
222 if( IsFileEmpty( _path))
223 return NULL;
225 img = new wxImage( _path );
226 if( ! img->IsOk() )
228 delete img;
229 img = NULL;
232 return img;
236 imgFile* Image_Holder::Get_GIF_or_PNG()
238 if( img == NULL && GetImage() == NULL )
239 return NULL;
241 wxFileName fn = GetFileName();
242 wxString str_path = fn.GetFullPath();
243 if( str_path ==wxString() )
244 return NULL;
246 if( ! fn.FileExists() )
247 return NULL;
249 // Check if the file is Zero Size
250 if( IsFileEmpty( str_path))
251 return NULL;
253 if( fn.GetExt().Upper() ==wxT("PNG"))
254 png_or_gif = new wxIndexedPNG( str_path );
256 else if( fn.GetExt().Upper() ==wxT("GIF"))
257 png_or_gif = new wxIndexedGIF( str_path );
259 else
260 return NULL;
262 if( ! png_or_gif->IsOk() )
264 delete png_or_gif;
265 png_or_gif = NULL;
266 return NULL;
269 return png_or_gif;
272 //---------------------------------------------------------
273 wxString
274 wxColour_ToStr( const wxColour& c )
276 return IntToStr(c.Red())
277 +wxT(",")+ IntToStr(c.Green())
278 +wxT(",")+ IntToStr(c.Blue())
282 //---------------------------------------------------------
283 wxColour
284 wxColour_FromStr( const wxString& s )
286 wxArrayString as = StrSplit( s,wxT(","));
287 return wxColour( StrToInt(as[0])
288 , StrToInt(as[1])
289 , StrToInt(as[2])
293 void
294 Image_Rescale_To_Fit( wxImage& img, size_t w, size_t h )
296 if( img.IsOk() == false )
297 return;
299 size_t img_w = img.GetWidth();
300 size_t img_h = img.GetHeight();
301 float zoom_x = 10000;
302 float zoom_y = 10000;
304 if( img_w >= w )
305 zoom_y = (float)w/(float)img_w;
306 if( img_h >= h )
307 zoom_x = (float)h/(float)img_h;
309 if( zoom_y != 10000 || zoom_x != 10000 )
311 float z = min(zoom_x,zoom_y);
312 img.Rescale( img_w * z, img_h * z );
313 return;
316 zoom_y = (float)w/(float)img_w;
317 zoom_x = (float)h/(float)img_h;
319 float z = min(zoom_x,zoom_y);
320 img.Rescale( img_w * z, img_h * z );
321 return;
324 /**\internal*****************
325 * Ob_objects facilities
326 * **************************
328 void Sort_ob_Object_ByName( ob_object**& objs, size_t count )
330 for( size_t i =0; i < count ; i++ )
332 size_t curr_ind = i;
333 for( size_t j = i+1; j < count; j++ )
334 if( objs[j]->name.Upper() < objs[curr_ind]->name.Upper() )
335 curr_ind = j;
337 ob_object *temp = objs[i];
338 objs[i] = objs[curr_ind];
339 objs[curr_ind] = temp;
344 void Sort_ob_Object_ByTag( ob_object**& objs, size_t count, size_t num_tag )
346 for( size_t i =0; i < count ; i++ )
348 size_t curr_ind = i;
349 for( size_t j = i+1; j < count; j++ )
350 if( objs[j]->GetToken(num_tag).Upper() < objs[curr_ind]->GetToken(num_tag).Upper() )
351 curr_ind = j;
353 ob_object *temp = objs[i];
354 objs[i] = objs[curr_ind];
355 objs[curr_ind] = temp;
359 void Sort_ob_Object_ByTag( ob_anim**& objs, size_t count, size_t num_tag )
361 ob_object** temp = (ob_object**) objs;
362 Sort_ob_Object_ByTag( temp, count, num_tag );
366 wxString* Reverse_Null_StrArray( wxString* tokens, size_t tokens_size )
368 wxString* res = new wxString[tokens_size];
369 int i = 0;
370 int j = tokens_size -1;
371 while( j >=0 )
373 res[j] = tokens[i];
374 i++;
375 j--;
377 return res;
381 wxString UnTokenize( ob_object* _obj )
383 if( _obj == NULL)
384 return wxString();
386 wxString res;
387 int j = 0;
388 while(j>=0)
390 wxString _t = _obj->GetToken(j);
391 if( _t == wxString() )
392 j = -1;
393 else
395 res += _t + wxT(" ");
396 j++;
399 res.Trim();
400 return res;
404 wxArrayString ArrayString_PrependAll( const wxArrayString& arrStr, const wxString& _prefix )
406 wxArrayString res;
407 for( size_t i = 0; i < arrStr.Count(); i++)
409 res.Add( _prefix + arrStr[i] );
411 return res;
415 wxString ArrayString_Join( const wxArrayString& arrStr, const wxString& _jointure )
417 if( arrStr.Count() <= 0 )
418 return wxString();
420 wxString res = arrStr[0];
421 for( size_t i = 1; i < arrStr.Count(); i++)
423 res += _jointure + arrStr[i];
425 return res;
428 void TabStringToArrayString( wxString* tStr, size_t nb, wxArrayString& arrStr )
430 arrStr.Clear();
431 for( size_t i=0; i < nb; i++)
432 arrStr.Add( tStr[i] );
436 bool IsInArray( const wxString& _t, wxString* arr, size_t arr_tay )
438 for( size_t i = 0; i < arr_tay; i++ )
440 if( _t.Upper() == arr[i].Upper() )
441 return true;
443 return false;
447 /**\internal*****************
448 * Conversions facilities
449 * **************************
451 wxString IntToStr( int i )
453 return wxString::Format(wxT("%d"), (int)i);
456 wxString IntToStr( size_t i )
458 return wxString::Format(wxT("%d"), static_cast<int>(i));
461 int StrToInt( const wxString& str, bool& ok )
463 long res = 0;
464 ok = str.ToLong(&res);
465 return (int)res;
468 int StrToInt( const wxString& str )
470 long res = 0;
471 bool ok;
472 ok = str.ToLong(&res);
473 return (int)res;
476 unsigned int StrToUInt( const wxString& str, bool& ok )
478 long int res = 0;
479 ok = str.ToLong(&res);
480 if( res < 0 )
482 ok = false;
483 return (unsigned int) -res;
485 return (unsigned int) res;
488 float StrToFloat(const wxString& str, bool& ok )
490 double res = 0;
491 wxString t(str);
492 t.Replace( wxT("."), wxT(",") );
493 ok = t.ToDouble(&res);
494 return (float)res;
497 float StrToFloat(const wxString& str )
499 bool dummy;
500 return StrToFloat( str, dummy );
503 wxString FloatToStr( const float f)
505 wxString t;
506 t.Printf( wxT("%f"), f);
507 t.Replace( wxT(","), wxT(".") );
508 if( t.Find( wxT('.') ) )
510 while( t[t.Len()-1] == wxT('0') )
511 t.Truncate(t.Len() -1 );
512 if( t[t.Len()-1] == '.' )
513 t.Truncate(t.Len() -1 );
515 return t;
518 bool IntToBool(const int i )
519 { return i != 0; }
521 bool StrToBool( const wxString& str )
523 bool ok = false;
524 int res = StrToInt( str, ok );
525 if( !ok )
526 return false;
527 return IntToBool( res );
533 /**\internal*****************
534 * Strings facilities
535 * **************************
538 bool StrIsObBool( const wxString& str )
540 if( str.Len() != 1 )
541 return false;
542 if( str[0] != wxT('0') && str[0] != wxT('1') )
543 return false;
544 return true;
547 bool StrIsInt( const wxString& str )
549 bool res;
550 StrToInt(str, res );
551 return res;
554 bool StrIsUInt( const wxString& str )
556 bool res;
557 StrToUInt(str, res );
558 return res;
561 bool StrIsFloat( const wxString& str )
563 bool res;
564 StrToFloat(str, res );
565 return res;
568 wxString ArrStrConcat( const wxArrayString& arrStr, const wxString& separator )
570 if( arrStr.Count() == 0 )
571 return wxString();
573 wxString res;
574 for( size_t i=0; i < arrStr.Count()-1; i++)
575 res += arrStr[i] + separator;
576 res += arrStr[arrStr.Count()-1];
577 return res;
580 wxArrayString StrSplit( const wxString& str, const wxString& delim, bool b_remove_empty )
582 wxArrayString res;
583 if( str.Len() == 0 )
585 res.Add(wxString());
586 return res;
588 if( delim.Len() == 0 )
590 res.Add( str );
591 return res;
594 wxString temp = str;
595 while( true )
597 int ind = temp.Find( delim );
598 if( ind == wxNOT_FOUND )
600 res.Add( temp );
601 break;
603 else
605 if( ind != 0 || ! b_remove_empty)
606 res.Add( temp.Left(ind) );
607 temp = temp.Right( temp.Len() -delim.Len() - ind );
610 return res;
614 inline wxArrayString Concat_ArrayString( const wxArrayString & arr1, const wxArrayString & arr2 )
616 wxArrayString res = arr1;
617 for( size_t i = 0; i < arr2.Count(); i++ )
618 res.Add( arr2[i] );
619 return res;
622 inline wxArrayString __Tokenize( wxArrayString& arr_str, const wxString& delim )
624 wxArrayString res;
625 for( size_t i = 0; i < arr_str.Count(); i++ )
626 res = Concat_ArrayString( res, StrSplit( arr_str[i], delim, true ) );
628 // removing empty elts
629 wxArrayString res2;
630 for( size_t i = 0; i < res.Count(); i++ )
631 if( res[i] != wxString() )
632 res2.Add( res[i]);
633 return res2;
636 wxArrayString Tokenize( const wxString& str )
638 wxArrayString res;
639 if( str.Len() == 0 )
640 return res;
642 res.Add( str );
643 res = __Tokenize( res, wxT(" ") );
644 res = __Tokenize( res, wxT("\t") );
645 return res;
649 //--------------------------------------------------------------------
650 void
651 wxArraystring__Add( wxArrayString& arr_str, size_t nb_str, ... )
653 va_list ap;
654 va_start (ap, nb_str);
655 for( size_t i= 0; i < nb_str; i++ )
656 arr_str.Add( wxString::FromAscii(va_arg(ap, const char* )));
657 va_end (ap);
660 //--------------------------------------------------------------------
661 wxArrayString
662 wxArrayString_Build( size_t nb_str, ... )
664 wxArrayString res;
665 va_list ap;
666 va_start (ap, nb_str);
667 for( size_t i= 0; i < nb_str; i++ )
668 res.Add( wxString::FromAscii(va_arg(ap, const char* )));
669 va_end (ap);
671 return res;
676 /**\internal*****************
677 * Files facilities
678 * **************************
680 wxFileName MyDirAppend( const wxFileName dataDirPath, const wxString& subDir )
682 wxFileName res = dataDirPath;
683 wxArrayString arr_dirs = StrSplit( subDir, wxT('/') );
684 for( size_t i = 1; i < arr_dirs.Count(); i++)
685 res.AppendDir( arr_dirs[i] );
686 return res;
689 wxFileName MyPathAppend( const wxFileName _dataDirPath, const wxString& subPath )
691 wxFileName res = _dataDirPath;
692 wxArrayString arr_dirs = StrSplit( subPath, wxT('/') );
693 if( arr_dirs.Count() == 1 )
695 return wxFileName(res.GetPath(), arr_dirs[0] );
698 wxString filename = arr_dirs[arr_dirs.Count() -1];
700 for( size_t i = 0; i < arr_dirs.Count() -1; i++)
701 res.AppendDir( arr_dirs[i] );
702 return wxFileName(res.GetPath(), filename );
705 wxString
706 ObPath_To_FullPath( const wxString& _subPath )
708 return GetObFile( _subPath ).GetFullPath();
711 wxFileName GetObFile( const wxString& _subPath )
713 return MyPathAppend( dataDirPath, _subPath);
716 wxString Convert_To_Ob_Path( const wxString& s_path )
718 // first remove the base dir
719 wxString __t = dataDirPath.GetPath();
721 wxString _path(s_path);
722 //if( _path.Replace( __t , _T(""), false ) == 0 ) // FIXME: figure what _T did !
723 if( _path.Replace( __t , wxString(), false ) == 0 )
724 // No replacement made => not a valid dataDir relative path
725 return wxString();
727 wxFileName temp( _path );
728 wxArrayString t_arr = temp.GetDirs();
729 if( t_arr.Count() == 0 )
731 if( _path[0] == '/' )
732 return _path.Mid( 1, _path.Len() -1 );
733 else
734 return _path;
737 wxString res = ArrStrConcat( t_arr, wxT("/") );
738 if( res[0] == wxT('/') )
739 res = res.Mid( 1, res.Len() -1 );
740 if( res.Len() > 0 )
741 res += wxT('/') + temp.GetFullName();
743 return res;
747 wxFileName GetRessourceFile( const wxString& _strFileName )
749 wxFileName temp = dirRessources;
750 temp.SetFullName( _strFileName );
751 return temp;
754 wxString GetRessourceFile_String( const wxString& _strFileName )
756 return GetRessourceFile( _strFileName ).GetFullPath();
759 void RemoveLastAtom( wxFileName& _fn )
761 if( _fn.HasName() )
762 _fn = _fn.GetPath();
763 else
764 _fn.RemoveLastDir();
767 bool DirExists( wxFileName _fn )
769 wxString ttt = _fn.GetFullPath();
770 if( ! _fn.IsDir() )
771 return false ;
773 if( _fn.DirExists() )
774 return true;
776 return false;
779 bool __RECURS_FindFirsValidPath( wxString& path, wxArrayString& sub_dirs, int& arr_ind )
781 if( sub_dirs.Count() == 0)
782 return true;
784 wxString new_dir = path + wxFileName::GetPathSeparator() + sub_dirs[arr_ind];
786 wxFileName ttt(new_dir + wxFileName::GetPathSeparator());
788 if( ttt.DirExists() )
790 path = new_dir;
791 arr_ind++;
792 return __RECURS_FindFirsValidPath( path, sub_dirs, arr_ind );
795 return true;
798 int __apply_string_path( wxString& curr_dir, long& camino)
800 long t = camino;
801 size_t camino_len = 0;
802 while( t > 0 )
804 t = t >> 1;
805 camino_len++;
808 if( camino_len > curr_dir.Len() )
809 return false;
811 wxString res;
812 bool all_ones = true;
813 for( size_t i = 0; i < curr_dir.Len(); i ++)
815 long t = (camino >> i );
816 if( t & 1 )
817 res += toupper( curr_dir[i] );
818 else
820 res += tolower( curr_dir[i] );
821 all_ones = false;
824 camino++;
825 curr_dir = res;
826 return all_ones;
829 wxString TryRepairObPath( const wxFileName& _fn )
831 // easy repair
832 if( _fn.FileExists() )
833 return _fn.GetFullPath();
835 wxString _sep = wxFileName::GetPathSeparator();
837 wxString _fp = _fn.GetFullPath();
838 #ifdef OSLINUX
839 _fp.Replace( wxT("\\"), wxT("/") );
840 #endif
841 // Try to find the first existing dir
842 wxArrayString sub_dirs = StrSplit( _fp, wxFileName::GetPathSeparator() );
843 wxString _curr_path;
844 int ind_sub_dirs = 0;
845 bool res = __RECURS_FindFirsValidPath(_curr_path , sub_dirs, ind_sub_dirs );
847 // Nothing in the path exists !!
848 if( ! res )
849 return wxString();
851 // Try to rebuild the path dir after dir
852 for( size_t i = ind_sub_dirs; i < sub_dirs.Count(); i++)
854 // try every combination of upper and lowercase string with the current dir
855 wxString curr_subdir = sub_dirs[i];
857 // If the curr_subdir name is too big => abandon repair
858 if( curr_subdir.Len() > 32 )
859 return wxString();
861 // Build the starting path of construction
862 long camino = 0;
864 int cont = 0;
865 wxString curr_Try;
866 while( cont == 0 )
868 wxString _temp_ = curr_subdir;
869 cont = __apply_string_path( _temp_, camino);
870 curr_Try = _curr_path + _sep + _temp_;
872 // Dir existence check
873 if( i < sub_dirs.Count() -1 )
875 _temp_ = curr_Try + _sep;
876 wxFileName t(_temp_);
877 if( t.DirExists() )
878 cont = 2;
880 // Final Existence check
881 else
882 if( wxFileName(curr_Try).FileExists() || wxDirExists(curr_Try + _sep) )
883 cont = 2;
886 // Not found
887 if( cont != 2 )
888 return wxString();
890 // Found !!
891 _curr_path = curr_Try;
894 // Repaired !!!
895 return _curr_path;
899 bool SimpleBackUpFile( const wxString& filePath )
901 wxString backup_path = filePath +wxT(".bak");
902 return wxCopyFile( filePath, backup_path, true );
905 WX_DECLARE_HASH_MAP( wxString, bool, wxStringHash, wxStringEqual, Hash_File_backedup );
906 Hash_File_backedup hash_file_backup;
908 bool myBackUp( const wxString& filePath )
910 // If already backedup
911 if( hash_file_backup[filePath] )
912 return true;
914 if( SimpleBackUpFile( filePath ) )
916 hash_file_backup[filePath] = true;
917 return true;
919 return false;
922 bool myMove( const wxString& _src, const wxString& _dest )
924 wxString tempfile = wxFileName::CreateTempFileName( _src );
925 if( ! wxRenameFile( _src, tempfile ) )
926 return false;
927 if( ! wxRenameFile( tempfile, _dest ) )
928 return false;
929 return true;
932 bool IsFileEmpty( const wxString& _path )
934 wxFile _t(_path );
935 if( ! _t.IsOpened() )
936 return true;
938 int len = _t.Length();
939 _t.Close();
940 return ( len == 0);
943 /**\internal*****************
944 * Helper Class for repairing paths
945 * **************************/
946 Repair_Set::Repair_Set()
950 Repair_Set::~Repair_Set()
952 while( props.empty() == false )
954 struct d_s_i t = props.front();
955 delete t.prop_name;
956 props.pop_front();
960 void
961 Repair_Set::Add_Repairable( const wxString& _prop_name, size_t _num_token )
963 struct d_s_i add;
964 add.prop_name = new wxString(_prop_name.Upper());
965 add.num_token = _num_token;
966 props.push_back( add );
969 // Return count of repaired
970 size_t
971 Repair_Set::Try_Repair(ob_object* o )
973 return RECURS_Repair(o);
977 size_t
978 Repair_Set::RECURS_Repair(ob_object* o)
980 size_t res = 0;
981 list<struct d_s_i>::iterator it(props.begin()),
982 it_end (props.end());
983 for(;it!=it_end;it++)
985 if( o->name.Upper() == *((*it).prop_name) )
987 if( o->nb_tokens > (*it).num_token )
989 wxString st_file = GetObFile( o->GetToken( (*it).num_token )).GetFullPath();
991 if( wxFileExists(st_file) == false && wxDirExists(st_file) == false )
993 wxString repaired_path =TryRepairObPath( st_file );
994 if( repaired_path != wxString() )
996 o->SetToken( (*it).num_token, Convert_To_Ob_Path( repaired_path ));
997 res++;
1004 // Recurs in subobjects
1005 ob_object* t = o->first_subobj;
1006 while( t != NULL )
1008 res += RECURS_Repair( t );
1009 t = t->next;
1012 return res;
1016 /**\internal*****************
1017 * LOGGINGS facilities
1018 * **************************
1020 myLog *logger;
1021 void __logstderr( wxLogLevel level, const wxChar *msg, time_t timestamp);
1022 void __loggui( wxLogLevel level, const wxChar *msg, time_t timestamp);
1024 #define MAXKEEPEDLOGS 100
1025 int logKeeper_level[MAXKEEPEDLOGS];
1026 wxString logKeeper_sources[MAXKEEPEDLOGS];
1027 wxString logKeeper_message[MAXKEEPEDLOGS];
1028 int next_ind__keepedlog = 0;
1030 void MyLog( int level, const wxString& source, const wxString& message )
1032 if( level == MYLOG_DEBUG )
1034 #ifdef MYDEBUG
1035 cout<<"DEBUG : "<<source<<" : "<<message<<endl;
1036 #endif
1037 return;
1040 if( startFrame->frame_launched == wxT("EDIT_ENTITIES") )
1042 // Keep message when the panel errors is not OK
1043 if( panel_Errors == NULL )
1045 if( next_ind__keepedlog == MAXKEEPEDLOGS )
1046 return;
1047 logKeeper_level[next_ind__keepedlog] = level;
1048 logKeeper_sources[next_ind__keepedlog] = source;
1049 logKeeper_message[next_ind__keepedlog] = message;
1050 next_ind__keepedlog++;
1051 return;
1054 // Have keeped message ?
1055 if( next_ind__keepedlog > 0 )
1057 for( int i=0; i < next_ind__keepedlog; i ++)
1058 panel_Errors->Log( logKeeper_level[i], logKeeper_sources[i], logKeeper_message[i] );
1059 next_ind__keepedlog = 0;
1061 panel_Errors->Log( level, source, message );
1062 return;
1066 // START FRAME LOG
1067 else
1069 wxString log_mess = source + wxT(" : ") + message;
1070 time_t timestamp;
1071 switch(level)
1074 // Debug level
1075 case wxLOG_Debug:
1076 wxLogInfo( log_mess );
1077 break;
1079 // Littles log levels
1080 case wxLOG_Warning:
1081 case wxLOG_Message:
1082 __loggui( level, log_mess, timestamp);
1083 break;
1085 default:
1086 wxLogInfo( log_mess );
1087 break;
1092 void ObjectsLog( int level, int num_line, const wxString& message )
1094 wxString source = curr_entity_filename;
1095 if( source == wxString() )
1096 source = wxT("models.txt");
1098 if( num_line >= 0 )
1099 source += wxT(" : line ") + IntToStr( num_line );
1101 MyLog( level, source, message );
1104 void EmptyLogKeeper()
1106 next_ind__keepedlog = 0;
1109 wxLogStderr* debugLog = NULL;
1110 wxLogWindow* guiLog = NULL;
1112 void myLog::DoLog(wxLogLevel level, const wxChar *msg, time_t timestamp)
1115 switch(level)
1118 // Debug level
1119 case wxLOG_Debug:
1120 __logstderr( level, msg, timestamp);
1121 break;
1123 // Littles log levels
1124 case wxLOG_Warning:
1125 case wxLOG_Message:
1126 __loggui( level, msg, timestamp);
1127 break;
1129 default:
1130 __logstderr( level, msg, timestamp);
1131 break;
1135 void __DispatchMsgLog( wxLogLevel level, const wxChar *msg, time_t timestamp)
1137 switch( level )
1139 case wxLOG_FatalError:
1140 wxLogFatalError( msg );
1141 break;
1143 case wxLOG_Warning:
1144 wxLogWarning( msg );
1145 break;
1147 case wxLOG_Error:
1148 wxLogError( msg );
1149 break;
1151 case wxLOG_Message:
1152 wxLogMessage( msg );
1153 break;
1155 case wxLOG_Info:
1156 case wxLOG_Status:
1157 wxLogStatus( msg );
1158 break;
1160 default:
1161 wxLogMessage( msg );
1162 break;
1165 void __logstderr( wxLogLevel level, const wxChar *msg, time_t timestamp)
1167 if( debugLog == NULL )
1168 debugLog = new wxLogStderr();
1169 wxLog::SetActiveTarget( debugLog );
1170 __DispatchMsgLog( level, msg, timestamp);
1171 wxLog::SetActiveTarget(logger);
1174 void __loggui( wxLogLevel level, const wxChar *msg, time_t timestamp)
1176 if( guiLog == NULL )
1177 guiLog = new wxLogWindow(startFrame, wxT("Infos"), false, false);
1178 guiLog->Show();
1179 wxLog::SetActiveTarget( guiLog );
1180 __DispatchMsgLog( level, msg, timestamp);
1181 wxLog::SetActiveTarget(logger);
1185 //----------------------------------------------------------------------
1186 wxImage*
1187 Build_Remap( wxImage* src // The target image in wxImage format
1188 , imgFile* src2 // The target image in imgFile format
1189 , imgFile* remap_src // The reamp src image
1190 , imgFile* remap_dest // The reamp dest image
1194 if( remap_src->height != remap_dest->height
1195 || remap_src->width != remap_dest->width
1197 return NULL;
1199 // Loading Palettes
1200 MyPalette* src_palette = remap_src->GetPalette();
1201 if( src_palette == NULL || src_palette->IsOk() == false )
1203 if( src_palette != NULL )
1204 delete src_palette;
1205 return NULL;
1207 int max_ind = src_palette->GetColoursCount();
1208 if( max_ind <= 0 )
1210 delete src_palette;
1211 return NULL;
1213 MyPalette* t_palette = remap_dest->GetPalette();
1214 if( t_palette == NULL || t_palette->IsOk() == false )
1216 if( t_palette != NULL )
1217 delete t_palette;
1218 remap_dest->SetPalette( wxPalette(*src_palette) );
1220 else
1222 if( t_palette->GetColoursCount() > max_ind )
1224 delete src_palette;
1225 max_ind = t_palette->GetColoursCount();
1226 src_palette = t_palette;
1227 remap_src->SetPalette( wxPalette(*src_palette) );
1229 else
1230 delete t_palette;
1232 t_palette = src2->GetPalette();
1233 if( t_palette == NULL || t_palette->IsOk() == false )
1235 if( t_palette != NULL )
1236 delete t_palette;
1237 src2->SetPalette( wxPalette(*src_palette) );
1239 else
1241 if( t_palette->GetColoursCount() > max_ind )
1243 delete src_palette;
1244 max_ind = t_palette->GetColoursCount();
1245 src_palette = t_palette;
1246 remap_src->SetPalette( wxPalette(*src_palette) );
1247 remap_dest->SetPalette( wxPalette(*src_palette) );
1249 else
1250 delete t_palette;
1254 // Init remap array
1255 int* arr_remaps = new int[max_ind];
1256 for( int i = 0; i < max_ind; i++ )
1257 arr_remaps[i] = i;
1259 // Some variables
1260 int nb_pixels = remap_src->height * remap_src->width;
1261 int w = remap_src->width;
1262 // int h = remap_src->height;
1264 // Get the list of remapped colors
1265 for( int i = 0; i < nb_pixels; i++)
1267 int s_ind = remap_src->GetIndex( i%w, i/w );
1268 int d_ind = remap_dest->GetIndex( i%w, i/w );
1269 if( s_ind >= max_ind || d_ind >= max_ind )
1271 delete src_palette;
1272 delete[] arr_remaps;
1273 return NULL;
1275 if( s_ind < 0 )
1276 continue;
1277 arr_remaps[s_ind] = d_ind;
1281 // Now do the remapping
1282 wxImage* res = new wxImage(*src);
1283 res->SetPalette( wxPalette(*src_palette) );
1284 nb_pixels = res->GetWidth() * res->GetHeight();
1285 unsigned char* pixs = res->GetData();
1286 w = src2->width;
1288 for( int i = 0; i < nb_pixels;i++)
1290 int ind = src2->GetIndex(i%w,i/w);
1291 if( (int) ind >= max_ind )
1293 delete src_palette;
1294 delete res;
1295 delete[] arr_remaps;
1296 return NULL;
1299 if( arr_remaps[ind] == ind )
1300 continue;
1302 src_palette->GetRGB(arr_remaps[ind],&pixs[3*i], &pixs[3*i+1], &pixs[3*i+2]);
1305 delete src_palette;
1306 delete[] arr_remaps;
1307 return res;
1310 inline static
1311 bool ANN_IsNumber( int i ) { return (i >= '0' && i <= '9' ); };
1314 P_StrCmp( const wxString& _s0, const wxString& _s1 )
1316 wxString s0 = _s0.Upper();
1317 wxString s1 = _s1.Upper();
1319 size_t max_ind = min( s0.Len(), s1.Len() );
1321 for( size_t i = 0; i < max_ind; i++ )
1323 if( ( isalpha(s0[i]) || ANN_IsNumber( s0[i] ) )
1324 && ( isalpha(s1[i]) || ANN_IsNumber( s1[i] ) )
1327 if( ANN_IsNumber( s0[i] ) && ANN_IsNumber( s1[i] ) )
1329 wxString s0_number;
1330 for( size_t j = i; j < s0.Len(); j++ )
1332 if( ANN_IsNumber( s0[j] ) == true )
1333 s0_number += s0[j];
1334 else
1335 break;
1337 int s0_number_val = StrToInt( s0_number );
1339 wxString s1_number;
1340 for( size_t j = i; j < s1.Len(); j++ )
1342 if( ANN_IsNumber( s1[j] ) == true )
1343 s1_number += s1[j];
1344 else
1345 break;
1347 int s1_number_val = StrToInt( s1_number );
1349 if( s0_number_val < s1_number_val )
1350 return -1;
1351 else if( s0_number_val > s1_number_val )
1352 return 1;
1353 else if( s0_number.Len() < s1_number.Len() )
1354 return -1;
1355 else if( s0_number.Len() > s1_number.Len() )
1356 return 1;
1358 // Exact Same number here => continue
1359 i += s0_number.Len() -1;
1362 else
1364 // Number are lower than letters
1365 if( ANN_IsNumber( s0[i] ) == true )
1366 return -1;
1367 else if( ANN_IsNumber( s1[i] ) == true )
1368 return 1;
1370 // Only letters here
1371 if( s0[i] < s1[i] )
1372 return -1;
1373 else if( s0[i] > s1[i] )
1374 return 1;
1376 // Exact same letter => continue
1380 else
1382 // Alphas are greaters than non-alphas
1383 if( isalpha( s0[i] ) == true )
1384 return 1;
1385 else if( isalpha( s1[i] ) == true )
1386 return -1;
1388 // Two Non alphas
1389 if( s0[i] < s1[i] )
1390 return -1;
1391 else if( s0[i] > s1[i] )
1392 return 1;
1394 // Exact same non-alpha => continue
1398 // Same prefix => the longest is the greater
1399 int diff = s0.Len() < s1.Len();
1400 if( diff < 0 )
1401 return 1;
1402 else if( diff > 0 )
1403 return -1;
1404 return 0;
1407 //----------------------------------------------------------------------
1408 bool
1409 IsEmpty( const wxString& s )
1411 bool res = true;
1412 for( size_t i = 0 ; i < s.Len(); i++ )
1414 if( s[i] != ' '
1415 && s[i] != '\t'
1418 res = false;
1419 break;
1423 return res;