]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/tools/radiant/PreviewDlg.cpp
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / tools / radiant / PreviewDlg.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31
32 #include "qe3.h"
33 #include "Radiant.h"
34 #include "WaitDlg.h"
35 #include "PreviewDlg.h"
36 #include "CommentsDlg.h"
37
38 const int PARENTID = 99999;
39
40 extern HTREEITEM FindTreeItem(CTreeCtrl *tree, HTREEITEM root, const char *text, HTREEITEM forceParent);
41
42 // CPreviewDlg dialog
43
44 IMPLEMENT_DYNAMIC(CPreviewDlg, CDialog)
45 CPreviewDlg::CPreviewDlg(CWnd* pParent /*=NULL*/)
46         : CDialog(CPreviewDlg::IDD, pParent)
47 {
48         currentMode = MODELS;
49         disablePreview = false;
50 }
51
52 CPreviewDlg::~CPreviewDlg()
53 {
54 }
55
56 void CPreviewDlg::DoDataExchange(CDataExchange* pDX)
57 {
58         CDialog::DoDataExchange(pDX);
59         DDX_Control(pDX, IDC_TREE_MEDIA, treeMedia);
60         DDX_Control(pDX, IDC_EDIT_INFO, editInfo);
61         DDX_Control(pDX, IDC_PREVIEW, wndPreview);
62 }
63
64
65 BEGIN_MESSAGE_MAP(CPreviewDlg, CDialog)
66         ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_MEDIA, OnTvnSelchangedTreeMedia)
67         ON_BN_CLICKED(IDC_BUTTON_RELOAD, OnBnClickedButtonReload)
68         ON_BN_CLICKED(IDC_BUTTON_ADD, OnBnClickedButtonAdd)
69         ON_BN_CLICKED(IDC_BUTTON_PLAY, OnBnClickedButtonPlay)
70 END_MESSAGE_MAP()
71
72
73 // CPreviewDlg message handlers
74
75 BOOL CPreviewDlg::OnInitDialog()
76 {
77         CDialog::OnInitDialog();
78
79         m_image.Create(IDB_BITMAP_MATERIAL, 16, 1, RGB(255, 255, 255));
80         treeMedia.SetImageList(&m_image, TVSIL_NORMAL);
81         if ( disablePreview ) {
82                 wndPreview.ShowWindow( SW_HIDE );
83         } else {
84                 wndPreview.setDrawable(&m_testDrawable);
85         }
86         
87         SetMode(currentMode);
88         BuildTree();
89
90         if ( mediaName.Length() ) {
91                 HTREEITEM root = treeMedia.GetRootItem();
92                 HTREEITEM sel = FindTreeItem(&treeMedia, root, mediaName, NULL );
93                 if (sel) {
94                         treeMedia.SelectItem(sel);
95                 }
96         }
97         mediaName = "";
98         return TRUE;  // return TRUE unless you set the focus to a control
99
100 }
101
102 void CPreviewDlg::BuildTree() {
103
104         CWaitCursor cursor;
105         quickTree.Clear();
106         treeMedia.DeleteAllItems();
107
108         idFileList *files;
109         
110         if ( currentMode == GUIS ) {
111                 files = fileSystem->ListFilesTree( "guis", ".gui" );
112                 AddStrList( "base", files->GetList(), GUIS );
113                 fileSystem->FreeFileList( files );
114         } else if ( currentMode == MODELS ) {
115                 files = fileSystem->ListFilesTree( "models", ".lwo" );
116                 AddStrList( "base", files->GetList(), MODELS );
117                 fileSystem->FreeFileList( files );
118                 files = fileSystem->ListFilesTree( "models", ".ase" );
119                 AddStrList( "base", files->GetList(), MODELS );
120                 fileSystem->FreeFileList( files );
121                 files = fileSystem->ListFilesTree( "models", ".ma" );
122                 AddStrList( "base", files->GetList(), MODELS );
123                 fileSystem->FreeFileList( files );
124         } else if ( currentMode == SOUNDS ) {
125                 AddSounds( true );
126         } else if ( currentMode == MATERIALS ) {
127                 AddMaterials( true );
128         } else if ( currentMode == PARTICLES ) {
129                 AddParticles( true );
130         } else if ( currentMode == SKINS ) {
131                 AddSkins( true );
132         }
133 }
134
135 void CPreviewDlg::RebuildTree( const char *_data ) {
136         data = _data;
137         data.ToLower();
138         BuildTree();
139 }
140
141 void CPreviewDlg::AddCommentedItems() {
142         const char *buffer = NULL;
143         const char *path;
144         items.Clear();
145         path = (currentMode == GUIS) ? "guis/guis.commented" : "models/models.commented";
146         idParser src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
147         if (fileSystem->ReadFile(path, (void**)&buffer, NULL) && buffer) {
148                 src.LoadMemory(buffer, strlen(buffer), path);
149                 if (src.IsLoaded()) {
150                         idToken token, tok1, tok2, tok3;
151                         while( src.ReadToken( &token ) ) {
152                                 if (token == "{") {
153                                         // start a new commented item
154                                         CommentedItem ci;
155                                         if (src.ReadToken(&tok1) && src.ReadToken(&tok2) && src.ReadToken(&tok3)) {
156                                                 ci.Name = tok1;
157                                                 ci.Path = tok2;
158                                                 ci.Comments = tok3;
159                                                 items.Append(ci);
160                                         }
161                                 }
162                         }
163                 }
164                 fileSystem->FreeFile((void*)buffer);
165         }
166         commentItem = treeMedia.InsertItem("Commented");
167         int c = items.Num();
168         if (c) {
169                 for (int i = 0; i < c; i++) {
170                         HTREEITEM child = treeMedia.InsertItem(items[i].Name, commentItem);
171                         treeMedia.SetItemData(child, -1 - i);
172                         treeMedia.SetItemImage(child, 2, 2);
173                 }
174         }
175 }
176         
177
178
179 void CPreviewDlg::AddStrList( const char *root, const idStrList &list, int id ) {
180         idStr           out, path;
181         HTREEITEM       base = treeMedia.GetRootItem();
182         if (base) {
183                 out = treeMedia.GetItemText(base);
184                 if (stricmp(root, out)) {
185                         base = NULL;
186                 }
187         }
188
189         if (base == NULL) {
190                 base = treeMedia.InsertItem(root);
191                 treeMedia.SetItemData(base, PARENTID);
192         }
193
194         HTREEITEM       item = base;
195         HTREEITEM       add;
196         
197         int             count = list.Num();
198
199         idStr   last, qt;
200         for (int i = 0; i < count; i++) {
201                 idStr name = list[i];
202
203                 // now break the name down convert to slashes
204                 name.BackSlashesToSlashes();
205                 name.Strip(' ');
206
207                 int index;
208                 int len = last.Length();
209                 if (len == 0) {
210                         index = name.Last('/');
211                         if (index >= 0) {
212                                 name.Left(index, last);
213                         }
214                 }
215                 else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) {
216                         name.Right(name.Length() - len - 1, out);
217                         add = treeMedia.InsertItem(out, item);
218                         qt = root;
219                         qt += "/";
220                         qt += name;
221                         quickTree.Set(qt, add);
222                         treeMedia.SetItemImage(add, 2, 2);
223                         treeMedia.SetItemData(add, id);
224                         continue;
225                 }
226                 else {
227                         last.Empty();
228                 }
229
230                 index = 0;
231                 item = base;
232                 path = "";
233                 while (index >= 0) {
234                         index = name.Find('/');
235                         if (index >= 0) {
236                                 HTREEITEM newItem = NULL;
237                                 HTREEITEM *check = NULL;
238                                 name.Left( index, out );
239                                 path += out;
240                                 qt = root;
241                                 qt += "/";
242                                 qt += path;
243                                 if (quickTree.Get(qt, &check)) {
244                                         newItem = *check;
245                                 }
246                                 //HTREEITEM     newItem = FindTreeItem(&treeMedia, item, name.Left(index, out), item);
247                                 if (newItem == NULL) {
248                                         newItem = treeMedia.InsertItem(out, item);
249                                         qt = root;
250                                         qt += "/";
251                                         qt += path;
252                                         quickTree.Set(qt, newItem);
253                                         treeMedia.SetItemImage(newItem, 0, 1);
254                                         treeMedia.SetItemData(newItem, PARENTID);
255                                 }
256
257                                 assert(newItem);
258                                 item = newItem;
259                                 name.Right(name.Length() - index - 1, out);
260                                 name = out;
261                                 path += "/";
262                         }
263                         else {
264                                 add = treeMedia.InsertItem(name, item);
265                                 qt = root;
266                                 qt += "/";
267                                 qt += path;
268                                 qt += name;
269                                 quickTree.Set(qt, add);
270                                 treeMedia.SetItemImage(add, 2, 2);
271                                 treeMedia.SetItemData(add, id);
272                                 path = "";
273                         }
274                 }
275         }
276
277 }
278
279 void CPreviewDlg::OnTvnSelchangedTreeMedia(NMHDR *pNMHDR, LRESULT *pResult)
280 {
281         LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
282         HTREEITEM item = treeMedia.GetSelectedItem();
283         mediaName = "";
284         CWnd *add = GetDlgItem(IDC_BUTTON_ADD);
285         if (add) {
286                 add->EnableWindow(treeMedia.GetItemData(item) == GUIS || treeMedia.GetItemData(item) == MODELS);
287         }
288         if (item) {
289
290                 editInfo.SetWindowText("No comments for this item");
291                 int id = treeMedia.GetItemData(item);
292                 if ( id == GUIS || id == MODELS || id == MATERIALS || id == WAVES || id == PARTICLES || id == SKINS ) {
293                         mediaName = treeMedia.GetItemText( item );
294
295                         // have to build the name back up
296                         HTREEITEM parent = treeMedia.GetParentItem( item );
297                         while ( parent != NULL ) {
298                                 idStr strParent = treeMedia.GetItemText( parent );
299                                 strParent += "/";
300                                 strParent += mediaName;
301                                 mediaName = strParent;
302                                 parent = treeMedia.GetParentItem( parent );
303                         }
304                         // strip the leading "base/"
305                         if (id == MATERIALS) {
306                                 mediaName.Strip("Materials/");
307                         } else if (id == WAVES) {
308                                 mediaName.Strip( "Wave files/" );
309                         } else if (id == PARTICLES) {
310                                 mediaName.Strip("Particles/");
311                                 mediaName += ".prt";
312                         } else if ( id == SKINS ) {
313                                 mediaName.Strip( "Matching Skins/" );
314                                 mediaName.Strip( "Skins/" );
315                         } else {
316                                 mediaName.Strip( "base/" );
317                         }
318
319                 } else if (id == WAVES || id == SOUNDS) {
320                         mediaName = treeMedia.GetItemText( item );
321                 } else if (id < 0) {
322                         if ( treeMedia.ItemHasChildren(item) == FALSE ) {
323                                 int dw = abs(( int )treeMedia.GetItemData( item )) - 1;
324                                 if ( dw < items.Num() ) {
325                                         idStr work = items[dw].Path;
326                                         work += "\r\n\r\n";
327                                         work += items[dw].Comments;
328                                         editInfo.SetWindowText( work );
329                                         mediaName = items[dw].Path;
330                                 }
331                         }
332                 }
333
334                 if ( currentMode == MODELS || currentMode == SKINS ) {
335                         idStr modelMedia;
336                         if ( currentMode == MODELS ) {
337                                 modelMedia = mediaName;
338                         } else {
339                                 modelMedia = data;
340                         }
341                         if ( modelMedia.Length() ) {
342                                 int size = fileSystem->ReadFile( modelMedia, NULL, NULL );
343                                 int lsize;
344                                 if ( strstr( modelMedia, ".lwo" ) ) {
345                                         lsize = 128 * 1024;
346                                 }
347                                 else {
348                                         lsize = 768 * 1024;
349                                 }
350                                 if ( size > lsize ) {
351                                         if ( MessageBox("Model appears to be quite large, are you sure you want to preview it?", "High Poly Model?", MB_YESNO ) == IDNO ) {
352                                                 *pResult = 0;
353                                                 return;
354                                         }
355                                 }
356                                 m_drawModel.setMedia( modelMedia );
357                                 if ( currentMode == SKINS ) {
358                                         m_drawModel.SetSkin( mediaName );
359                                 }
360                         }
361                         m_drawModel.SetRealTime(0);
362                         wndPreview.setDrawable( &m_drawModel );
363                         wndPreview.Invalidate();
364                         wndPreview.RedrawWindow();
365                         RedrawWindow();
366                 }
367                 else if ( currentMode == PARTICLES ) {
368                         m_drawModel.setMedia( mediaName );
369                         m_drawModel.SetRealTime(50);
370                         wndPreview.setDrawable( &m_drawModel );
371                         wndPreview.Invalidate();
372                         wndPreview.RedrawWindow();
373                         RedrawWindow();
374                 } else if ( currentMode == GUIS ) {
375                         const idMaterial *mat = declManager->FindMaterial("guisurfs/guipreview");
376                         mat->SetGui(mediaName);
377                         m_drawMaterial.setMedia("guisurfs/guipreview");
378                         m_drawMaterial.setScale(4.4f);
379                         wndPreview.setDrawable(&m_drawMaterial);
380                         wndPreview.Invalidate();
381                         wndPreview.RedrawWindow();
382                         idUserInterface *gui = uiManager->FindGui( mediaName, false, false, true );
383                         if ( gui ) {
384                                 idStr str = gui->Comment();
385                                 str.Replace( "\n", "\r\n" );
386                                 if ( str != "" ) {
387                                         editInfo.SetWindowText( str );
388                                 }
389                         }
390                         RedrawWindow();
391                 } else if (currentMode == MATERIALS) {
392                         m_drawMaterial.setMedia(mediaName);
393                         m_drawMaterial.setScale(1.0);
394                         wndPreview.setDrawable(&m_drawMaterial);
395                         wndPreview.Invalidate();
396                         wndPreview.RedrawWindow();
397                         RedrawWindow();
398                 }
399
400                 //m_drawGui.setMedia(matName);
401                 //wndPreview.setDrawable(&m_drawMaterial);
402                 //wndPreview.RedrawWindow();
403         }
404
405         *pResult = 0;
406 }
407
408
409 BOOL CPreviewDlg::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
410 {
411         BOOL b =  CDialog::Create(lpszTemplateName, pParentWnd);
412         ShowWindow(SW_SHOW);
413         return b;
414 }
415
416 void CPreviewDlg::OnCancel()
417 {
418         if ( AfxGetApp()->GetMainWnd() == GetParent() && GetParent() ) {
419                 GetParent()->EnableWindow(TRUE);
420                 g_qeglobals.sw->StopAllSounds();
421                 ShowWindow(SW_HIDE);
422         } else {
423                 CDialog::OnCancel();
424         }
425         returnCode = IDCANCEL;
426 }
427
428 void CPreviewDlg::OnOK()
429 {
430         if ( AfxGetApp()->GetMainWnd() == GetParent() && GetParent() ) {
431                 GetParent()->EnableWindow(TRUE);
432                 g_qeglobals.sw->StopAllSounds();
433                 ShowWindow(SW_HIDE);
434         } else {
435                 CDialog::OnOK();
436         }
437         returnCode = IDOK;
438 }
439
440 bool CPreviewDlg::Waiting() {
441         AfxGetApp()->PumpMessage();
442         return (returnCode == -1);
443 }
444
445 void CPreviewDlg::SetModal() {
446         returnCode = -1;
447 }
448 void CPreviewDlg::OnBnClickedButtonReload()
449 {
450         BuildTree();
451         g_qeglobals.sw->StopAllSounds();
452 }
453
454 void CPreviewDlg::OnBnClickedButtonAdd()
455 {
456         HTREEITEM item = treeMedia.GetSelectedItem();
457         if (treeMedia.ItemHasChildren(item) == FALSE && (treeMedia.GetItemData(item) == GUIS || treeMedia.GetItemData(item) == MODELS)) {
458                 CCommentsDlg dlg;
459                 dlg.strPath = mediaName;
460                 if (dlg.DoModal()) {
461                         CommentedItem ci;
462                         ci.Name = dlg.strName;
463                         ci.Path = dlg.strPath;
464                         ci.Comments = dlg.strComments;
465                         items.Append(ci);
466                         item = treeMedia.InsertItem(ci.Name, commentItem);
467                         treeMedia.SetItemData(item, -1 - (items.Num() + 1));
468                         treeMedia.SetItemImage(item, 2, 2);
469                         const char *path;
470                         path = (currentMode == GUIS) ? "guis/guis.commented" : "models/models.commented";
471                         idStr str;
472                         void *buffer;
473                         fileSystem->ReadFile( path, &buffer );
474                         str = (char *) buffer;
475                         fileSystem->FreeFile( buffer );
476                         str += "\r\n\r\n{\r\n\t\"";
477                         str += ci.Name;
478                         str += "\"\r\n\t\"";
479                         str += ci.Path;
480                         str += "\"\r\n\t\"";
481                         str += ci.Comments;
482                         str += "\"\r\n}\r\n";
483                         fileSystem->WriteFile(path, (void*)&str[0], str.Length(), "fs_devpath");
484
485                 }
486         }
487 }
488
489
490 void CPreviewDlg::AddSounds(bool rootItems) {
491         int i, j;
492         idStrList list(1024);
493         idStrList list2(1024);
494         HTREEITEM base = treeMedia.InsertItem("Sound Shaders");
495          
496         for( i = 0; i < declManager->GetNumDecls( DECL_SOUND ); i++ ) {
497                 const idSoundShader *poo = declManager->SoundByIndex( i, false );
498                 list.AddUnique( poo->GetFileName() );
499         }
500         list.Sort();
501         
502         for ( i = 0; i < list.Num(); i++ ) {
503                 HTREEITEM child = treeMedia.InsertItem(list[i], base);
504                 treeMedia.SetItemData(child, SOUNDPARENT);
505                 treeMedia.SetItemImage(child, 0, 1);
506                 list2.Clear();
507                 for (j = 0; j < declManager->GetNumDecls( DECL_SOUND ); j++) {
508                         const idSoundShader *poo = declManager->SoundByIndex( j, false );
509                         if ( idStr::Icmp( list[i], poo->GetFileName() ) == 0 ) {
510                                 list2.Append( poo->GetName() );
511                         }
512                 }
513                 list2.Sort();           
514                 for (j = 0; j < list2.Num(); j++) {
515                         HTREEITEM child2 = treeMedia.InsertItem( list2[j], child );
516                         treeMedia.SetItemData(child2, SOUNDS);
517                         treeMedia.SetItemImage(child2, 2, 2);
518                 }
519         }
520
521         idFileList *files;
522         files = fileSystem->ListFilesTree( "sound", ".wav" );
523     AddStrList( "Wave files", files->GetList(), WAVES );
524         fileSystem->FreeFileList( files );
525 }
526
527 void CPreviewDlg::SetMode( int mode, const char *preSelect ) {
528         
529         currentMode = mode;
530         if ( preSelect ) {
531                 mediaName = preSelect;
532         }
533
534         if (GetSafeHwnd() == NULL) {
535                 return;
536         }
537
538         CWnd *wnd;
539         switch (currentMode) {
540                 case GUIS :
541                 case SKINS :
542                 case MODELS :
543                 case PARTICLES :
544                                 wndPreview.ShowWindow(SW_SHOW);
545                                 wnd = GetDlgItem(IDC_BUTTON_PLAY);
546                                 if (wnd) {
547                                         wnd->ShowWindow(SW_HIDE);
548                                 }
549                                 wnd = GetDlgItem(IDC_BUTTON_ADD);
550                                 if (wnd) {
551                                         wnd->ShowWindow(SW_SHOW);
552                                 }
553                                 wnd = GetDlgItem(IDC_EDIT_INFO);
554                                 if (wnd) {
555                                         wnd->ShowWindow(SW_SHOW);
556                                 }
557                         break;
558                 case MATERIALS :
559                                 wndPreview.ShowWindow(SW_SHOW);
560                                 wnd = GetDlgItem(IDC_BUTTON_PLAY);
561                                 if (wnd) {
562                                         wnd->ShowWindow(SW_HIDE);
563                                 }
564                                 wnd = GetDlgItem(IDC_BUTTON_ADD);
565                                 if (wnd) {
566                                         wnd->ShowWindow(SW_HIDE);
567                                 }
568                                 wnd = GetDlgItem(IDC_EDIT_INFO);
569                                 if (wnd) {
570                                         wnd->ShowWindow(SW_HIDE);
571                                 }
572                                 break;
573                 case SOUNDS :
574                 case WAVES :
575                                 wndPreview.ShowWindow(SW_HIDE);
576                                 wnd = GetDlgItem(IDC_BUTTON_PLAY);
577                                 if (wnd) {
578                                         wnd->ShowWindow(SW_SHOW);
579                                 }
580                                 wnd = GetDlgItem(IDC_BUTTON_ADD);
581                                 if (wnd) {
582                                         wnd->ShowWindow(SW_HIDE);
583                                 }
584                                 wnd = GetDlgItem(IDC_EDIT_INFO);
585                                 if (wnd) {
586                                         wnd->ShowWindow(SW_HIDE);
587                                 }
588                         break;
589         }
590 }
591
592 void CPreviewDlg::OnBnClickedButtonPlay() {
593         g_qeglobals.sw->PlayShaderDirectly(mediaName);
594 }
595
596 void CPreviewDlg::AddMaterials(bool rootItems) {
597         idStrList list(1024);
598         //char temp[2048];
599         int count = declManager->GetNumDecls( DECL_MATERIAL );
600         if (count > 0) {
601                 for (int i = 0; i < count; i++) {
602                         const idMaterial *mat = declManager->MaterialByIndex(i, false);
603                         if (!rootItems) {
604                                 if (strchr(mat->GetName(), '/') == NULL && strchr(mat->GetName(), '\\') == NULL) {
605                                         continue;
606                                 }
607                         }
608                         list.Append(mat->GetName());
609                 }
610                 list.Sort();
611                 AddStrList("Materials", list, MATERIALS);
612         }
613
614 }
615
616 void CPreviewDlg::AddParticles(bool rootItems) {
617         idStrList list(1024);
618         int count = declManager->GetNumDecls( DECL_PARTICLE );
619         if (count > 0) {
620                 for (int i = 0; i < count; i++) {
621                         const idDecl *ips = declManager->DeclByIndex( DECL_PARTICLE, i );
622                         if (!rootItems) {
623                                 if (strchr(ips->GetName(), '/') == NULL && strchr(ips->GetName(), '\\') == NULL) {
624                                         continue;
625                                 }
626                         }
627                         list.Append(ips->GetName());
628                 }
629                 list.Sort();
630                 AddStrList("Particles", list, PARTICLES);
631         }
632 }
633
634 void CPreviewDlg::AddSkins( bool rootItems ) {
635         idStrList list(1024);
636         idStrList list2(1024);
637         idStr str;
638         int count = declManager->GetNumDecls( DECL_SKIN );
639         if (count > 0) {
640                 for (int i = 0; i < count; i++) {
641                         const idDeclSkin *skin = declManager->SkinByIndex(i);
642                         if (!rootItems) {
643                                 if (strchr(skin->GetName(), '/') == NULL && strchr(skin->GetName(), '\\') == NULL) {
644                                         continue;
645                                 }
646                         }
647                         if ( data.Length() ) {
648                                 for ( int j = 0; j < skin->GetNumModelAssociations(); j++ ){
649                                         str = skin->GetAssociatedModel( j );
650                                         str.ToLower();
651                                         if ( data.Cmp(str) == 0 ) {
652                                                 list.Append(skin->GetName());
653                                         }
654                                 }
655                         }
656                         list2.Append(skin->GetName());
657                 }
658                 list.Sort();
659                 list2.Sort();
660                 AddStrList( "Matching Skins", list, SKINS );
661                 AddStrList( "Skins", list2, SKINS );
662         }
663 }
664
665 void CPreviewDlg::OnShowWindow( BOOL bShow, UINT status ) {
666         if ( bShow && AfxGetApp()->GetMainWnd() == GetParent() && GetParent() ) {
667                 GetParent()->EnableWindow( FALSE );
668         }               
669 }