]> git.saurik.com Git - wxWidgets.git/blame - utils/dialoged/src/reseditr.cpp
Fixed drawing of the lines data, also ensure that only tuples are
[wxWidgets.git] / utils / dialoged / src / reseditr.cpp
CommitLineData
457814b5
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: reseditr.cpp
3// Purpose: Resource editor class
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "reseditr.h"
14#endif
15
16// For compilers that support precompilation, includes "wx/wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/wx.h"
25
26#include "wx/checkbox.h"
27#include "wx/button.h"
28#include "wx/choice.h"
29#include "wx/listbox.h"
30#include "wx/radiobox.h"
31#include "wx/statbox.h"
32#include "wx/gauge.h"
33#include "wx/slider.h"
34#include "wx/textctrl.h"
b127f301
RR
35#include "wx/menu.h"
36#include "wx/toolbar.h"
457814b5
JS
37#endif
38
39#include "wx/scrolbar.h"
560b92f5 40#include "wx/config.h"
f6bcfd97
BP
41#include "wx/dir.h"
42#include "wx/progdlg.h"
457814b5
JS
43
44#include <ctype.h>
45#include <stdlib.h>
46#include <math.h>
47#include <string.h>
48
d0fff5cb 49#ifdef __WXMSW__
457814b5 50#include "wx/help.h"
b127f301 51#endif
457814b5
JS
52
53#include "reseditr.h"
54#include "winprop.h"
457814b5 55#include "dlghndlr.h"
ae8351fc
JS
56#include "edtree.h"
57#include "edlist.h"
457814b5 58
ae8351fc 59wxResourceManager *wxResourceManager::sm_currentResourceManager = NULL;
457814b5 60
3f2b72b2 61#if !defined(__WXMSW__)
b127f301
RR
62#include "bitmaps/load.xpm"
63#include "bitmaps/save.xpm"
64#include "bitmaps/new.xpm"
d5c462fd
RR
65#include "bitmaps/vert.xpm"
66#include "bitmaps/alignt.xpm"
67#include "bitmaps/alignb.xpm"
68#include "bitmaps/horiz.xpm"
69#include "bitmaps/alignl.xpm"
70#include "bitmaps/alignr.xpm"
71#include "bitmaps/copysize.xpm"
72#include "bitmaps/tofront.xpm"
73#include "bitmaps/toback.xpm"
74#include "bitmaps/help.xpm"
75#include "bitmaps/wxwin.xpm"
f6bcfd97
BP
76#include "bitmaps/distvert.xpm"
77#include "bitmaps/disthor.xpm"
78#include "bitmaps/copywdth.xpm"
79#include "bitmaps/copyhght.xpm"
b46e8696
RR
80
81#include "bitmaps/dialog.xpm"
82#include "bitmaps/folder1.xpm"
83#include "bitmaps/folder2.xpm"
84#include "bitmaps/buttonsm.xpm"
457814b5
JS
85#endif
86
87/*
f6bcfd97
BP
88* Resource manager
89*/
457814b5 90
ae8351fc 91wxResourceManager::wxResourceManager():
f6bcfd97
BP
92m_imageList(16, 16, TRUE)
93{
94 sm_currentResourceManager = this;
95 m_editorFrame = NULL;
96 m_editorPanel = NULL;
97 m_popupMenu = NULL;
98 m_editorResourceTree = NULL;
99 m_editorControlList = NULL;
100 m_nameCounter = 1;
101 m_symbolIdCounter = 99;
102 m_modified = FALSE;
103 m_currentFilename = "";
104 m_symbolFilename = "";
105 m_editorToolBar = NULL;
106
107 // Default window positions
108 m_resourceEditorWindowSize.width = 500;
109 m_resourceEditorWindowSize.height = 450;
110
111 m_resourceEditorWindowSize.x = 0;
112 m_resourceEditorWindowSize.y = 0;
113
114 m_propertyWindowSize.width = 300;
115 m_propertyWindowSize.height = 300;
116
d0fff5cb 117#ifdef __WXMSW__
f6bcfd97 118 m_helpController = NULL;
b127f301 119#endif
f6bcfd97
BP
120
121 m_bitmapImage = NULL;
122 m_rootDialogItem = 0;
457814b5
JS
123}
124
ae8351fc 125wxResourceManager::~wxResourceManager()
457814b5 126{
f6bcfd97
BP
127 sm_currentResourceManager = NULL;
128 SaveOptions();
129
d0fff5cb 130#ifdef __WXMSW__
f6bcfd97
BP
131 if (m_helpController)
132 {
133 m_helpController->Quit();
134 delete m_helpController;
135 m_helpController = NULL;
136 }
b127f301 137#endif
f6bcfd97
BP
138
139 delete m_bitmapImage;
140 delete m_popupMenu;
457814b5
JS
141}
142
ae8351fc 143bool wxResourceManager::Initialize()
457814b5 144{
f6bcfd97
BP
145 // Set up the resource filename for each platform.
146 // TODO: This shold be replaced by wxConfig usage.
2049ba38 147#ifdef __WXMSW__
f6bcfd97
BP
148 // dialoged.ini in the Windows directory
149 wxString windowsDir = wxGetOSDirectory();
150 windowsDir += "\\dialoged.ini" ;
151
152 m_optionsResourceFilename = windowsDir;
3f2b72b2 153#else
f6bcfd97
BP
154 wxGetHomeDir( &m_optionsResourceFilename );
155 m_optionsResourceFilename += "/.dialogedrc";
457814b5 156#endif
f6bcfd97
BP
157
158 LoadOptions();
159
d0fff5cb 160#ifdef __WXMSW__
f6bcfd97
BP
161 m_helpController = new wxHelpController;
162 m_helpController->Initialize("dialoged");
b127f301 163#endif
f6bcfd97
BP
164
165 m_popupMenu = new wxMenu;
58d5bf3a
GT
166 m_popupMenu->Append(OBJECT_MENU_TITLE, "WIDGET TYPE");
167 m_popupMenu->AppendSeparator();
f6bcfd97
BP
168 m_popupMenu->Append(OBJECT_MENU_EDIT, "Edit properties");
169 m_popupMenu->Append(OBJECT_MENU_DELETE, "Delete object");
170
171 if (!m_bitmapImage)
172 {
2049ba38 173#ifdef __WXMSW__
f6bcfd97 174 m_bitmapImage = new wxBitmap("WXWINBMP", wxBITMAP_TYPE_BMP_RESOURCE);
3f2b72b2 175#else
f6bcfd97 176 m_bitmapImage = new wxBitmap( wxwin_xpm );
457814b5 177#endif
f6bcfd97
BP
178 }
179
180 // Initialize the image list icons
2049ba38 181#ifdef __WXMSW__
f6bcfd97
BP
182 wxIcon icon1("DIALOG_ICON", wxBITMAP_TYPE_ICO_RESOURCE, 16, 16);
183 wxIcon icon2("FOLDER1_ICON", wxBITMAP_TYPE_ICO_RESOURCE, 16, 16);
184 wxIcon icon3("FOLDER2_ICON", wxBITMAP_TYPE_ICO_RESOURCE, 16, 16);
185 wxIcon icon4("BUTTONSM_ICON", wxBITMAP_TYPE_ICO_RESOURCE, 16, 16);
b46e8696 186#else
f6bcfd97
BP
187 wxIcon icon1( dialog_xpm );
188 wxIcon icon2( folder1_xpm );
189 wxIcon icon3( folder2_xpm );
190 wxIcon icon4( buttonsm_xpm );
b46e8696 191#endif
f6bcfd97
BP
192 m_imageList.Add(icon1);
193 m_imageList.Add(icon2);
194 m_imageList.Add(icon3);
195 m_imageList.Add(icon4);
196
197 m_symbolTable.AddStandardSymbols();
198
199 return TRUE;
457814b5
JS
200}
201
ae8351fc 202bool wxResourceManager::LoadOptions()
457814b5 203{
f6bcfd97
BP
204 wxConfig config("DialogEd", "wxWindows");
205
206 config.Read("editorWindowX", &m_resourceEditorWindowSize.x);
207 config.Read("editorWindowY", &m_resourceEditorWindowSize.y);
208 config.Read("editorWindowWidth", &m_resourceEditorWindowSize.width);
209 config.Read("editorWindowHeight", &m_resourceEditorWindowSize.height);
210 config.Read("propertyWindowX", &m_propertyWindowSize.x);
211 config.Read("propertyWindowY", &m_propertyWindowSize.y);
212 config.Read("propertyWindowWidth", &m_propertyWindowSize.width);
213 config.Read("propertyWindowHeight", &m_propertyWindowSize.height);
214
215 return TRUE;
457814b5
JS
216}
217
ae8351fc 218bool wxResourceManager::SaveOptions()
457814b5 219{
f6bcfd97
BP
220 wxConfig config("DialogEd", "wxWindows");
221
222 config.Write("editorWindowX", (long) m_resourceEditorWindowSize.x);
223 config.Write("editorWindowY", (long) m_resourceEditorWindowSize.y);
224 config.Write("editorWindowWidth", (long) m_resourceEditorWindowSize.width);
225 config.Write("editorWindowHeight", (long) m_resourceEditorWindowSize.height);
226 config.Write("propertyWindowX", (long) m_propertyWindowSize.x);
227 config.Write("propertyWindowY", (long) m_propertyWindowSize.y);
228 config.Write("propertyWindowWidth", (long) m_propertyWindowSize.width);
229 config.Write("propertyWindowHeight", (long) m_propertyWindowSize.height);
230
231 return TRUE;
457814b5
JS
232}
233
234// Show or hide the resource editor frame, which displays a list
235// of resources with ability to edit them.
b127f301 236bool wxResourceManager::ShowResourceEditor(bool show, wxWindow *WXUNUSED(parent), const char *title)
457814b5 237{
f6bcfd97 238 if (show)
457814b5 239 {
f6bcfd97
BP
240 if (m_editorFrame)
241 {
242 m_editorFrame->Iconize(FALSE);
243 m_editorFrame->Show(TRUE);
244 return TRUE;
245 }
246 m_editorFrame = OnCreateEditorFrame(title);
247 SetFrameTitle("");
248 wxMenuBar *menuBar = OnCreateEditorMenuBar(m_editorFrame);
249 m_editorFrame->SetMenuBar(menuBar);
250
251 m_editorToolBar = (EditorToolBar *)OnCreateToolBar(m_editorFrame);
252 m_editorControlList = new wxResourceEditorControlList(m_editorFrame, IDC_LISTCTRL, wxPoint(0, 0), wxSize(-1, -1));
253 m_editorResourceTree = new wxResourceEditorProjectTree(m_editorFrame, IDC_TREECTRL, wxPoint(0, 0), wxSize(-1, -1),
254 wxTR_HAS_BUTTONS);
255 m_editorPanel = OnCreateEditorPanel(m_editorFrame);
256
257 m_editorResourceTree->SetImageList(& m_imageList);
258
259 // Constraints for toolbar
260 wxLayoutConstraints *c = new wxLayoutConstraints;
261 c->left.SameAs (m_editorFrame, wxLeft, 0);
262 c->top.SameAs (m_editorFrame, wxTop, 0);
263 c->right.SameAs (m_editorFrame, wxRight, 0);
264 c->bottom.Unconstrained();
265 c->width.Unconstrained();
266 c->height.Absolute(28);
267 m_editorToolBar->SetConstraints(c);
268
269 // Constraints for listbox
270 c = new wxLayoutConstraints;
271 c->left.SameAs (m_editorFrame, wxLeft, 0);
272 c->top.SameAs (m_editorToolBar, wxBottom, 0);
273 c->right.Absolute (150);
274 c->bottom.SameAs (m_editorControlList, wxTop, 0);
275 c->width.Unconstrained();
276 c->height.Unconstrained();
277 m_editorResourceTree->SetConstraints(c);
278
279 // Constraints for panel
280 c = new wxLayoutConstraints;
281 c->left.SameAs (m_editorResourceTree, wxRight, 0);
282 c->top.SameAs (m_editorToolBar, wxBottom, 0);
283 c->right.SameAs (m_editorFrame, wxRight, 0);
284 c->bottom.SameAs (m_editorControlList, wxTop, 0);
285 c->width.Unconstrained();
286 c->height.Unconstrained();
287 m_editorPanel->SetConstraints(c);
288
289 // Constraints for control list (bottom window)
290 c = new wxLayoutConstraints;
291 c->left.SameAs (m_editorFrame, wxLeft, 0);
292 c->right.SameAs (m_editorFrame, wxRight, 0);
293 c->bottom.SameAs (m_editorFrame, wxBottom, 0);
294 c->width.Unconstrained();
15d5ab67 295#if defined(__WXGTK__) || defined(__WXMOTIF__)
f6bcfd97 296 c->height.Absolute(120);
b127f301 297#else
f6bcfd97 298 c->height.Absolute(60);
b127f301 299#endif
f6bcfd97
BP
300
301 m_editorControlList->SetConstraints(c);
302
303 m_editorFrame->SetAutoLayout(TRUE);
304
305 UpdateResourceList();
306
307 m_editorFrame->Show(TRUE);
308 return TRUE;
309 }
310 else
457814b5 311 {
f6bcfd97
BP
312 if (m_editorFrame->Close())
313 {
314 m_editorFrame = NULL;
315 m_editorPanel = NULL;
316 }
457814b5 317 }
f6bcfd97 318 return TRUE;
457814b5
JS
319}
320
321void wxResourceManager::SetFrameTitle(const wxString& filename)
322{
f6bcfd97 323 if (m_editorFrame)
457814b5 324 {
f6bcfd97
BP
325 if (filename == wxString(""))
326 m_editorFrame->SetTitle("wxWindows Dialog Editor - untitled");
327 else
328 {
329 wxString str("wxWindows Dialog Editor - ");
330 wxString str2(wxFileNameFromPath(WXSTRINGCAST filename));
331 str += str2;
332 m_editorFrame->SetTitle(str);
333 }
457814b5 334 }
457814b5
JS
335}
336
ae8351fc 337bool wxResourceManager::Save()
457814b5 338{
f6bcfd97
BP
339 if (m_currentFilename == wxString(""))
340 return SaveAs();
341 else
342 return Save(m_currentFilename);
457814b5
JS
343}
344
345bool wxResourceManager::Save(const wxString& filename)
346{
f6bcfd97
BP
347 // Ensure all visible windows are saved to their resources
348 m_currentFilename = filename;
349 SetFrameTitle(m_currentFilename);
350 InstantiateAllResourcesFromWindows();
351 if (m_resourceTable.Save(filename))
352 {
353 m_symbolTable.WriteIncludeFile(m_symbolFilename);
354 Modify(FALSE);
355 return TRUE;
356 }
357 else
358 return FALSE;
457814b5
JS
359}
360
ae8351fc 361bool wxResourceManager::SaveAs()
457814b5 362{
f6bcfd97
BP
363 wxString s(wxFileSelector("Save resource file", wxPathOnly(WXSTRINGCAST m_currentFilename), wxFileNameFromPath(WXSTRINGCAST m_currentFilename),
364 "wxr", "*.wxr", wxSAVE | wxOVERWRITE_PROMPT, wxTheApp->GetTopWindow()));
457814b5 365
f6bcfd97
BP
366 if (s.IsNull() || s == "")
367 return FALSE;
457814b5 368
f6bcfd97
BP
369 m_currentFilename = s;
370 wxStripExtension(m_currentFilename);
371 m_currentFilename += ".wxr";
372
373 // Construct include filename from this file
374 m_symbolFilename = m_currentFilename;
375
376 wxStripExtension(m_symbolFilename);
377 m_symbolFilename += ".h";
378
379 Save(m_currentFilename);
380 return TRUE;
457814b5
JS
381}
382
ae8351fc 383bool wxResourceManager::SaveIfModified()
457814b5 384{
f6bcfd97
BP
385 if (Modified())
386 return Save();
387 else return TRUE;
457814b5
JS
388}
389
390bool wxResourceManager::Load(const wxString& filename)
391{
f6bcfd97 392 return New(TRUE, filename);
457814b5
JS
393}
394
395bool wxResourceManager::New(bool loadFromFile, const wxString& filename)
396{
f6bcfd97 397 if (!Clear(TRUE, FALSE))
457814b5 398 return FALSE;
457814b5 399
f6bcfd97
BP
400 m_symbolTable.AddStandardSymbols();
401
402 if (loadFromFile)
03f68f12 403 {
f6bcfd97
BP
404 wxString str = filename;
405 if (str == wxString(""))
406 {
407 wxString f(wxFileSelector("Open resource file", wxGetCwd(), wxEmptyString, "wxr", "*.wxr", 0, wxTheApp->GetTopWindow()));
408 if (!f.IsNull() && f != "")
409 str = f;
410 else
411 return FALSE;
412 }
413
414 if (!m_resourceTable.ParseResourceFile(str))
415 {
416 wxMessageBox("Could not read file.", "Resource file load error", wxOK | wxICON_EXCLAMATION);
417 return FALSE;
418 }
419 m_currentFilename = str;
420
421 SetFrameTitle(m_currentFilename);
422
423 UpdateResourceList();
424
425 // Construct include filename from this file
426 m_symbolFilename = m_currentFilename;
427
428 wxStripExtension(m_symbolFilename);
429 m_symbolFilename += ".h";
430
431 if (!m_symbolTable.ReadIncludeFile(m_symbolFilename))
432 {
433 wxString str("Could not find include file ");
434 str += m_symbolFilename;
435 str += ".\nDialog Editor maintains a header file containing id symbols to be used in the application.\n";
436 str += "The next time this .wxr file is saved, a header file will be saved also.";
437 wxMessageBox(str, "Dialog Editor Warning", wxOK );
438
439 m_symbolIdCounter = 99;
440 }
441 else
442 {
443 // Set the id counter to the last known id
444 m_symbolIdCounter = m_symbolTable.FindHighestId();
445 }
446
447 // Now check in case some (or all) resources don't have resource ids, or they
448 // don't match the .h file, or something of that nature.
449 bool altered = RepairResourceIds();
450 if (altered)
451 {
452 wxMessageBox("Some resources have had new identifiers associated with them, since they were missing.",
453 "Dialog Editor Warning", wxOK );
454 Modify(TRUE);
455 }
456 else
457 Modify(FALSE);
458
459 return TRUE;
5de76427
JS
460 }
461 else
462 {
f6bcfd97
BP
463 SetFrameTitle("");
464 m_currentFilename = "";
bbcdf8bc 465 }
f6bcfd97
BP
466 Modify(FALSE);
467
bbcdf8bc 468 return TRUE;
457814b5
JS
469}
470
b127f301 471bool wxResourceManager::Clear(bool WXUNUSED(deleteWindows), bool force)
457814b5 472{
f6bcfd97
BP
473 wxPropertyInfo::CloseWindow();
474
475 if (!force && Modified())
476 {
477 int ans = wxMessageBox("Save modified resource file?", "Dialog Editor", wxYES_NO | wxCANCEL);
478 if (ans == wxCANCEL)
479 return FALSE;
480 if (ans == wxYES)
481 if (!SaveIfModified())
482 return FALSE;
483 if (ans == wxNO)
484 Modify(FALSE);
485 }
486
487 ClearCurrentDialog();
488 DisassociateWindows();
489
490 m_symbolTable.Clear();
491 m_resourceTable.ClearTable();
492 UpdateResourceList();
493
494 return TRUE;
457814b5
JS
495}
496
ae8351fc 497bool wxResourceManager::DisassociateWindows()
457814b5 498{
f6bcfd97
BP
499 m_resourceTable.BeginFind();
500 wxNode *node;
501 while ((node = m_resourceTable.Next()))
502 {
503 wxItemResource *res = (wxItemResource *)node->Data();
504 DisassociateResource(res);
505 }
506
507 return TRUE;
457814b5
JS
508}
509
510void wxResourceManager::AssociateResource(wxItemResource *resource, wxWindow *win)
511{
f6bcfd97
BP
512 if (!m_resourceAssociations.Get((long)resource))
513 m_resourceAssociations.Put((long)resource, win);
514
515 wxNode *node = resource->GetChildren().First();
516 wxNode* node2 = win->GetChildren().First();
517 while (node && node2)
8caa4ed1 518 {
f6bcfd97
BP
519 wxItemResource *child = (wxItemResource *)node->Data();
520 wxWindow* childWindow = (wxWindow*) node2->Data();
521
522 if (child->GetId() != childWindow->GetId())
523 {
524 wxString msg;
525 msg.Printf("AssociateResource: error when associating child window %ld with resource %ld", child->GetId(), childWindow->GetId());
526 wxMessageBox(msg, "Dialog Editor problem", wxOK);
527 }
528 else if (childWindow->GetName() != child->GetName())
529 {
530 wxString msg;
531 msg.Printf("AssociateResource: error when associating child window with resource %s", child->GetName() ? (const char*) child->GetName() : "(unnamed)");
532 wxMessageBox(msg, "Dialog Editor problem", wxOK);
533 }
534 else
535 {
536 AssociateResource(child, childWindow);
537 }
538
539 // New code to avoid the problem of duplicate ids and names. We simply
540 // traverse the child windows and child resources in parallel,
541 // checking for any mismatch.
8caa4ed1 542#if 0
f6bcfd97
BP
543 wxWindow *childWindow = (wxWindow *)m_resourceAssociations.Get((long)child);
544 if (!childWindow)
545 // childWindow = win->FindWindow(child->GetName());
546 childWindow = win->FindWindow(child->GetId());
547 if (childWindow)
548 AssociateResource(child, childWindow);
549 else
550 {
551 wxString msg;
552 msg.Printf("AssociateResource: cannot find child window %s", child->GetName() ? (const char*) child->GetName() : "(unnamed)");
553 wxMessageBox(msg, "Dialog Editor problem", wxOK);
554 }
8caa4ed1 555#endif
f6bcfd97
BP
556 node = node->Next();
557 node2 = node2->Next();
558 }
457814b5
JS
559}
560
ae8351fc 561bool wxResourceManager::DisassociateResource(wxItemResource *resource)
457814b5 562{
f6bcfd97
BP
563 wxWindow *win = FindWindowForResource(resource);
564 if (!win)
565 return FALSE;
566
567 // Disassociate children of window
568 wxNode *node = win->GetChildren().First();
569 while (node)
570 {
571 wxWindow *child = (wxWindow *)node->Data();
572 if (child->IsKindOf(CLASSINFO(wxControl)))
573 DisassociateResource(child);
574 node = node->Next();
575 }
576
577 RemoveSelection(win);
578 m_resourceAssociations.Delete((long)resource);
579 return TRUE;
457814b5
JS
580}
581
ae8351fc 582bool wxResourceManager::DisassociateResource(wxWindow *win)
457814b5 583{
f6bcfd97
BP
584 wxItemResource *res = FindResourceForWindow(win);
585 if (res)
586 return DisassociateResource(res);
587 else
588 return FALSE;
ae8351fc
JS
589}
590
591// Saves the window info into the resource, and deletes the
592// handler. Doesn't actually disassociate the window from
593// the resources. Replaces OnClose.
594bool wxResourceManager::SaveInfoAndDeleteHandler(wxWindow* win)
595{
596 wxItemResource *res = FindResourceForWindow(win);
f6bcfd97 597
ae8351fc
JS
598 if (win->IsKindOf(CLASSINFO(wxPanel)))
599 {
600 wxResourceEditorDialogHandler* handler = (wxResourceEditorDialogHandler*) win->GetEventHandler();
601 win->PopEventHandler();
f6bcfd97 602
ae8351fc 603 // Now reset all child event handlers
c030b70f 604 wxNode *node = win->GetChildren().First();
ae8351fc
JS
605 while ( node )
606 {
f6bcfd97
BP
607 wxWindow *child = (wxWindow *)node->Data();
608 wxEvtHandler *childHandler = child->GetEventHandler();
609 if ( child->IsKindOf(CLASSINFO(wxControl)) && childHandler != child )
610 {
611 child->PopEventHandler(TRUE);
612 }
613 node = node->Next();
ae8351fc
JS
614 }
615 delete handler;
616 }
617 else
618 {
619 win->PopEventHandler(TRUE);
620 }
f6bcfd97 621
ae8351fc
JS
622 // Save the information
623 InstantiateResourceFromWindow(res, win, TRUE);
f6bcfd97
BP
624
625 // DisassociateResource(win);
626
ae8351fc
JS
627 return TRUE;
628}
629
630// Destroys the window. If this is the 'current' panel, NULLs the
631// variable.
632bool wxResourceManager::DeleteWindow(wxWindow* win)
633{
03f68f12 634 bool clearDisplay = FALSE;
ae8351fc 635 if (m_editorPanel->m_childWindow == win)
03f68f12 636 {
ae8351fc 637 m_editorPanel->m_childWindow = NULL;
03f68f12
JS
638 clearDisplay = TRUE;
639 }
f6bcfd97 640
ae8351fc 641 win->Destroy();
f6bcfd97 642
16d54adb
JJ
643 //if (clearDisplay)
644 // m_editorPanel->Clear();
f6bcfd97 645
ae8351fc 646 return TRUE;
457814b5
JS
647}
648
649wxItemResource *wxResourceManager::FindResourceForWindow(wxWindow *win)
650{
f6bcfd97
BP
651 m_resourceAssociations.BeginFind();
652 wxNode *node;
653 while ((node = m_resourceAssociations.Next()))
457814b5 654 {
f6bcfd97
BP
655 wxWindow *w = (wxWindow *)node->Data();
656 if (w == win)
657 {
658 return (wxItemResource *)node->GetKeyInteger();
659 }
457814b5 660 }
f6bcfd97 661 return NULL;
457814b5
JS
662}
663
664wxWindow *wxResourceManager::FindWindowForResource(wxItemResource *resource)
665{
f6bcfd97 666 return (wxWindow *)m_resourceAssociations.Get((long)resource);
457814b5
JS
667}
668
669
670void wxResourceManager::MakeUniqueName(char *prefix, char *buf)
671{
f6bcfd97
BP
672 while (TRUE)
673 {
674 sprintf(buf, "%s%d", prefix, m_nameCounter);
675 m_nameCounter ++;
676
677 if (!m_resourceTable.FindResource(buf))
678 return;
679 }
457814b5
JS
680}
681
682wxFrame *wxResourceManager::OnCreateEditorFrame(const char *title)
683{
f6bcfd97
BP
684 wxResourceEditorFrame *frame = new wxResourceEditorFrame(this, NULL, title,
685 wxPoint(m_resourceEditorWindowSize.x, m_resourceEditorWindowSize.y),
686 wxSize(m_resourceEditorWindowSize.width, m_resourceEditorWindowSize.height),
687 wxDEFAULT_FRAME_STYLE);
688
689 frame->CreateStatusBar(1);
690
691 frame->SetAutoLayout(TRUE);
2049ba38 692#ifdef __WXMSW__
f6bcfd97 693 frame->SetIcon(wxIcon("DIALOGEDICON"));
457814b5 694#endif
f6bcfd97 695 return frame;
457814b5
JS
696}
697
b127f301 698wxMenuBar *wxResourceManager::OnCreateEditorMenuBar(wxFrame *WXUNUSED(parent))
457814b5 699{
f6bcfd97
BP
700 wxMenuBar *menuBar = new wxMenuBar;
701
702 wxMenu *fileMenu = new wxMenu;
703 fileMenu->Append(RESED_NEW_DIALOG, "New &Dialog", "Create a new dialog");
704 fileMenu->AppendSeparator();
705 fileMenu->Append(wxID_NEW, "&New Project", "Clear the current project");
706 fileMenu->Append(wxID_OPEN, "&Open...", "Load a resource file");
707 fileMenu->Append(wxID_SAVE, "&Save", "Save a resource file");
708 fileMenu->Append(wxID_SAVEAS, "Save &As...", "Save a resource file as...");
709 fileMenu->Append(RESED_CLEAR, "&Clear", "Clear current resources");
710 fileMenu->AppendSeparator();
711 fileMenu->Append(RESED_CONVERT_WXRS, "Convert Old &Resources...", "Convert old resources to new");
712 fileMenu->AppendSeparator();
713 fileMenu->Append(wxID_EXIT, "E&xit", "Exit resource editor");
714
715 wxMenu *editMenu = new wxMenu;
716 editMenu->Append(RESED_TEST, "&Test Dialog", "Test dialog");
717 editMenu->Append(RESED_RECREATE, "&Recreate", "Recreate the selected resource(s)");
718 editMenu->Append(RESED_DELETE, "&Delete", "Delete the selected resource(s)");
719
720 wxMenu *helpMenu = new wxMenu;
721 helpMenu->Append(RESED_CONTENTS, "&Help Topics", "Invokes the on-line help");
722 helpMenu->AppendSeparator();
723 helpMenu->Append(wxID_ABOUT, "&About", "About wxWindows Dialog Editor");
724
725 menuBar->Append(fileMenu, "&File");
726 menuBar->Append(editMenu, "&Edit");
727 menuBar->Append(helpMenu, "&Help");
728
729 return menuBar;
457814b5
JS
730}
731
ae8351fc 732wxResourceEditorScrolledWindow *wxResourceManager::OnCreateEditorPanel(wxFrame *parent)
457814b5 733{
f6bcfd97
BP
734 wxResourceEditorScrolledWindow *panel = new wxResourceEditorScrolledWindow(parent, wxDefaultPosition, wxDefaultSize,
735 // wxSUNKEN_BORDER|wxCLIP_CHILDREN);
15d5ab67 736#ifdef __WXMOTIF__
f6bcfd97 737 wxBORDER);
15d5ab67 738#else
ae8351fc 739 wxSUNKEN_BORDER);
15d5ab67 740#endif
f6bcfd97
BP
741
742 panel->SetScrollbars(10, 10, 100, 100);
743
744 return panel;
745}
457814b5 746
163f0dbe 747wxToolBar *wxResourceManager::OnCreateToolBar(wxFrame *parent)
457814b5 748{
f6bcfd97 749 // Load palette bitmaps
2049ba38 750#ifdef __WXMSW__
f6bcfd97
BP
751 wxBitmap ToolbarLoadBitmap("LOADTOOL");
752 wxBitmap ToolbarSaveBitmap("SAVETOOL");
753 wxBitmap ToolbarNewBitmap("NEWTOOL");
754 wxBitmap ToolbarVertBitmap("VERTTOOL");
755 wxBitmap ToolbarAlignTBitmap("ALIGNTTOOL");
756 wxBitmap ToolbarAlignBBitmap("ALIGNBTOOL");
757 wxBitmap ToolbarHorizBitmap("HORIZTOOL");
758 wxBitmap ToolbarAlignLBitmap("ALIGNLTOOL");
759 wxBitmap ToolbarAlignRBitmap("ALIGNRTOOL");
760 wxBitmap ToolbarCopySizeBitmap("COPYSIZETOOL");
761 wxBitmap ToolbarToBackBitmap("TOBACKTOOL");
762 wxBitmap ToolbarToFrontBitmap("TOFRONTTOOL");
763 wxBitmap ToolbarHelpBitmap("HELPTOOL");
764 wxBitmap ToolbarCopyWidthBitmap("COPYWIDTHTOOL");
765 wxBitmap ToolbarCopyHeightBitmap("COPYHEIGHTTOOL");
766 wxBitmap ToolbarDistributeHorizBitmap("DISTHORIZTOOL");
767 wxBitmap ToolbarDistributeVertBitmap("DISTVERTTOOL");
3f2b72b2 768#else
f6bcfd97
BP
769 wxBitmap ToolbarLoadBitmap( load_xpm );
770 wxBitmap ToolbarSaveBitmap( save_xpm);
771 wxBitmap ToolbarNewBitmap( new_xpm );
772 wxBitmap ToolbarVertBitmap( vert_xpm );
773 wxBitmap ToolbarAlignTBitmap( alignt_xpm );
774 wxBitmap ToolbarAlignBBitmap( alignb_xpm );
775 wxBitmap ToolbarHorizBitmap( horiz_xpm );
776 wxBitmap ToolbarAlignLBitmap( alignl_xpm );
777 wxBitmap ToolbarAlignRBitmap( alignr_xpm );
778 wxBitmap ToolbarCopySizeBitmap( copysize_xpm );
779 wxBitmap ToolbarToBackBitmap( toback_xpm );
780 wxBitmap ToolbarToFrontBitmap( tofront_xpm );
781 wxBitmap ToolbarHelpBitmap( help_xpm );
782 wxBitmap ToolbarCopyWidthBitmap(copywdth_xpm);
783 wxBitmap ToolbarCopyHeightBitmap(copyhght_xpm);
784 wxBitmap ToolbarDistributeHorizBitmap(disthor_xpm);
785 wxBitmap ToolbarDistributeVertBitmap(distvert_xpm);
457814b5 786#endif
f6bcfd97
BP
787
788 // Create the toolbar
789 EditorToolBar *toolbar = new EditorToolBar(parent, wxPoint(0, 0), wxSize(-1, -1), wxNO_BORDER|wxTB_HORIZONTAL|wxTB_FLAT);
790 toolbar->SetMargins(2, 2);
791
2049ba38 792#ifdef __WXMSW__
f6bcfd97
BP
793 int width = 24;
794 int dx = 2;
795 int gap = 6;
457814b5 796#else
f6bcfd97
BP
797 int width = 24; // ToolbarLoadBitmap->GetWidth(); ???
798 int dx = 2;
799 int gap = 6;
457814b5 800#endif
f6bcfd97
BP
801 int currentX = gap;
802 //toolbar->AddSeparator();
803 toolbar->AddTool(TOOLBAR_NEW, ToolbarNewBitmap, wxNullBitmap,
804 FALSE, currentX, -1, NULL, "New dialog");
805 currentX += width + dx;
806 toolbar->AddTool(TOOLBAR_LOAD_FILE, ToolbarLoadBitmap, wxNullBitmap,
807 FALSE, currentX, -1, NULL, "Load");
808 currentX += width + dx;
809 toolbar->AddTool(TOOLBAR_SAVE_FILE, ToolbarSaveBitmap, wxNullBitmap,
810 FALSE, currentX, -1, NULL, "Save");
811 currentX += width + dx + gap;
812 toolbar->AddSeparator();
813 toolbar->AddTool(TOOLBAR_FORMAT_HORIZ, ToolbarVertBitmap, wxNullBitmap,
814 FALSE, currentX, -1, NULL, "Horizontal align");
815 currentX += width + dx;
816 toolbar->AddTool(TOOLBAR_FORMAT_VERT_TOP_ALIGN, ToolbarAlignTBitmap, wxNullBitmap,
817 FALSE, currentX, -1, NULL, "Top align");
818 currentX += width + dx;
819 toolbar->AddTool(TOOLBAR_FORMAT_VERT_BOT_ALIGN, ToolbarAlignBBitmap, wxNullBitmap,
820 FALSE, currentX, -1, NULL, "Bottom align");
821 currentX += width + dx;
822 toolbar->AddTool(TOOLBAR_FORMAT_VERT, ToolbarHorizBitmap, wxNullBitmap,
823 FALSE, currentX, -1, NULL, "Vertical align");
824 currentX += width + dx;
825 toolbar->AddTool(TOOLBAR_FORMAT_HORIZ_LEFT_ALIGN, ToolbarAlignLBitmap, wxNullBitmap,
826 FALSE, currentX, -1, NULL, "Left align");
827 currentX += width + dx;
828 toolbar->AddTool(TOOLBAR_FORMAT_HORIZ_RIGHT_ALIGN, ToolbarAlignRBitmap, wxNullBitmap,
829 FALSE, currentX, -1, NULL, "Right align");
830 currentX += width + dx + gap;
831 toolbar->AddSeparator();
832 toolbar->AddTool(TOOLBAR_COPY_SIZE, ToolbarCopySizeBitmap, wxNullBitmap,
833 FALSE, currentX, -1, NULL, "Copy size");
834 currentX += width + dx;
835 toolbar->AddTool(TOOLBAR_COPY_WIDTH, ToolbarCopyWidthBitmap, wxNullBitmap,
836 FALSE, currentX, -1, NULL, "Copy width");
837 currentX += width + dx;
838 toolbar->AddTool(TOOLBAR_COPY_HEIGHT, ToolbarCopyHeightBitmap, wxNullBitmap,
839 FALSE, currentX, -1, NULL, "Copy height");
840 currentX += width + dx;
841 toolbar->AddTool(TOOLBAR_DISTRIBUTE_HORIZ, ToolbarDistributeHorizBitmap, wxNullBitmap,
842 FALSE, currentX, -1, NULL, "Distribute horizontally");
843 currentX += width + dx;
844 toolbar->AddTool(TOOLBAR_DISTRIBUTE_VERT, ToolbarDistributeVertBitmap, wxNullBitmap,
845 FALSE, currentX, -1, NULL, "Distribute vertically");
846 currentX += width + dx + gap;
847 toolbar->AddSeparator();
848 toolbar->AddTool(TOOLBAR_TO_FRONT, ToolbarToFrontBitmap, wxNullBitmap,
849 FALSE, currentX, -1, NULL, "To front");
850 currentX += width + dx;
851 toolbar->AddTool(TOOLBAR_TO_BACK, ToolbarToBackBitmap, wxNullBitmap,
852 FALSE, currentX, -1, NULL, "To back");
853 currentX += width + dx + gap;
854
855 toolbar->AddSeparator();
856 toolbar->AddTool(TOOLBAR_HELP, ToolbarHelpBitmap, wxNullBitmap,
857 FALSE, currentX, -1, NULL, "Help");
858 currentX += width + dx;
859
860 toolbar->Realize();
861
862 return toolbar;
457814b5
JS
863}
864
ae8351fc 865void wxResourceManager::UpdateResourceList()
457814b5 866{
f6bcfd97
BP
867 if (!m_editorResourceTree)
868 return;
869
870 m_editorResourceTree->SetInvalid(TRUE);
871 m_editorResourceTree->DeleteAllItems();
872
873 long id = m_editorResourceTree->AddRoot("Dialogs", 1, 2);
874
875 m_resourceTable.BeginFind();
876 wxNode *node;
877 while ((node = m_resourceTable.Next()))
457814b5 878 {
f6bcfd97
BP
879 wxItemResource *res = (wxItemResource *)node->Data();
880 wxString resType(res->GetType());
881 if (resType == "wxDialog" || resType == "wxDialogBox" || resType == "wxPanel" || resType == "wxBitmap")
882 {
883 AddItemsRecursively(id, res);
884 }
457814b5 885 }
f6bcfd97
BP
886 m_editorResourceTree->Expand(id);
887 m_editorResourceTree->SetInvalid(FALSE);
457814b5
JS
888}
889
ae8351fc 890void wxResourceManager::AddItemsRecursively(long parent, wxItemResource *resource)
457814b5 891{
f6bcfd97
BP
892 wxString theString("");
893 theString = resource->GetName();
894
895 int imageId = 0;
896 wxString resType(resource->GetType());
897 if (resType == "wxDialog" || resType == "wxDialogBox" || resType == "wxPanel")
898 imageId = 0;
899 else
900 imageId = 3;
901
902 long id = m_editorResourceTree->AppendItem(parent, theString, imageId );
903
904 m_editorResourceTree->SetItemData(id, new wxResourceTreeData(resource));
905
906 if (strcmp(resource->GetType(), "wxBitmap") != 0)
457814b5 907 {
f6bcfd97
BP
908 wxNode *node = resource->GetChildren().First();
909 while (node)
910 {
911 wxItemResource *res = (wxItemResource *)node->Data();
912 AddItemsRecursively(id, res);
913 node = node->Next();
914 }
457814b5 915 }
f6bcfd97 916 // m_editorResourceTree->ExpandItem(id, wxTREE_EXPAND_EXPAND);
457814b5
JS
917}
918
ae8351fc 919bool wxResourceManager::EditSelectedResource()
457814b5 920{
f6bcfd97
BP
921 int sel = m_editorResourceTree->GetSelection();
922 if (sel != 0)
923 {
924 wxResourceTreeData *data = (wxResourceTreeData *)m_editorResourceTree->GetItemData(sel);
925 wxItemResource *res = data->GetResource();
926 return Edit(res);
927 }
928 return FALSE;
457814b5
JS
929}
930
931bool wxResourceManager::Edit(wxItemResource *res)
932{
f6bcfd97
BP
933 wxPropertyInfo::CloseWindow();
934
935 ClearCurrentDialog();
936
937 wxString resType(res->GetType());
938 wxPanel *panel = (wxPanel *)FindWindowForResource(res);
939
940 if (panel)
941 {
942 wxMessageBox("Should not find panel in wxResourceManager::Edit");
943 return FALSE;
944 }
945 else
946 {
947 // long style = res->GetStyle();
948 // res->SetStyle(style|wxRAISED_BORDER);
457814b5
JS
949 panel = new wxPanel;
950 wxResourceEditorDialogHandler *handler = new wxResourceEditorDialogHandler(panel, res, panel->GetEventHandler(),
f6bcfd97
BP
951 this);
952
2fc9385a 953 wxLoadFromResource(panel, m_editorPanel, res->GetName(), &m_resourceTable);
f6bcfd97 954
ae8351fc 955 panel->PushEventHandler(handler);
f6bcfd97
BP
956
957 // res->SetStyle(style);
958 handler->AddChildHandlers(); // Add event handlers for all controls
ae8351fc 959 AssociateResource(res, panel);
f6bcfd97 960
ae8351fc
JS
961 m_editorPanel->m_childWindow = panel;
962 panel->Move(m_editorPanel->GetMarginX(), m_editorPanel->GetMarginY());
963 panel->Show(TRUE);
964 panel->Refresh();
f6bcfd97 965
ae8351fc
JS
966 wxClientDC dc(m_editorPanel);
967 m_editorPanel->DrawTitle(dc);
f6bcfd97
BP
968 }
969 return FALSE;
457814b5
JS
970}
971
ae8351fc 972bool wxResourceManager::CreateNewPanel()
457814b5 973{
f6bcfd97
BP
974 wxPropertyInfo::CloseWindow();
975
976 ClearCurrentDialog();
977
978 char buf[256];
979 MakeUniqueName("dialog", buf);
980
981 wxItemResource *resource = new wxItemResource;
982 resource->SetType("wxDialog");
983 resource->SetName(buf);
984 resource->SetTitle(buf);
985 resource->SetResourceStyle(wxRESOURCE_USE_DEFAULTS);
986 resource->SetResourceStyle(wxRESOURCE_DIALOG_UNITS);
987
988 wxString newIdName;
989 int id = GenerateWindowId("ID_DIALOG", newIdName);
990 resource->SetId(id);
991
992 // This is now guaranteed to be unique, so just add to symbol table
993 m_symbolTable.AddSymbol(newIdName, id);
994
995 m_resourceTable.AddResource(resource);
996
997 wxSize size(400, 300);
998
999 wxPanel *panel = new wxPanel(m_editorPanel, -1,
1000 wxPoint(m_editorPanel->GetMarginX(), m_editorPanel->GetMarginY()),
1001 size, wxRAISED_BORDER|wxDEFAULT_DIALOG_STYLE, buf);
1002 m_editorPanel->m_childWindow = panel;
1003
1004 resource->SetStyle(panel->GetWindowStyleFlag());
1005
1006 // Store dialog units in resource
1007 size = panel->ConvertPixelsToDialog(size);
1008
1009 resource->SetSize(10, 10, size.x, size.y);
1010
1011 // For editing in situ we will need to use the hash table to ensure
1012 // we don't dereference invalid pointers.
1013 // resourceWindowTable.Put((long)resource, panel);
1014
1015 wxResourceEditorDialogHandler *handler = new wxResourceEditorDialogHandler(panel, resource, panel->GetEventHandler(),
1016 this);
1017 panel->PushEventHandler(handler);
1018
1019 AssociateResource(resource, panel);
1020 UpdateResourceList();
1021
1022 Modify(TRUE);
1023 m_editorPanel->m_childWindow->Refresh();
1024
1025 // panel->Refresh();
1026
1027 wxClientDC dc(m_editorPanel);
1028 m_editorPanel->DrawTitle(dc);
1029
1030 return TRUE;
457814b5
JS
1031}
1032
1033bool wxResourceManager::CreatePanelItem(wxItemResource *panelResource, wxPanel *panel, char *iType, int x, int y, bool isBitmap)
1034{
f6bcfd97
BP
1035 char buf[256];
1036 if (!panel->IsKindOf(CLASSINFO(wxPanel)) && !panel->IsKindOf(CLASSINFO(wxDialog)))
1037 return FALSE;
1038
1039 Modify(TRUE);
1040
1041 wxItemResource *res = new wxItemResource;
1042 wxControl *newItem = NULL;
1043
1044 if ((panelResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS) != 0)
1045 {
1046 wxPoint pt = panel->ConvertPixelsToDialog(wxPoint(x, y));
1047 res->SetSize(pt.x, pt.y, -1, -1);
1048 }
1049 else res->SetSize(x, y, -1, -1);
1050
1051 res->SetType(iType);
1052
1053 wxString prefix;
1054
1055 wxString itemType(iType);
1056
1057 if (itemType == "wxButton")
1058 {
1059 prefix = "ID_BUTTON";
1060 MakeUniqueName("button", buf);
1061 res->SetName(buf);
1062 if (isBitmap)
1063 newItem = new wxBitmapButton(panel, -1, * m_bitmapImage, wxPoint(x, y), wxSize(-1, -1), wxBU_AUTODRAW, wxDefaultValidator, buf);
1064 else
1065 newItem = new wxButton(panel, -1, "Button", wxPoint(x, y), wxSize(-1, -1), 0, wxDefaultValidator, buf);
1066 }
1067 if (itemType == "wxBitmapButton")
457814b5 1068 {
f6bcfd97
BP
1069 prefix = "ID_BITMAPBUTTON";
1070 MakeUniqueName("button", buf);
1071 res->SetName(buf);
d0b223a1 1072 newItem = new wxBitmapButton(panel, -1, * m_bitmapImage, wxPoint(x, y), wxSize(-1, -1), wxBU_AUTODRAW, wxDefaultValidator, buf);
457814b5 1073 }
f6bcfd97 1074 else if (itemType == "wxMessage" || itemType == "wxStaticText")
457814b5 1075 {
f6bcfd97
BP
1076 prefix = "ID_STATIC";
1077 MakeUniqueName("statictext", buf);
1078 res->SetName(buf);
1079 if (isBitmap)
1080 newItem = new wxStaticBitmap(panel, -1, * m_bitmapImage, wxPoint(x, y), wxSize(0, 0), 0, buf);
1081 else
1082 newItem = new wxStaticText(panel, -1, "Static", wxPoint(x, y), wxSize(-1, -1), 0, buf);
457814b5 1083 }
f6bcfd97 1084 else if (itemType == "wxStaticBitmap")
457814b5 1085 {
f6bcfd97
BP
1086 prefix = "ID_STATICBITMAP";
1087 MakeUniqueName("static", buf);
1088 res->SetName(buf);
1089 newItem = new wxStaticBitmap(panel, -1, * m_bitmapImage, wxPoint(x, y), wxSize(-1, -1), 0, buf);
457814b5 1090 }
f6bcfd97 1091 else if (itemType == "wxCheckBox")
457814b5 1092 {
f6bcfd97
BP
1093 prefix = "ID_CHECKBOX";
1094 MakeUniqueName("checkbox", buf);
1095 res->SetName(buf);
1096 newItem = new wxCheckBox(panel, -1, "Checkbox", wxPoint(x, y), wxSize(-1, -1), 0, wxDefaultValidator, buf);
457814b5 1097 }
f6bcfd97 1098 else if (itemType == "wxListBox")
457814b5 1099 {
f6bcfd97
BP
1100 prefix = "ID_LISTBOX";
1101 MakeUniqueName("listbox", buf);
1102 res->SetName(buf);
1103 newItem = new wxListBox(panel, -1, wxPoint(x, y), wxSize(-1, -1), 0, NULL, 0, wxDefaultValidator, buf);
457814b5 1104 }
f6bcfd97 1105 else if (itemType == "wxRadioBox")
457814b5 1106 {
f6bcfd97
BP
1107 prefix = "ID_RADIOBOX";
1108 MakeUniqueName("radiobox", buf);
1109 res->SetName(buf);
1110 wxString names[] = { "One", "Two" };
1111 newItem = new wxRadioBox(panel, -1, "Radiobox", wxPoint(x, y), wxSize(-1, -1), 2, names, 2,
1112 wxHORIZONTAL, wxDefaultValidator, buf);
1113 res->SetStringValues(wxStringList("One", "Two", NULL));
457814b5 1114 }
f6bcfd97 1115 else if (itemType == "wxRadioButton")
457814b5 1116 {
f6bcfd97
BP
1117 prefix = "ID_RADIOBUTTON";
1118 MakeUniqueName("radiobutton", buf);
1119 res->SetName(buf);
1120 wxString names[] = { "One", "Two" };
1121 newItem = new wxRadioButton(panel, -1, "Radiobutton", wxPoint(x, y), wxSize(-1, -1),
1122 0, wxDefaultValidator, buf);
457814b5 1123 }
f6bcfd97 1124 else if (itemType == "wxChoice")
03f68f12 1125 {
f6bcfd97
BP
1126 prefix = "ID_CHOICE";
1127 MakeUniqueName("choice", buf);
1128 res->SetName(buf);
1129 newItem = new wxChoice(panel, -1, wxPoint(x, y), wxSize(-1, -1), 0, NULL, 0, wxDefaultValidator, buf);
03f68f12 1130 }
f6bcfd97 1131 else if (itemType == "wxComboBox")
457814b5 1132 {
f6bcfd97
BP
1133 prefix = "ID_COMBOBOX";
1134 MakeUniqueName("combobox", buf);
1135 res->SetName(buf);
1136 newItem = new wxComboBox(panel, -1, "", wxPoint(x, y), wxSize(-1, -1), 0, NULL, wxCB_DROPDOWN, wxDefaultValidator, buf);
457814b5 1137 }
f6bcfd97 1138 else if (itemType == "wxGroupBox" || itemType == "wxStaticBox")
9c331ded 1139 {
f6bcfd97
BP
1140 prefix = "ID_STATICBOX";
1141 MakeUniqueName("staticbox", buf);
1142 res->SetName(buf);
1143 newItem = new wxStaticBox(panel, -1, "Static", wxPoint(x, y), wxSize(200, 200), 0, buf);
9c331ded 1144 }
f6bcfd97 1145 else if (itemType == "wxGauge")
457814b5 1146 {
f6bcfd97
BP
1147 prefix = "ID_GAUGE";
1148 MakeUniqueName("gauge", buf);
1149 res->SetName(buf);
1150 newItem = new wxGauge(panel, -1, 10, wxPoint(x, y), wxSize(80, 30), wxHORIZONTAL, wxDefaultValidator, buf);
457814b5 1151 }
f6bcfd97 1152 else if (itemType == "wxSlider")
457814b5 1153 {
f6bcfd97
BP
1154 prefix = "ID_SLIDER";
1155 MakeUniqueName("slider", buf);
1156 res->SetName(buf);
1157 newItem = new wxSlider(panel, -1, 1, 1, 10, wxPoint(x, y), wxSize(120, -1), wxHORIZONTAL, wxDefaultValidator, buf);
457814b5 1158 }
f6bcfd97 1159 else if (itemType == "wxText" || itemType == "wxTextCtrl (single-line)")
457814b5 1160 {
f6bcfd97
BP
1161 prefix = "ID_TEXTCTRL";
1162 MakeUniqueName("textctrl", buf);
1163 res->SetName(buf);
1164 res->SetType("wxTextCtrl");
1165 newItem = new wxTextCtrl(panel, -1, "", wxPoint(x, y), wxSize(120, -1), 0, wxDefaultValidator, buf);
457814b5 1166 }
f6bcfd97 1167 else if (itemType == "wxMultiText" || itemType == "wxTextCtrl (multi-line)")
457814b5 1168 {
f6bcfd97
BP
1169 prefix = "ID_TEXTCTRL";
1170 MakeUniqueName("textctrl", buf);
1171 res->SetName(buf);
1172 res->SetType("wxTextCtrl");
1173 newItem = new wxTextCtrl(panel, -1, "", wxPoint(x, y), wxSize(120, 100), wxTE_MULTILINE, wxDefaultValidator, buf);
457814b5 1174 }
f6bcfd97 1175 else if (itemType == "wxScrollBar")
457814b5 1176 {
f6bcfd97
BP
1177 prefix = "ID_SCROLLBAR";
1178 MakeUniqueName("scrollbar", buf);
1179 res->SetName(buf);
1180 newItem = new wxScrollBar(panel, -1, wxPoint(x, y), wxSize(140, -1), wxHORIZONTAL, wxDefaultValidator, buf);
457814b5 1181 }
f6bcfd97
BP
1182 if (!newItem)
1183 return FALSE;
1184
1185 int actualW, actualH;
1186 newItem->GetSize(&actualW, &actualH);
1187 wxSize actualSize(actualW, actualH);
1188
1189 if ((panelResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS) != 0)
457814b5 1190 {
f6bcfd97 1191 actualSize = panel->ConvertPixelsToDialog(actualSize);
457814b5 1192 }
f6bcfd97
BP
1193 res->SetSize(res->GetX(), res->GetY(), actualSize.x, actualSize.y);
1194
1195 wxString newIdName;
1196 int id = GenerateWindowId(prefix, newIdName);
1197 res->SetId(id);
1198
1199 // This is now guaranteed to be unique, so just add to symbol table
1200 m_symbolTable.AddSymbol(newIdName, id);
1201
1202 newItem->PushEventHandler(new wxResourceEditorControlHandler(newItem, newItem));
1203
1204 res->SetStyle(newItem->GetWindowStyleFlag());
1205 AssociateResource(res, newItem);
1206 panelResource->GetChildren().Append(res);
1207
1208 UpdateResourceList();
1209
1210 return TRUE;
457814b5
JS
1211}
1212
ae8351fc
JS
1213void wxResourceManager::ClearCurrentDialog()
1214{
f6bcfd97
BP
1215 if (m_editorPanel->m_childWindow)
1216 {
1217 SaveInfoAndDeleteHandler(m_editorPanel->m_childWindow);
1218 DisassociateResource(m_editorPanel->m_childWindow);
1219 DeleteWindow(m_editorPanel->m_childWindow);
1220 m_editorPanel->m_childWindow = NULL;
16d54adb 1221 //m_editorPanel->Clear();
f6bcfd97 1222 }
ae8351fc
JS
1223}
1224
03f68f12
JS
1225bool wxResourceManager::TestCurrentDialog(wxWindow* parent)
1226{
f6bcfd97 1227 if (m_editorPanel->m_childWindow)
03f68f12 1228 {
f6bcfd97
BP
1229 wxItemResource* item = FindResourceForWindow(m_editorPanel->m_childWindow);
1230 if (!item)
1231 return FALSE;
1232
1233 // Make sure the resources are up-to-date w.r.t. the window
1234 InstantiateResourceFromWindow(item, m_editorPanel->m_childWindow, TRUE);
1235
1236 ResourceEditorDialogTester* dialog = new ResourceEditorDialogTester;
1237 bool success = FALSE;
2fc9385a 1238 if (wxLoadFromResource(dialog, parent, item->GetName(), & m_resourceTable))
f6bcfd97
BP
1239 {
1240 dialog->Centre();
1241 dialog->ShowModal();
1242 success = TRUE;
1243 }
1244 return success;
03f68f12 1245 }
f6bcfd97 1246 return FALSE;
03f68f12
JS
1247}
1248
457814b5
JS
1249// Find the first dialog or panel for which
1250// there is a selected panel item.
ae8351fc 1251wxWindow *wxResourceManager::FindParentOfSelection()
457814b5 1252{
f6bcfd97
BP
1253 m_resourceTable.BeginFind();
1254 wxNode *node;
1255 while ((node = m_resourceTable.Next()))
457814b5 1256 {
f6bcfd97
BP
1257 wxItemResource *res = (wxItemResource *)node->Data();
1258 wxWindow *win = FindWindowForResource(res);
1259 if (win)
1260 {
1261 wxNode *node1 = win->GetChildren().First();
1262 while (node1)
1263 {
1264 wxControl *item = (wxControl *)node1->Data();
1265 wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
1266 if (item->IsKindOf(CLASSINFO(wxControl)) && childHandler->IsSelected())
1267 return win;
1268 node1 = node1->Next();
1269 }
1270 }
457814b5 1271 }
f6bcfd97 1272 return NULL;
457814b5
JS
1273}
1274
1275// Format the panel items according to 'flag'
1276void wxResourceManager::AlignItems(int flag)
1277{
f6bcfd97
BP
1278 wxWindow *win = FindParentOfSelection();
1279 if (!win)
1280 return;
457814b5 1281
f6bcfd97
BP
1282 wxNode *node = GetSelections().First();
1283 if (!node)
1284 return;
457814b5 1285
f6bcfd97
BP
1286 wxControl *firstSelection = (wxControl *)node->Data();
1287 if (firstSelection->GetParent() != win)
1288 return;
1289
1290 int firstX, firstY;
1291 int firstW, firstH;
1292 firstSelection->GetPosition(&firstX, &firstY);
1293 firstSelection->GetSize(&firstW, &firstH);
1294 int centreX = (int)(firstX + (firstW / 2));
1295 int centreY = (int)(firstY + (firstH / 2));
1296
1297 while ((node = node->Next()))
457814b5 1298 {
f6bcfd97
BP
1299 wxControl *item = (wxControl *)node->Data();
1300 if (item->GetParent() == win)
457814b5 1301 {
f6bcfd97
BP
1302 int x, y, w, h;
1303 item->GetPosition(&x, &y);
1304 item->GetSize(&w, &h);
1305
1306 int newX, newY;
1307
1308 switch (flag)
1309 {
1310 case TOOLBAR_FORMAT_HORIZ:
1311 {
1312 newX = x;
1313 newY = (int)(centreY - (h/2.0));
1314 break;
1315 }
1316 case TOOLBAR_FORMAT_VERT:
1317 {
1318 newX = (int)(centreX - (w/2.0));
1319 newY = y;
1320 break;
1321 }
1322 case TOOLBAR_FORMAT_HORIZ_LEFT_ALIGN:
1323 {
1324 newX = firstX;
1325 newY = y;
1326 break;
1327 }
1328 case TOOLBAR_FORMAT_VERT_TOP_ALIGN:
1329 {
1330 newX = x;
1331 newY = firstY;
1332 break;
1333 }
1334 case TOOLBAR_FORMAT_HORIZ_RIGHT_ALIGN:
1335 {
1336 newX = firstX + firstW - w;
1337 newY = y;
1338 break;
1339 }
1340 case TOOLBAR_FORMAT_VERT_BOT_ALIGN:
1341 {
1342 newX = x;
1343 newY = firstY + firstH - h;
1344 break;
1345 }
1346 default:
1347 newX = x; newY = y;
1348 break;
1349 }
1350
1351 wxItemResource* resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(item);
1352 wxItemResource* parentResource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(item->GetParent());
1353
1354 item->SetSize(newX, newY, w, h);
1355
1356 // Also update the associated resource
1357 // We need to convert to dialog units if this is not a dialog or panel, but
1358 // the parent resource specifies dialog units.
1359 if (parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
1360 {
1361 wxPoint pt = item->GetParent()->ConvertPixelsToDialog(wxPoint(newX, newY));
1362 newX = pt.x; newY = pt.y;
1363 wxSize sz = item->GetParent()->ConvertPixelsToDialog(wxSize(w, h));
1364 w = sz.x; h = sz.y;
1365 }
1366 resource->SetSize(newX, newY, w, h);
457814b5 1367 }
f6bcfd97
BP
1368 }
1369 win->Refresh();
1370}
1371
1372// Copy the first image's size to subsequent images
1373void wxResourceManager::CopySize(int command)
1374{
1375 bool copyWidth = (command == TOOLBAR_COPY_SIZE || command == TOOLBAR_COPY_WIDTH) ;
1376 bool copyHeight = (command == TOOLBAR_COPY_SIZE || command == TOOLBAR_COPY_HEIGHT) ;
1377
1378 wxWindow *win = FindParentOfSelection();
1379 if (!win)
1380 return;
1381
1382 wxNode *node = GetSelections().First();
1383 if (!node)
1384 return;
1385
1386 wxControl *firstSelection = (wxControl *)node->Data();
1387 if (firstSelection->GetParent() != win)
1388 return;
1389
1390 int firstX, firstY;
1391 int firstW, firstH;
1392 firstSelection->GetPosition(&firstX, &firstY);
1393 firstSelection->GetSize(&firstW, &firstH);
1394
1395 while ((node = node->Next()))
1396 {
1397 wxControl *item = (wxControl *)node->Data();
1398 if (item->GetParent() == win)
457814b5 1399 {
f6bcfd97
BP
1400 wxSize sz = item->GetSize();
1401 int widthToSet = (copyWidth ? firstW : sz.x);
1402 int heightToSet = (copyHeight ? firstH : sz.y);
1403
1404 item->SetSize(-1, -1, widthToSet, heightToSet);
1405
1406 wxItemResource* resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(item);
1407 wxItemResource* parentResource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(item->GetParent());
1408
1409 widthToSet = resource->GetWidth();
1410 heightToSet = resource->GetHeight();
1411
1412 // Also update the associated resource
1413 // We need to convert to dialog units if this is not a dialog or panel, but
1414 // the parent resource specifies dialog units.
1415 if (parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
1416 {
1417 wxSize convertedSize = item->GetParent()->ConvertPixelsToDialog(wxSize(firstW, firstH));
1418 if (copyWidth)
1419 widthToSet = convertedSize.x;
1420 if (copyHeight)
1421 heightToSet = convertedSize.y;
1422 }
1423 resource->SetSize(resource->GetX(), resource->GetY(), widthToSet, heightToSet);
457814b5 1424 }
f6bcfd97
BP
1425 }
1426 win->Refresh();
1427}
1428
1429void wxResourceManager::ToBackOrFront(bool toBack)
1430{
1431 wxWindow *win = FindParentOfSelection();
1432 if (!win)
1433 return;
1434 wxItemResource *winResource = FindResourceForWindow(win);
1435
1436 wxNode *node = GetSelections().First();
1437 while (node)
1438 {
1439 wxControl *item = (wxControl *)node->Data();
1440 wxItemResource *itemResource = FindResourceForWindow(item);
1441 if (item->GetParent() == win)
457814b5 1442 {
f6bcfd97
BP
1443 win->GetChildren().DeleteObject(item);
1444 if (winResource)
1445 winResource->GetChildren().DeleteObject(itemResource);
1446 if (toBack)
1447 {
1448 win->GetChildren().Insert(item);
1449 if (winResource)
1450 winResource->GetChildren().Insert(itemResource);
1451 }
1452 else
1453 {
1454 win->GetChildren().Append(item);
1455 if (winResource)
1456 winResource->GetChildren().Append(itemResource);
1457 }
457814b5 1458 }
f6bcfd97 1459 node = node->Next();
457814b5 1460 }
f6bcfd97 1461 // win->Refresh();
457814b5
JS
1462}
1463
f6bcfd97
BP
1464// Distribute controls evenly between first and last
1465void wxResourceManager::DistributePositions(int command)
457814b5 1466{
f6bcfd97 1467 bool horizontal = (command == TOOLBAR_DISTRIBUTE_HORIZ) ;
457814b5 1468
f6bcfd97
BP
1469 wxWindow *win = FindParentOfSelection();
1470 if (!win)
1471 return;
457814b5 1472
f6bcfd97
BP
1473 if (GetSelections().Number() < 3)
1474 {
1475 wxMessageBox(wxT("Sorry, distributing less than three controls does not make sense."));
1476 return;
1477 }
457814b5 1478
f6bcfd97
BP
1479 wxControl *firstSelection = (wxControl*) GetSelections().First()->Data();
1480 wxControl *lastSelection = (wxControl*) GetSelections().Last()->Data();
457814b5 1481
f6bcfd97
BP
1482 // For now, assume the ordering is correct (the user selected the controls in order).
1483 // TODO: explicitly order the selections in terms of increading x or y position.
3013b6f4 1484
f6bcfd97
BP
1485 // Find the total amount of space between all controls
1486 int totalControlSpace = 0; // How much space the controls take up
8caa4ed1 1487
f6bcfd97
BP
1488 wxNode* node = GetSelections().First();
1489 while (node)
1490 {
1491 wxControl* control = (wxControl*) node->Data();
3013b6f4 1492
f6bcfd97
BP
1493 int x, y;
1494 int w, h;
1495 control->GetPosition(&x, &y);
1496 control->GetSize(&w, &h);
3013b6f4 1497
f6bcfd97
BP
1498 // Don't include the space taken up by the first and last controls.
1499 if (control != firstSelection && control != lastSelection)
1500 {
1501 if (horizontal)
1502 totalControlSpace += w;
1503 else
1504 totalControlSpace += h;
1505 }
457814b5 1506
f6bcfd97
BP
1507 node = node->Next();
1508 }
1509
1510
1511 int firstX, firstY, lastX, lastY;
1512 int firstW, firstH, lastW, lastH;
1513 firstSelection->GetPosition(&firstX, &firstY);
1514 firstSelection->GetSize(&firstW, &firstH);
1515
1516 lastSelection->GetPosition(&lastX, &lastY);
1517 lastSelection->GetSize(&lastW, &lastH);
1518
1519 /*
1520
1521 firstX lastX
1522 |===| |====| |======| |==|
1523
1524 */
1525
1526 int spacing, currentPos;
1527 if (horizontal)
1528 {
1529 spacing = ((lastX - (firstX + firstW)) - totalControlSpace) / (GetSelections().Number() - 1);
1530 currentPos = firstX + firstW + spacing;
1531 }
1532 else
1533 {
1534 spacing = ((lastY - (firstY + firstH)) - totalControlSpace) / (GetSelections().Number() - 1);
1535 currentPos = firstY + firstH + spacing;
1536 }
1537
1538 node = GetSelections().First();
1539
1540 while ((node = node->Next()))
1541 {
1542 wxControl *item = (wxControl *)node->Data();
1543 wxSize sz = item->GetSize();
1544 wxPoint pos = item->GetPosition();
1545 wxItemResource* resource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(item);
1546 wxItemResource* parentResource = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(item->GetParent());
1547
1548 int controlX = (horizontal ? currentPos : pos.x);
1549 int controlY = (horizontal ? pos.y : currentPos);
1550
1551 item->Move(controlX, controlY);
1552
1553 int resX = controlX;
1554 int resY = controlY;
1555
1556 // Also update the associated resource
1557 // We need to convert to dialog units if this is not a dialog or panel, but
1558 // the parent resource specifies dialog units.
1559 if (parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS)
1560 {
1561 wxPoint convertedPos = item->GetParent()->ConvertPixelsToDialog(wxPoint(resX, resY));
1562 resX = convertedPos.x;
1563 resY = convertedPos.y;
1564 }
1565 resource->SetSize(resX, resY, resource->GetWidth(), resource->GetHeight());
1566
1567 currentPos += (horizontal ? (sz.x + spacing) : (sz.y + spacing));
1568 }
1569 win->Refresh();
457814b5
JS
1570}
1571
1572void wxResourceManager::AddSelection(wxWindow *win)
1573{
f6bcfd97
BP
1574 if (!m_selections.Member(win))
1575 m_selections.Append(win);
457814b5
JS
1576}
1577
1578void wxResourceManager::RemoveSelection(wxWindow *win)
1579{
f6bcfd97 1580 m_selections.DeleteObject(win);
457814b5
JS
1581}
1582
30b5fc11
JS
1583void wxResourceManager::DeselectItemIfNecessary(wxWindow *win)
1584{
1585 if (win->IsKindOf(CLASSINFO(wxControl)) && (win->GetEventHandler() != win))
1586 {
1587 // Deselect and refresh window in case we leave selection
1588 // handles behind
1589 wxControl *item = (wxControl *)win;
1590 wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
1591 if (childHandler->IsSelected())
1592 {
1593 wxResourceManager::GetCurrentResourceManager()->RemoveSelection(item);
1594 childHandler->SelectItem(FALSE);
1595#ifndef __WXGTK__
1596 item->GetParent()->Refresh();
1597#endif
1598 }
1599 }
1600}
1601
457814b5
JS
1602// Need to search through resource table removing this from
1603// any resource which has this as a parent.
1604bool wxResourceManager::RemoveResourceFromParent(wxItemResource *res)
1605{
f6bcfd97
BP
1606 m_resourceTable.BeginFind();
1607 wxNode *node;
1608 while ((node = m_resourceTable.Next()))
457814b5 1609 {
f6bcfd97
BP
1610 wxItemResource *thisRes = (wxItemResource *)node->Data();
1611 if (thisRes->GetChildren().Member(res))
1612 {
1613 thisRes->GetChildren().DeleteObject(res);
1614 return TRUE;
1615 }
457814b5 1616 }
f6bcfd97 1617 return FALSE;
457814b5
JS
1618}
1619
1620bool wxResourceManager::DeleteResource(wxItemResource *res)
1621{
f6bcfd97
BP
1622 if (!res)
1623 return FALSE;
1624
1625 RemoveResourceFromParent(res);
1626
1627 wxNode *node = res->GetChildren().First();
1628 while (node)
1629 {
1630 wxNode *next = node->Next();
1631 wxItemResource *child = (wxItemResource *)node->Data();
1632 DeleteResource(child);
1633 node = next;
1634 }
1635
1636 // If this is a button or message resource, delete the
1637 // associate bitmap resource if not being used.
1638 wxString resType(res->GetType());
1639
1640 /* shouldn't have to do this now bitmaps are ref-counted
1641 if ((resType == "wxMessage" || resType == "wxStaticBitmap" || resType == "wxButton" || resType == "wxBitmapButton") && res->GetValue4())
1642 {
457814b5 1643 PossiblyDeleteBitmapResource(res->GetValue4());
f6bcfd97
BP
1644 }
1645 */
1646
1647 // Remove symbol from table if appropriate
1648 if (!IsSymbolUsed(res, res->GetId()))
1649 {
1650 m_symbolTable.RemoveSymbol(res->GetId());
1651 }
1652
1653 m_resourceTable.Delete(res->GetName());
1654 delete res;
1655 Modify(TRUE);
1656 return TRUE;
457814b5
JS
1657}
1658
ae8351fc 1659bool wxResourceManager::DeleteResource(wxWindow *win)
457814b5 1660{
f6bcfd97
BP
1661 DeselectItemIfNecessary(win);
1662
1663 wxItemResource *res = FindResourceForWindow(win);
1664
1665 DisassociateResource(res);
1666 DeleteResource(res);
1667 UpdateResourceList();
1668
1669 return TRUE;
457814b5
JS
1670}
1671
1672// Will eventually have bitmap type information, for different
1673// kinds of bitmap.
fd71308f 1674wxString wxResourceManager::AddBitmapResource(const wxString& filename)
457814b5 1675{
f6bcfd97
BP
1676 wxItemResource *resource = FindBitmapResourceByFilename(filename);
1677 if (!resource)
1678 {
1679 char buf[256];
1680 MakeUniqueName("bitmap", buf);
1681 resource = new wxItemResource;
1682 resource->SetType("wxBitmap");
1683 resource->SetName(buf);
1684
1685 // A bitmap resource has one or more children, specifying
1686 // alternative bitmaps.
1687 wxItemResource *child = new wxItemResource;
1688 child->SetType("wxBitmap");
1689 child->SetName(filename);
1690 child->SetValue1(wxBITMAP_TYPE_BMP);
1691 child->SetValue2(RESOURCE_PLATFORM_ANY);
1692 child->SetValue3(0); // Depth
1693 child->SetSize(0,0,0,0);
1694 resource->GetChildren().Append(child);
1695
1696 m_resourceTable.AddResource(resource);
1697
1698 UpdateResourceList();
1699 }
1700 if (resource)
1701 return resource->GetName();
1702 else
1703 return wxEmptyString;
457814b5
JS
1704}
1705
f6bcfd97 1706// Delete the bitmap resource if it isn't being used by another resource.
fd71308f 1707void wxResourceManager::PossiblyDeleteBitmapResource(const wxString& resourceName)
457814b5 1708{
f6bcfd97
BP
1709 if (!IsBitmapResourceUsed(resourceName))
1710 {
1711 wxItemResource *res = m_resourceTable.FindResource(resourceName);
1712 DeleteResource(res);
1713 UpdateResourceList();
1714 }
457814b5
JS
1715}
1716
fd71308f 1717bool wxResourceManager::IsBitmapResourceUsed(const wxString& resourceName)
457814b5 1718{
f6bcfd97
BP
1719 m_resourceTable.BeginFind();
1720 wxNode *node;
1721 while ((node = m_resourceTable.Next()))
457814b5 1722 {
f6bcfd97
BP
1723 wxItemResource *res = (wxItemResource *)node->Data();
1724 wxString resType(res->GetType());
1725 if (resType == "wxDialog")
1726 {
1727 wxNode *node1 = res->GetChildren().First();
1728 while (node1)
1729 {
1730 wxItemResource *child = (wxItemResource *)node1->Data();
1731 wxString childResType(child->GetType());
1732
1733 if ((childResType == "wxMessage" || childResType == "wxButton") &&
1734 child->GetValue4() &&
1735 (strcmp(child->GetValue4(), resourceName) == 0))
1736 return TRUE;
1737 node1 = node1->Next();
1738 }
1739 }
457814b5 1740 }
f6bcfd97 1741 return FALSE;
457814b5
JS
1742}
1743
1744// Given a wxButton or wxMessage, find the corresponding bitmap filename.
fd71308f 1745wxString wxResourceManager::FindBitmapFilenameForResource(wxItemResource *resource)
457814b5 1746{
f6bcfd97
BP
1747 if (!resource || (resource->GetValue4() == ""))
1748 return wxEmptyString;
1749 wxItemResource *bitmapResource = m_resourceTable.FindResource(resource->GetValue4());
1750 if (!bitmapResource)
1751 return wxEmptyString;
457814b5 1752
f6bcfd97
BP
1753 wxNode *node = bitmapResource->GetChildren().First();
1754 while (node)
1755 {
1756 // Eventually augment this to return a bitmap of the right kind or something...
1757 // Maybe the root of the filename remains the same, so it doesn't matter which we
1758 // pick up. Otherwise how do we specify multiple filenames... too boring...
1759 wxItemResource *child = (wxItemResource *)node->Data();
1760 return child->GetName();
1761
1762 //node = node->Next();
1763 }
1764 return wxEmptyString;
457814b5
JS
1765}
1766
fd71308f 1767wxItemResource *wxResourceManager::FindBitmapResourceByFilename(const wxString& filename)
457814b5 1768{
f6bcfd97
BP
1769 m_resourceTable.BeginFind();
1770 wxNode *node;
1771 while ((node = m_resourceTable.Next()))
457814b5 1772 {
f6bcfd97
BP
1773 wxItemResource *res = (wxItemResource *)node->Data();
1774 wxString resType(res->GetType());
1775 if (resType == "wxBitmap")
1776 {
1777 wxNode *node1 = res->GetChildren().First();
1778 while (node1)
1779 {
1780 wxItemResource *child = (wxItemResource *)node1->Data();
1781 if (child->GetName() && (strcmp(child->GetName(), filename) == 0))
1782 return res;
1783 node1 = node1->Next();
1784 }
1785 }
457814b5 1786 }
f6bcfd97 1787 return NULL;
457814b5
JS
1788}
1789
5de76427
JS
1790// Is this window identifier symbol in use?
1791// Let's assume that we can't have 2 names for the same integer id.
1792// Therefore we can tell by the integer id whether the symbol is
1793// in use.
1794bool wxResourceManager::IsSymbolUsed(wxItemResource* thisResource, wxWindowID id)
1795{
f6bcfd97
BP
1796 m_resourceTable.BeginFind();
1797 wxNode *node;
1798 while ((node = m_resourceTable.Next()))
5de76427 1799 {
f6bcfd97
BP
1800 wxItemResource *res = (wxItemResource *)node->Data();
1801
1802 wxString resType(res->GetType());
1803 if (resType == "wxDialog" || resType == "wxDialogBox" || resType == "wxPanel")
1804 {
1805 if ((res != thisResource) && (res->GetId() == id))
1806 return TRUE;
1807
1808 wxNode *node1 = res->GetChildren().First();
1809 while (node1)
1810 {
1811 wxItemResource *child = (wxItemResource *)node1->Data();
1812 if ((child != thisResource) && (child->GetId() == id))
1813 return TRUE;
1814 node1 = node1->Next();
1815 }
1816 }
5de76427 1817 }
f6bcfd97 1818 return FALSE;
5de76427
JS
1819}
1820
1821// Is this window identifier compatible with the given name? (i.e.
1822// does it already exist under a different name)
1823bool wxResourceManager::IsIdentifierOK(const wxString& name, wxWindowID id)
1824{
1825 if (m_symbolTable.SymbolExists(name))
1826 {
1827 int foundId = m_symbolTable.GetIdForSymbol(name);
1828 if (foundId != id)
1829 return FALSE;
1830 }
1831 return TRUE;
1832}
1833
1834// Change all integer ids that match oldId, to newId.
1835// This is necessary if an id is changed for one resource - all resources
1836// must be changed.
1837void wxResourceManager::ChangeIds(int oldId, int newId)
1838{
f6bcfd97
BP
1839 m_resourceTable.BeginFind();
1840 wxNode *node;
1841 while ((node = m_resourceTable.Next()))
5de76427 1842 {
f6bcfd97
BP
1843 wxItemResource *res = (wxItemResource *)node->Data();
1844
1845 wxString resType(res->GetType());
1846 if (resType == "wxDialog" || resType == "wxDialogBox" || resType == "wxPanel")
1847 {
1848 if (res->GetId() == oldId)
1849 res->SetId(newId);
1850
1851 wxNode *node1 = res->GetChildren().First();
1852 while (node1)
1853 {
1854 wxItemResource *child = (wxItemResource *)node1->Data();
1855 if (child->GetId() == oldId)
1856 child->SetId(newId);
1857
1858 node1 = node1->Next();
1859 }
1860 }
5de76427 1861 }
5de76427
JS
1862}
1863
bbcdf8bc
JS
1864// If any resource ids were missing (or their symbol was missing),
1865// repair them i.e. give them new ids. Returns TRUE if any resource
1866// needed repairing.
1867bool wxResourceManager::RepairResourceIds()
1868{
f6bcfd97
BP
1869 bool repaired = FALSE;
1870
1871 m_resourceTable.BeginFind();
1872 wxNode *node;
1873 while ((node = m_resourceTable.Next()))
bbcdf8bc 1874 {
f6bcfd97
BP
1875 wxItemResource *res = (wxItemResource *)node->Data();
1876 wxString resType(res->GetType());
1877 if (resType == "wxDialog" || resType == "wxDialogBox" || resType == "wxPanel")
bbcdf8bc 1878 {
f6bcfd97
BP
1879
1880 if ( (res->GetId() == 0) || ((res->GetId() > 0) && !m_symbolTable.IdExists(res->GetId())) )
bbcdf8bc 1881 {
f6bcfd97
BP
1882 wxString newSymbolName;
1883 int newId = GenerateWindowId("ID_DIALOG", newSymbolName) ;
1884
1885 if (res->GetId() == 0)
1886 {
1887 res->SetId(newId);
1888 m_symbolTable.AddSymbol(newSymbolName, newId);
1889 }
1890 else
1891 {
1892 m_symbolTable.AddSymbol(newSymbolName, res->GetId());
1893 }
1894
1895 repaired = TRUE;
bbcdf8bc 1896 }
f6bcfd97
BP
1897
1898 wxNode *node1 = res->GetChildren().First();
1899 while (node1)
bbcdf8bc 1900 {
f6bcfd97
BP
1901 wxItemResource *child = (wxItemResource *)node1->Data();
1902
1903 if ( (child->GetId() == 0) || ((child->GetId() > 0) && !m_symbolTable.IdExists(child->GetId())) )
1904 {
1905 wxString newSymbolName;
1906 int newId = GenerateWindowId("ID_CONTROL", newSymbolName) ;
1907
1908 if (child->GetId() == 0)
1909 {
1910 child->SetId(newId);
1911 m_symbolTable.AddSymbol(newSymbolName, newId);
1912 }
1913 else
1914 {
1915 m_symbolTable.AddSymbol(newSymbolName, child->GetId());
1916 }
1917
1918 repaired = TRUE;
1919 }
1920
1921 node1 = node1->Next();
bbcdf8bc 1922 }
bbcdf8bc 1923 }
bbcdf8bc 1924 }
f6bcfd97 1925 return repaired;
bbcdf8bc
JS
1926}
1927
1928
f6bcfd97
BP
1929// Deletes 'win' and creates a new window from the resource that
1930// was associated with it. E.g. if you can't change properties on the
1931// fly, you'll need to delete the window and create it again.
30b5fc11 1932wxWindow *wxResourceManager::RecreateWindowFromResource(wxWindow *win, wxWindowPropertyInfo *info, bool instantiateFirst)
457814b5 1933{
f6bcfd97 1934 wxItemResource *resource = FindResourceForWindow(win);
457814b5 1935
f6bcfd97
BP
1936 // Put the current window properties into the wxItemResource object
1937
1938 wxWindowPropertyInfo *newInfo = NULL;
1939 if (!info)
1940 {
1941 newInfo = CreatePropertyInfoForWindow(win);
1942 info = newInfo;
1943 }
1944
1945 // May not always want to copy values back from the resource
1946 if (instantiateFirst)
1947 info->InstantiateResource(resource);
1948
1949 wxWindow *newWin = NULL;
1950 wxWindow *parent = win->GetParent();
1951 wxItemResource* parentResource = NULL;
1952 if (parent)
1953 parentResource = FindResourceForWindow(parent);
1954
1955 if (win->IsKindOf(CLASSINFO(wxPanel)))
1956 {
1957 Edit(resource);
1958 newWin = FindWindowForResource(resource);
1959 }
1960 else
1961 {
1962 DisassociateResource(resource);
1963 if (win->GetEventHandler() != win)
1964 win->PopEventHandler(TRUE);
1965
1966 DeleteWindow(win);
1967 newWin = m_resourceTable.CreateItem((wxPanel *)parent, resource, parentResource);
1968 newWin->PushEventHandler(new wxResourceEditorControlHandler((wxControl*) newWin, (wxControl*) newWin));
1969 AssociateResource(resource, newWin);
1970 UpdateResourceList();
1971 }
1972
1973 if (info)
1974 info->SetPropertyWindow(newWin);
1975
1976 if (newInfo)
1977 delete newInfo;
1978
1979 return newWin;
457814b5
JS
1980}
1981
1982// Delete resource highlighted in the listbox
ae8351fc 1983bool wxResourceManager::DeleteSelection()
457814b5 1984{
f6bcfd97
BP
1985 int sel = m_editorResourceTree->GetSelection();
1986 if (sel != 0)
457814b5 1987 {
f6bcfd97
BP
1988 wxResourceTreeData *data = (wxResourceTreeData *)m_editorResourceTree->GetItemData(sel);
1989 wxItemResource *res = data->GetResource();
1990 wxWindow *win = FindWindowForResource(res);
1991 if (win)
1992 {
1993 DeleteResource(win);
1994 DeleteWindow(win);
1995 UpdateResourceList();
1996 Modify(TRUE);
1997 }
1998 return TRUE;
457814b5 1999 }
f6bcfd97
BP
2000
2001 return FALSE;
457814b5
JS
2002}
2003
2004// Delete resource highlighted in the listbox
ae8351fc 2005bool wxResourceManager::RecreateSelection()
457814b5 2006{
f6bcfd97
BP
2007 wxNode *node = GetSelections().First();
2008 while (node)
2009 {
2010 wxControl *item = (wxControl *)node->Data();
2011 wxResourceEditorControlHandler *childHandler = (wxResourceEditorControlHandler *)item->GetEventHandler();
2012 wxNode *next = node->Next();
2013 childHandler->SelectItem(FALSE);
2014
2015 RemoveSelection(item);
2016
2017 RecreateWindowFromResource(item);
2018
2019 node = next;
2020 }
2021 return TRUE;
457814b5
JS
2022}
2023
fd71308f 2024bool wxResourceManager::EditDialog(wxDialog *WXUNUSED(dialog), wxWindow *WXUNUSED(parent))
457814b5 2025{
f6bcfd97 2026 return FALSE;
457814b5
JS
2027}
2028
457814b5
JS
2029// Ensures that all currently shown windows are saved to resources,
2030// e.g. just before writing to a .wxr file.
ae8351fc 2031bool wxResourceManager::InstantiateAllResourcesFromWindows()
457814b5 2032{
f6bcfd97
BP
2033 m_resourceTable.BeginFind();
2034 wxNode *node;
2035 while ((node = m_resourceTable.Next()))
457814b5 2036 {
f6bcfd97
BP
2037 wxItemResource *res = (wxItemResource *)node->Data();
2038 wxString resType(res->GetType());
2039
2040 if (resType == "wxDialog")
2041 {
2042 wxWindow *win = (wxWindow *)FindWindowForResource(res);
2043 if (win)
2044 InstantiateResourceFromWindow(res, win, TRUE);
2045 }
2046 else if (resType == "wxPanel")
2047 {
2048 wxWindow *win = (wxWindow *)FindWindowForResource(res);
2049 if (win)
2050 InstantiateResourceFromWindow(res, win, TRUE);
2051 }
457814b5 2052 }
f6bcfd97 2053 return TRUE;
457814b5
JS
2054}
2055
2056bool wxResourceManager::InstantiateResourceFromWindow(wxItemResource *resource, wxWindow *window, bool recurse)
2057{
f6bcfd97
BP
2058 wxWindowPropertyInfo *info = CreatePropertyInfoForWindow(window);
2059 info->SetResource(resource);
2060 info->InstantiateResource(resource);
2061 delete info;
2062
2063 if (recurse)
457814b5 2064 {
f6bcfd97
BP
2065 wxNode *node = resource->GetChildren().First();
2066 while (node)
2067 {
2068 wxItemResource *child = (wxItemResource *)node->Data();
2069 wxWindow *childWindow = FindWindowForResource(child);
2070
2071 if (!childWindow)
2072 {
2073 char buf[200];
2074 sprintf(buf, "Could not find window %s", (const char*) child->GetName());
2075 wxMessageBox(buf, "Dialog Editor problem", wxOK);
2076 }
2077 else
2078 InstantiateResourceFromWindow(child, childWindow, recurse);
2079 node = node->Next();
2080 }
2081 }
2082
2083 return TRUE;
457814b5
JS
2084}
2085
ae8351fc
JS
2086// Create a window information object for the give window
2087wxWindowPropertyInfo *wxResourceManager::CreatePropertyInfoForWindow(wxWindow *win)
2088{
f6bcfd97
BP
2089 wxWindowPropertyInfo *info = NULL;
2090 if (win->IsKindOf(CLASSINFO(wxScrollBar)))
2091 {
2092 info = new wxScrollBarPropertyInfo(win);
2093 }
2094 else if (win->IsKindOf(CLASSINFO(wxStaticBox)))
2095 {
2096 info = new wxGroupBoxPropertyInfo(win);
2097 }
2098 else if (win->IsKindOf(CLASSINFO(wxCheckBox)))
2099 {
2100 info = new wxCheckBoxPropertyInfo(win);
2101 }
2102 else if (win->IsKindOf(CLASSINFO(wxSlider)))
2103 {
2104 info = new wxSliderPropertyInfo(win);
2105 }
2106 else if (win->IsKindOf(CLASSINFO(wxGauge)))
2107 {
2108 info = new wxGaugePropertyInfo(win);
2109 }
2110 else if (win->IsKindOf(CLASSINFO(wxListBox)))
2111 {
2112 info = new wxListBoxPropertyInfo(win);
2113 }
2114 else if (win->IsKindOf(CLASSINFO(wxRadioBox)))
2115 {
2116 info = new wxRadioBoxPropertyInfo(win);
2117 }
2118 else if (win->IsKindOf(CLASSINFO(wxRadioButton)))
2119 {
2120 info = new wxRadioButtonPropertyInfo(win);
2121 }
2122 else if (win->IsKindOf(CLASSINFO(wxComboBox)))
2123 {
2124 info = new wxComboBoxPropertyInfo(win);
2125 }
2126 else if (win->IsKindOf(CLASSINFO(wxChoice)))
2127 {
2128 info = new wxChoicePropertyInfo(win);
2129 }
2130 else if (win->IsKindOf(CLASSINFO(wxBitmapButton)))
2131 {
2132 info = new wxBitmapButtonPropertyInfo(win);
2133 }
2134 else if (win->IsKindOf(CLASSINFO(wxButton)))
2135 {
2136 info = new wxButtonPropertyInfo(win);
2137 }
2138 else if (win->IsKindOf(CLASSINFO(wxStaticBitmap)))
2139 {
2140 info = new wxStaticBitmapPropertyInfo(win);
2141 }
2142 else if (win->IsKindOf(CLASSINFO(wxStaticText)))
2143 {
2144 info = new wxStaticTextPropertyInfo(win);
2145 }
2146 else if (win->IsKindOf(CLASSINFO(wxTextCtrl)))
2147 {
2148 info = new wxTextPropertyInfo(win);
2149 }
2150 else if (win->IsKindOf(CLASSINFO(wxPanel)))
2151 {
2152 info = new wxPanelPropertyInfo(win);
2153 }
2154 else
2155 {
2156 info = new wxWindowPropertyInfo(win);
2157 }
2158 return info;
ae8351fc
JS
2159}
2160
2161// Edit the given window
2162void wxResourceManager::EditWindow(wxWindow *win)
2163{
f6bcfd97
BP
2164 wxWindowPropertyInfo *info = CreatePropertyInfoForWindow(win);
2165 if (info)
2166 {
2167 info->SetResource(FindResourceForWindow(win));
2168 wxString str("Editing ");
2169 str += win->GetClassInfo()->GetClassName();
2170 str += ": ";
2171 if (win->GetName() != "")
2172 str += win->GetName();
2173 else
2174 str += "properties";
2175 info->Edit(NULL, str);
2176 }
ae8351fc
JS
2177}
2178
5de76427
JS
2179// Generate a window id and a first stab at a name
2180int wxResourceManager::GenerateWindowId(const wxString& prefix, wxString& idName)
2181{
2182 m_symbolIdCounter ++;
2183 while (m_symbolTable.IdExists(m_symbolIdCounter))
2184 m_symbolIdCounter ++;
f6bcfd97 2185
5de76427 2186 int nameId = m_symbolIdCounter;
f6bcfd97 2187
5de76427
JS
2188 wxString str;
2189 str.Printf("%d", nameId);
2190 idName = prefix + str;
f6bcfd97 2191
5de76427
JS
2192 while (m_symbolTable.SymbolExists(idName))
2193 {
2194 nameId ++;
2195 str.Printf("%d", nameId);
2196 idName = prefix + str;
2197 }
f6bcfd97 2198
5de76427
JS
2199 return m_symbolIdCounter;
2200}
2201
457814b5
JS
2202
2203/*
f6bcfd97
BP
2204* Resource editor frame
2205*/
ae8351fc
JS
2206
2207IMPLEMENT_CLASS(wxResourceEditorFrame, wxFrame)
2208
2209BEGIN_EVENT_TABLE(wxResourceEditorFrame, wxFrame)
f6bcfd97
BP
2210EVT_MENU(wxID_NEW, wxResourceEditorFrame::OnNew)
2211EVT_MENU(RESED_NEW_DIALOG, wxResourceEditorFrame::OnNewDialog)
2212EVT_MENU(wxID_OPEN, wxResourceEditorFrame::OnOpen)
2213EVT_MENU(RESED_CLEAR, wxResourceEditorFrame::OnClear)
2214EVT_MENU(wxID_SAVE, wxResourceEditorFrame::OnSave)
2215EVT_MENU(wxID_SAVEAS, wxResourceEditorFrame::OnSaveAs)
2216EVT_MENU(wxID_EXIT, wxResourceEditorFrame::OnExit)
2217EVT_MENU(wxID_ABOUT, wxResourceEditorFrame::OnAbout)
2218EVT_MENU(RESED_CONTENTS, wxResourceEditorFrame::OnContents)
2219EVT_MENU(RESED_DELETE, wxResourceEditorFrame::OnDeleteSelection)
2220EVT_MENU(RESED_RECREATE, wxResourceEditorFrame::OnRecreateSelection)
2221EVT_MENU(RESED_TEST, wxResourceEditorFrame::OnTest)
2222EVT_MENU(RESED_CONVERT_WXRS, wxResourceEditorFrame::OnConvertWXRs)
2223EVT_CLOSE(wxResourceEditorFrame::OnCloseWindow)
ae8351fc
JS
2224END_EVENT_TABLE()
2225
2226wxResourceEditorFrame::wxResourceEditorFrame(wxResourceManager *resMan, wxFrame *parent, const wxString& title,
f6bcfd97
BP
2227 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
2228wxFrame(parent, -1, title, pos, size, style, name)
457814b5 2229{
f6bcfd97 2230 manager = resMan;
457814b5
JS
2231}
2232
ae8351fc 2233wxResourceEditorFrame::~wxResourceEditorFrame()
457814b5
JS
2234{
2235}
2236
f6bcfd97
BP
2237void wxResourceEditorFrame::OnConvertWXRs(wxCommandEvent& WXUNUSED(event))
2238{
2239 manager->ConvertWXRs();
2240}
2241
b127f301 2242void wxResourceEditorFrame::OnNew(wxCommandEvent& WXUNUSED(event))
457814b5 2243{
f6bcfd97 2244 manager->New(FALSE);
ae8351fc
JS
2245}
2246
b127f301 2247void wxResourceEditorFrame::OnNewDialog(wxCommandEvent& WXUNUSED(event))
ae8351fc 2248{
f6bcfd97 2249 manager->CreateNewPanel();
ae8351fc
JS
2250}
2251
b127f301 2252void wxResourceEditorFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
ae8351fc 2253{
f6bcfd97 2254 manager->New(TRUE);
ae8351fc
JS
2255}
2256
b127f301 2257void wxResourceEditorFrame::OnClear(wxCommandEvent& WXUNUSED(event))
ae8351fc 2258{
f6bcfd97 2259 manager->Clear(TRUE, FALSE);
ae8351fc
JS
2260}
2261
b127f301 2262void wxResourceEditorFrame::OnSave(wxCommandEvent& WXUNUSED(event))
ae8351fc 2263{
f6bcfd97 2264 manager->Save();
ae8351fc
JS
2265}
2266
b127f301 2267void wxResourceEditorFrame::OnSaveAs(wxCommandEvent& WXUNUSED(event))
ae8351fc 2268{
f6bcfd97 2269 manager->SaveAs();
ae8351fc
JS
2270}
2271
b127f301 2272void wxResourceEditorFrame::OnExit(wxCommandEvent& WXUNUSED(event))
ae8351fc 2273{
f6bcfd97
BP
2274 manager->Clear(TRUE, FALSE) ;
2275 this->Destroy();
ae8351fc
JS
2276}
2277
b127f301 2278void wxResourceEditorFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
ae8351fc 2279{
f6bcfd97 2280 char buf[300];
316df2f2 2281 sprintf(buf, "wxWindows Dialog Editor %.1f\n(c) Julian Smart 1996-1999", wxDIALOG_EDITOR_VERSION);
f6bcfd97 2282 wxMessageBox(buf, "About Dialog Editor", wxOK|wxCENTRE);
ae8351fc
JS
2283}
2284
b127f301 2285void wxResourceEditorFrame::OnTest(wxCommandEvent& WXUNUSED(event))
ae8351fc 2286{
03f68f12 2287 manager->TestCurrentDialog(this);
ae8351fc
JS
2288}
2289
b127f301 2290void wxResourceEditorFrame::OnContents(wxCommandEvent& WXUNUSED(event))
ae8351fc 2291{
d0fff5cb 2292#ifdef __WXMSW__
f6bcfd97
BP
2293 wxBeginBusyCursor();
2294 manager->GetHelpController()->LoadFile();
2295 manager->GetHelpController()->DisplayContents();
2296 wxEndBusyCursor();
b127f301 2297#endif
ae8351fc
JS
2298}
2299
b127f301 2300void wxResourceEditorFrame::OnDeleteSelection(wxCommandEvent& WXUNUSED(event))
ae8351fc 2301{
f6bcfd97 2302 manager->DeleteSelection();
ae8351fc
JS
2303}
2304
b127f301 2305void wxResourceEditorFrame::OnRecreateSelection(wxCommandEvent& WXUNUSED(event))
ae8351fc 2306{
f6bcfd97 2307 manager->RecreateSelection();
457814b5
JS
2308}
2309
e3065973 2310void wxResourceEditorFrame::OnCloseWindow(wxCloseEvent& event)
457814b5 2311{
f6bcfd97
BP
2312 wxPropertyInfo::CloseWindow();
2313 manager->ClearCurrentDialog();
2314 if (manager->Modified())
2315 {
2316 if (!manager->Clear(TRUE, FALSE))
2317 {
2318 event.Veto();
2319 return;
2320 }
e3065973 2321 }
457814b5 2322
f6bcfd97
BP
2323 if (!IsIconized())
2324 {
2325 int w, h;
2326 GetSize(&w, &h);
2327 manager->m_resourceEditorWindowSize.width = w;
2328 manager->m_resourceEditorWindowSize.height = h;
2329
2330 int x, y;
2331 GetPosition(&x, &y);
2332
2333 manager->m_resourceEditorWindowSize.x = x;
2334 manager->m_resourceEditorWindowSize.y = y;
2335 }
2336 manager->SetEditorFrame(NULL);
2337 manager->SetEditorToolBar(NULL);
2338
2339 this->Destroy();
457814b5
JS
2340}
2341
2342/*
f6bcfd97
BP
2343* Resource editor window that contains the dialog/panel being edited
2344*/
ae8351fc
JS
2345
2346BEGIN_EVENT_TABLE(wxResourceEditorScrolledWindow, wxScrolledWindow)
f6bcfd97 2347EVT_PAINT(wxResourceEditorScrolledWindow::OnPaint)
ae8351fc
JS
2348END_EVENT_TABLE()
2349
2350wxResourceEditorScrolledWindow::wxResourceEditorScrolledWindow(wxWindow *parent, const wxPoint& pos, const wxSize& size,
f6bcfd97
BP
2351 long style):
2352wxScrolledWindow(parent, -1, pos, size, style)
457814b5 2353{
ae8351fc
JS
2354 m_marginX = 10;
2355 m_marginY = 40;
2356 m_childWindow = NULL;
f6bcfd97 2357
15d5ab67 2358 SetBackgroundColour(* wxWHITE);
457814b5
JS
2359}
2360
ae8351fc 2361wxResourceEditorScrolledWindow::~wxResourceEditorScrolledWindow()
457814b5
JS
2362{
2363}
2364
b127f301 2365void wxResourceEditorScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
ae8351fc
JS
2366{
2367 wxPaintDC dc(this);
f6bcfd97 2368
ae8351fc
JS
2369 DrawTitle(dc);
2370}
2371
2372void wxResourceEditorScrolledWindow::DrawTitle(wxDC& dc)
2373{
2374 if (m_childWindow)
2375 {
2376 wxItemResource* res = wxResourceManager::GetCurrentResourceManager()->FindResourceForWindow(m_childWindow);
2377 if (res)
2378 {
2379 wxString str(res->GetTitle());
2380 int x, y;
5e998a33 2381 GetViewStart(& x, & y);
f6bcfd97 2382
ae8351fc
JS
2383 wxFont font(10, wxSWISS, wxNORMAL, wxBOLD);
2384 dc.SetFont(font);
2385 dc.SetBackgroundMode(wxTRANSPARENT);
2386 dc.SetTextForeground(wxColour(0, 0, 0));
f6bcfd97 2387
ae8351fc
JS
2388 long w, h;
2389 dc.GetTextExtent(str, & w, & h);
f6bcfd97 2390
ae8351fc
JS
2391 dc.DrawText(str, m_marginX + (- x * 10), m_marginY + (- y * 10) - h - 5);
2392 }
2393 }
457814b5
JS
2394}
2395
457814b5 2396/*
f6bcfd97
BP
2397* Main toolbar
2398*
2399*/
457814b5 2400
9d3221ab 2401BEGIN_EVENT_TABLE(EditorToolBar, wxToolBar)
33961d59 2402// EVT_PAINT(EditorToolBar::OnPaint)
9d3221ab
RR
2403END_EVENT_TABLE()
2404
ae8351fc 2405EditorToolBar::EditorToolBar(wxFrame *frame, const wxPoint& pos, const wxSize& size,
f6bcfd97
BP
2406 long style):
2407wxToolBar(frame, -1, pos, size, style)
457814b5
JS
2408{
2409}
2410
fd71308f 2411bool EditorToolBar::OnLeftClick(int toolIndex, bool WXUNUSED(toggled))
457814b5 2412{
f6bcfd97
BP
2413 wxResourceManager *manager = wxResourceManager::GetCurrentResourceManager();
2414
2415 switch (toolIndex)
457814b5 2416 {
f6bcfd97
BP
2417 case TOOLBAR_LOAD_FILE:
2418 {
2419 manager->New(TRUE);
2420 break;
2421 }
457814b5 2422 case TOOLBAR_NEW:
f6bcfd97
BP
2423 {
2424 manager->CreateNewPanel();
2425 break;
2426 }
457814b5 2427 case TOOLBAR_SAVE_FILE:
f6bcfd97
BP
2428 {
2429 manager->Save();
2430 break;
2431 }
457814b5 2432 case TOOLBAR_HELP:
f6bcfd97 2433 {
d0fff5cb 2434#ifdef __WXMSW__
f6bcfd97
BP
2435 wxBeginBusyCursor();
2436 manager->GetHelpController()->DisplayContents();
2437 wxEndBusyCursor();
b127f301 2438#endif
f6bcfd97
BP
2439 break;
2440 }
457814b5 2441 case TOOLBAR_FORMAT_HORIZ:
f6bcfd97
BP
2442 {
2443 manager->AlignItems(TOOLBAR_FORMAT_HORIZ);
2444 break;
2445 }
457814b5 2446 case TOOLBAR_FORMAT_HORIZ_LEFT_ALIGN:
f6bcfd97
BP
2447 {
2448 manager->AlignItems(TOOLBAR_FORMAT_HORIZ_LEFT_ALIGN);
2449 break;
2450 }
457814b5 2451 case TOOLBAR_FORMAT_HORIZ_RIGHT_ALIGN:
f6bcfd97
BP
2452 {
2453 manager->AlignItems(TOOLBAR_FORMAT_HORIZ_RIGHT_ALIGN);
2454 break;
2455 }
457814b5 2456 case TOOLBAR_FORMAT_VERT:
f6bcfd97
BP
2457 {
2458 manager->AlignItems(TOOLBAR_FORMAT_VERT);
2459 break;
2460 }
457814b5 2461 case TOOLBAR_FORMAT_VERT_TOP_ALIGN:
f6bcfd97
BP
2462 {
2463 manager->AlignItems(TOOLBAR_FORMAT_VERT_TOP_ALIGN);
2464 break;
2465 }
457814b5 2466 case TOOLBAR_FORMAT_VERT_BOT_ALIGN:
f6bcfd97
BP
2467 {
2468 manager->AlignItems(TOOLBAR_FORMAT_VERT_BOT_ALIGN);
2469 break;
2470 }
457814b5 2471 case TOOLBAR_COPY_SIZE:
f6bcfd97
BP
2472 {
2473 manager->CopySize(TOOLBAR_COPY_SIZE);
2474 break;
2475 }
2476 case TOOLBAR_COPY_WIDTH:
2477 {
2478 manager->CopySize(TOOLBAR_COPY_WIDTH);
2479 break;
2480 }
2481 case TOOLBAR_COPY_HEIGHT:
2482 {
2483 manager->CopySize(TOOLBAR_COPY_HEIGHT);
2484 break;
2485 }
2486 case TOOLBAR_DISTRIBUTE_HORIZ:
2487 {
2488 manager->DistributePositions(TOOLBAR_DISTRIBUTE_HORIZ);
2489 break;
2490 }
2491 case TOOLBAR_DISTRIBUTE_VERT:
2492 {
2493 manager->DistributePositions(TOOLBAR_DISTRIBUTE_VERT);
2494 break;
2495 }
457814b5 2496 case TOOLBAR_TO_BACK:
f6bcfd97
BP
2497 {
2498 manager->ToBackOrFront(TRUE);
2499 break;
2500 }
457814b5 2501 case TOOLBAR_TO_FRONT:
f6bcfd97
BP
2502 {
2503 manager->ToBackOrFront(FALSE);
2504 break;
2505 }
457814b5 2506 default:
f6bcfd97
BP
2507 break;
2508 }
2509 return TRUE;
457814b5
JS
2510}
2511
2512void EditorToolBar::OnMouseEnter(int toolIndex)
2513{
f6bcfd97
BP
2514 wxFrame *frame = (wxFrame *)GetParent();
2515
2516 if (!frame) return;
2517
2518 if (toolIndex > -1)
2519 {
2520 switch (toolIndex)
2521 {
457814b5 2522 case TOOLBAR_LOAD_FILE:
f6bcfd97
BP
2523 frame->SetStatusText("Load project file");
2524 break;
457814b5 2525 case TOOLBAR_SAVE_FILE:
f6bcfd97
BP
2526 frame->SetStatusText("Save project file");
2527 break;
457814b5 2528 case TOOLBAR_NEW:
f6bcfd97
BP
2529 frame->SetStatusText("Create a new resource");
2530 break;
457814b5 2531 case TOOLBAR_FORMAT_HORIZ:
f6bcfd97
BP
2532 frame->SetStatusText("Align items horizontally");
2533 break;
457814b5 2534 case TOOLBAR_FORMAT_VERT:
f6bcfd97
BP
2535 frame->SetStatusText("Align items vertically");
2536 break;
457814b5 2537 case TOOLBAR_FORMAT_HORIZ_LEFT_ALIGN:
f6bcfd97
BP
2538 frame->SetStatusText("Left-align items");
2539 break;
457814b5 2540 case TOOLBAR_FORMAT_HORIZ_RIGHT_ALIGN:
f6bcfd97
BP
2541 frame->SetStatusText("Right-align items");
2542 break;
457814b5 2543 case TOOLBAR_FORMAT_VERT_TOP_ALIGN:
f6bcfd97
BP
2544 frame->SetStatusText("Top-align items");
2545 break;
457814b5 2546 case TOOLBAR_FORMAT_VERT_BOT_ALIGN:
f6bcfd97
BP
2547 frame->SetStatusText("Bottom-align items");
2548 break;
457814b5 2549 case TOOLBAR_COPY_SIZE:
f6bcfd97
BP
2550 frame->SetStatusText("Copy size from first selection");
2551 break;
457814b5 2552 case TOOLBAR_TO_FRONT:
f6bcfd97
BP
2553 frame->SetStatusText("Put image to front");
2554 break;
457814b5 2555 case TOOLBAR_TO_BACK:
f6bcfd97
BP
2556 frame->SetStatusText("Put image to back");
2557 break;
457814b5 2558 case TOOLBAR_HELP:
f6bcfd97
BP
2559 frame->SetStatusText("Display help contents");
2560 break;
457814b5 2561 default:
f6bcfd97
BP
2562 break;
2563 }
2564 }
2565 else frame->SetStatusText("");
457814b5
JS
2566}
2567
f6bcfd97
BP
2568bool ResourceEditorDialogTester::ProcessEvent(wxEvent& event)
2569{
2570 if (event.IsCommandEvent() && event.GetId() != wxID_OK && event.GetId() != wxID_CANCEL)
2571 {
2572 // Do nothing
2573 return TRUE;
2574 }
2575 else
2576 return wxDialog::ProcessEvent(event);
2577}
2578
2579static int gs_LabelInsertionCount = 0;
2580
2581// Convert old WXRs to new
2582bool wxResourceManager::ConvertWXRs()
2583{
2584 gs_LabelInsertionCount = 0;
2585 m_symbolIdCounter = 20000;
2586
2587 wxString currentPath = wxGetCwd();
2588 wxString oldWXRPath, newWXRPath;
2589
2590 wxDirDialog dialog(NULL, wxT("Choose directory for old WXRs"), currentPath);
2591
2592 if (dialog.ShowModal() == wxID_OK)
2593 {
2594 oldWXRPath = dialog.GetPath();
2595 }
2596 else
2597 return FALSE;
2598
2599 wxDirDialog dialog2(NULL, wxT("Choose directory for new WXRs"), oldWXRPath);
2600
2601 if (dialog2.ShowModal() == wxID_OK)
2602 {
2603 newWXRPath = dialog2.GetPath();
2604 }
2605 else
2606 return FALSE;
2607
2608 if (newWXRPath == oldWXRPath)
2609 {
2610 wxMessageBox(wxT("Sorry, the directories must be different."));
2611 return FALSE;
2612 }
2613
2614 wxDir dir(oldWXRPath);
2615 if (!dir.IsOpened())
2616 return FALSE;
2617
2618 wxArrayString stringArray;
2619
2620 wxString filename;
2621 bool ok = dir.GetFirst(& filename, wxT("*.wxr"));
2622 while (ok)
2623 {
2624 stringArray.Add(filename);
2625
2626 ok = dir.GetNext(& filename);
2627 }
2628
2629 // Pop up a progress dialog
2630 wxProgressDialog progressDialog(wxT("Converting WXR files"), wxT("Converting files..."));
2631
2632 size_t i;
2633 for (i = 0; i < stringArray.Count(); i++)
2634 {
2635 progressDialog.Update((int) (100.0 * ((double) i / (double) stringArray.Count())));
2636
2637 filename = stringArray[i];
2638 wxString oldPath = oldWXRPath + wxString(wxFILE_SEP_PATH) + filename;
2639 wxString newPath = newWXRPath + wxString(wxFILE_SEP_PATH) + filename;
2640
2641 DoConvertWXR(oldPath, newPath);
2642 }
2643
2644 wxString msg;
2645 msg.Printf(wxT("Dialog Editor inserted %d labels."), gs_LabelInsertionCount);
2646 wxMessageBox(msg);
2647
2648 return TRUE;
2649}
2650
2651bool wxResourceManager::DoConvertWXR(const wxString& oldPath, const wxString& newPath)
2652{
2653
2654 if (!Clear(TRUE, FALSE))
2655 return FALSE;
2656
2657 m_symbolTable.AddStandardSymbols();
2658
2659 if (!m_resourceTable.ParseResourceFile(oldPath))
2660 {
2661 wxString msg;
2662 msg.Printf(wxT("Could not read file %s"), (const char*) oldPath);
2663 wxMessageBox(msg, "Resource file load error", wxOK | wxICON_EXCLAMATION);
2664 return FALSE;
2665 }
2666 m_currentFilename = oldPath;
2667
2668 //SetFrameTitle(m_currentFilename);
2669
2670 //UpdateResourceList();
2671
2672 // Construct include filename from this file
2673 m_symbolFilename = m_currentFilename;
2674
2675 wxStripExtension(m_symbolFilename);
2676 m_symbolFilename += wxT(".h");
2677
2678 if (!m_symbolTable.ReadIncludeFile(m_symbolFilename))
2679 {
2680 }
2681 else
2682 {
2683 // Set the id counter to the last known id
2684 m_symbolIdCounter = m_symbolTable.FindHighestId();
2685 }
2686
2687 // Now check in case some (or all) resources don't have resource ids, or they
2688 // don't match the .h file, or something of that nature.
2689 bool altered = RepairResourceIds();
2690
2691 // Do any necessary changes to the resources
2692 m_resourceTable.BeginFind();
2693 wxNode *node;
2694 while ((node = m_resourceTable.Next()))
2695 {
2696 wxItemResource *res = (wxItemResource *)node->Data();
2697 ChangeOldToNewResource(NULL, res);
2698 }
2699
2700 // Change the filename before saving
2701
2702 m_currentFilename = newPath;
2703 m_symbolFilename = m_currentFilename;
2704 wxStripExtension(m_symbolFilename);
2705 m_symbolFilename += wxT(".h");
2706
2707 Modify(TRUE);
2708
2709 Save();
2710
2711 Clear(TRUE, TRUE);
2712
2713 return TRUE;
2714
2715}
2716
2717bool wxResourceManager::ChangeOldToNewResource(wxItemResource* parent, wxItemResource* res)
2718{
2719 // Change these according to your needs
2720
2721 // Change all fonts to use system defaults for fonts, colours etc.
2722 static bool s_useSystemDefaultsAlways = FALSE; // TRUE;
2723
2724 // Increase dialog height by this amount (wxWin 2 uses dialog client size now)
2725 static int s_increaseDialogSize = -18;
2726
2727 // How many points to decrease the font sizes by, since
2728 // wxWin 2 fonts are larger in Windows
2729 static int s_decreaseFontSize = 3;
2730
2731 wxString itemType(res->GetType());
2732
2733 wxFont font = res->GetFont();
2734
2735 if ((s_decreaseFontSize) > 0 && font.Ok())
2736 {
2737 wxFont newFont = wxFont(font.GetPointSize() - s_decreaseFontSize,
2738 font.GetFamily(), font.GetStyle(), font.GetWeight(),
2739 font.GetUnderlined(), font.GetFaceName());
2740 res->SetFont(newFont);
2741 }
2742
2743 if (itemType == wxT("wxDialogBox") || itemType == wxT("wxDialog") || itemType == wxT("wxPanel"))
2744 {
2745 if (itemType == wxT("wxDialogBox"))
2746 res->SetType(wxT("wxDialog"));
2747
2748 if (itemType == wxT("wxDialogBox") || itemType == wxT("wxDialog"))
2749 {
2750 // Only change the height if it has a caption, i.e. it's going to be
2751 // used as a proper dialog and not a panel
2752 if (res->GetStyle() & wxCAPTION)
2753 res->SetSize(res->GetX(), res->GetY(), res->GetWidth(), res->GetHeight() + s_increaseDialogSize );
2754 }
2755
2756 if (s_useSystemDefaultsAlways)
2757 res->SetResourceStyle(res->GetResourceStyle() | wxRESOURCE_USE_DEFAULTS);
2758
2759 if (res->GetValue1())
2760 res->SetStyle(res->GetStyle() | wxDIALOG_MODAL);
2761
2762 wxNode *node = res->GetChildren().First();
2763 while (node)
2764 {
2765 wxItemResource *child = (wxItemResource *)node->Data();
2766
2767 ChangeOldToNewResource(res, child);
2768 node = node->Next();
2769 }
2770 }
2771 else if (itemType == wxT("wxMessage"))
2772 {
2773 // Figure out if this is a bitmap or text message
2774 if (res->GetValue4().IsEmpty())
2775 res->SetType(wxT("wxStaticText"));
2776 else
2777 res->SetType(wxT("wxStaticBitmap"));
2778 }
2779 else if (itemType == wxT("wxButton"))
2780 {
2781 // Figure out if this is a bitmap or text message
2782 if (res->GetValue4().IsEmpty())
2783 {
2784 }
2785 else
2786 res->SetType(wxT("wxBitmapButton"));
2787 }
2788 else if (itemType == wxT("wxGroupBox"))
2789 {
2790 res->SetType(wxT("wxStaticBox"));
2791 }
2792 else if (itemType == wxT("wxText"))
2793 {
2794 res->SetType(wxT("wxTextCtrl"));
2795 }
2796 else if (itemType == wxT("wxMultiText"))
2797 {
2798 res->SetType(wxT("wxTextCtrl"));
2799 res->SetStyle(res->GetStyle() | wxTE_MULTILINE);
2800 }
2801
2802 itemType = res->GetType();
2803
2804 if (!res->GetTitle().IsEmpty() &&
2805 (itemType == wxT("wxTextCtrl") || itemType == wxT("wxChoice") ||
2806 itemType == wxT("wxComboBox") || itemType == wxT("wxGauge") ||
2807 itemType == wxT("wxListBox")))
2808 {
2809 // Insert a label control resource, adjusting the size of this
2810 // resource accordingly.
2811 InsertLabelResource(parent, res);
2812 }
2813
2814 return TRUE;
2815}
2816
2817// Insert a label control resource, adjusting the size of this
2818// resource accordingly.
2819bool wxResourceManager::InsertLabelResource(wxItemResource* parent, wxItemResource* res)
2820{
2821 gs_LabelInsertionCount ++;
2822
2823 bool isHorizontal = TRUE;
2824
2825 // Determine panel orientation
2826 if (parent->GetResourceStyle() & wxRESOURCE_VERTICAL_LABEL)
2827 {
2828 isHorizontal = FALSE;
2829 }
2830 else if (parent->GetResourceStyle() & wxRESOURCE_HORIZONTAL_LABEL)
2831 {
2832 isHorizontal = TRUE;
2833 }
2834
2835 // Now override
2836 if (res->GetResourceStyle() & wxRESOURCE_VERTICAL_LABEL)
2837 {
2838 isHorizontal = FALSE;
2839 }
2840 else if (res->GetResourceStyle() & wxRESOURCE_HORIZONTAL_LABEL)
2841 {
2842 isHorizontal = TRUE;
2843 }
2844
2845 int x = res->GetX();
2846 int y = res->GetY();
2847 int width = res->GetWidth();
2848 int height = res->GetHeight();
2849
2850 // Find the font specified
2851 wxFont font;
2852 if (res->GetFont().Ok())
2853 font = res->GetFont();
2854 else
2855 font = parent->GetFont();
2856
2857 if (!font.Ok() || (parent->GetResourceStyle() & wxRESOURCE_USE_DEFAULTS))
e1c6c6ae 2858 font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
f6bcfd97
BP
2859
2860 int labelX, labelY;
2861 wxCoord labelWidth, labelHeight;
2862 wxScreenDC dc;
2863 dc.SetFont(font);
2864 dc.GetTextExtent(res->GetTitle(), & labelWidth, & labelHeight);
2865
2866 // Vert/horizontal margin between controls
2867 int margin = 3;
2868
2869 labelX = x;
2870 labelY = y;
2871 //labelWidth += 1;
2872 //labelHeight += 1;
2873
2874 if (isHorizontal)
2875 {
2876 x += labelWidth + margin;
2877 width -= (labelWidth + margin);
2878 }
2879 else
2880 {
2881 y += labelHeight + margin;
2882 height -= (labelHeight + margin);
2883
2884 // Fudge factors
2885 if (res->GetType() == wxT("wxTextCtrl"))
2886 {
2887 height += 3;
2888 }
2889 else if (res->GetType() == wxT("wxChoice") || res->GetType() == wxT("wxComboBox"))
2890 {
2891 height -= 4;
2892 }
2893 }
2894
2895 res->SetSize(x, y, width, height);
2896
2897 wxItemResource* staticItem = new wxItemResource;
2898 staticItem->SetSize(labelX, labelY, labelWidth, labelHeight);
2899 staticItem->SetTitle(res->GetTitle());
2900 staticItem->SetFont(font);
2901 staticItem->SetStyle(0);
2902 staticItem->SetType(wxT("wxStaticText"));
2903
2904 wxString newSymbolName;
2905 int newId = GenerateWindowId(wxT("ID_STATICTEXT"), newSymbolName) ;
2906 staticItem->SetId(newId);
2907
2908 newSymbolName = res->GetName() + wxT("_Label");
2909 staticItem->SetName(newSymbolName);
2910 m_symbolTable.AddSymbol(newSymbolName, newId);
2911
2912 wxNode* node = parent->GetChildren().Member(res);
2913
2914 wxASSERT( (node != NULL) );
2915
2916 parent->GetChildren().Insert(node, staticItem);
2917
2918 // Remove the title from this resource since we've replaced it
2919 // with a static text control
2920 res->SetTitle(wxEmptyString);
2921
2922 return TRUE;
2923}