]> git.saurik.com Git - wxWidgets.git/blame - contrib/utils/convertrc/rc2xml.cpp
linking fix for wxMotif
[wxWidgets.git] / contrib / utils / convertrc / rc2xml.cpp
CommitLineData
2193517f
VS
1// rc2xml.cpp: implementation of the rc2xml class.
2//Author: Brian Gavin 9/24/00
3//License: wxWindows License
4/*
5How to use:
6#include "rc2xml.h"
7...
8rc2xml trans;
9trans->Convert("Myfile.rc","Myfile.xml");
10*/
11/* TODO
121. Figure how to fix memory leaks in all wxLists in this class
132. Find a way to rename MS Windows fonts so that they work
14cross platform (wxGTK,etc)
153. Be able to abort incorrectly formated files without crashing
16*/
17
18#ifdef __GNUG__
19#pragma implementation "rc2xml.cpp"
20#pragma interface "rc2xml.cpp"
21#endif
22
88d42654 23// For compilers that support precompilation, includes "wx/wx.h".
2193517f
VS
24#include <wx/wxprec.h>
25
26#ifdef __BORLANDC__
27#pragma hdrstop
28#endif
29
30// for all others, include the necessary headers (this file is usually all you
31// need because it includes almost all "standard" wxWindows headers
32#ifndef WX_PRECOMP
33#include <wx/wx.h>
34#endif
35
88d42654
VS
36
37#include "rc2xml.h"
38#include "wx/image.h"
39#include "wx/resource.h"
2193517f
VS
40#include <wx/textfile.h>
41#include <wx/tokenzr.h>
42
43
44
88d42654
VS
45//////////////////////////////////////////////////////////////////////
46// Construction/Destruction
47//////////////////////////////////////////////////////////////////////
48
2193517f 49rc2xml::rc2xml()
88d42654 50{
2193517f
VS
51 m_done=FALSE;
52 m_bitmaplist=new wxList(wxKEY_STRING);
53 m_stringtable=new wxList(wxKEY_STRING);
54 m_iconlist = new wxList(wxKEY_STRING);
55 m_resourcelist =new wxList(wxKEY_INTEGER);
88d42654
VS
56}
57
2193517f 58rc2xml::~rc2xml()
88d42654 59{
2193517f
VS
60 delete m_bitmaplist;
61 delete m_stringtable;
62 delete m_iconlist;
63 delete m_resourcelist;
88d42654
VS
64}
65
2193517f 66bool rc2xml::Convert(wxString rcfile, wxString xmlfile)
88d42654 67{
2193517f
VS
68 m_rc.Open(rcfile.c_str());
69 m_filesize=m_rc.Length();
70
2c99715a
VS
71 m_workingpath=wxPathOnly(rcfile);
72 m_targetpath=wxPathOnly(xmlfile)+"\\";
73
74 wxSetWorkingDirectory(m_workingpath);
75
2193517f
VS
76 bool result;
77 result=m_xmlfile.Open(xmlfile.c_str(),"w+t");
78 wxASSERT_MSG(result,"Couldn't create XML file");
79 if (!result)
80 return FALSE;
88d42654
VS
81
82
83/* Write Basic header for XML file */
2193517f
VS
84 m_xmlfile.Write("<?xml version=\"1.0\" ?>\n");
85 m_xmlfile.Write("<resource>\n");
86
87//Read resource.h
88 ParseResourceHeader();
88d42654 89//Gather all the resource we need for toolbars,menus, and etc
2193517f
VS
90 FirstPass();
91 m_done=FALSE;
92 m_rc.Seek(0);
88d42654 93//Read in dialogs, toolbars,menus
2193517f 94 SecondPass();
88d42654 95
2193517f
VS
96 m_xmlfile.Write("</resource>\n");
97 m_xmlfile.Close();
98 m_rc.Close();
88d42654
VS
99
100return TRUE;
101}
102
103
2193517f 104void rc2xml::ParseDialog(wxString dlgname)
88d42654 105{
2193517f
VS
106 wxString token;
107 static int dlgid=999;
108 dlgid++;
109/* Make sure that this really is a dialog
110microsoft reuses the keyword DIALOG for other things
111*/
112 token=PeekToken();
113//Microsoft notation?
114 if (token=="DISCARDABLE")
115 {
116 token=GetToken();
117 token=PeekToken();
118 }
119//Error isn't a Dialog resource eject eject
120 if (!token.IsNumber())
121 return;
88d42654
VS
122
123//Record x,y,width,height
2193517f
VS
124 int x,y,width,height;
125 ReadRect(x,y,width,height);
88d42654 126//Get Title
2193517f
VS
127 token=GetToken();
128 wxString title;
129 wxString ptsize,face;
130
e066e256 131 m_xmlfile.Write("\t<object class=\"wxDialog\"");
2193517f
VS
132 //Avoid duplicate names this way
133 dlgname.Replace("IDD_","DLG_");
134 WriteBasicInfo(x,y,width,height,dlgname);
135 WriteTitle(title);
136
137
138 while ((token!="BEGIN")&(token!="{"))
139 {
140 if (token=="CAPTION")
141 {
142 title=GetQuoteField();
143 }
144
145//TODO fix face name so that it is cross platform name
146// FONT 8, "MS Sans Serif"
147 if (token=="FONT")
148 {
149 ptsize=GetToken();
150 face=GetQuoteField();
151 m_xmlfile.Write("\t\t<font>\n");
152 m_xmlfile.Write("\t\t\t<size>"+ptsize+"</size>\n");
153 m_xmlfile.Write("\t\t\t<face>"+face+"</face>\n");
154 m_xmlfile.Write("\t\t</font>\n");
155 }
156
157 token=GetToken();
158 }
88d42654 159
2193517f 160 ParseControls();
e066e256 161 m_xmlfile.Write("\t</object>\n");
88d42654
VS
162}
163
164/*
165BEGIN
166 EDITTEXT IDC_BANDS,36,83,22,14,ES_AUTOHSCROLL | ES_NUMBER | NOT
167 WS_TABSTOP
168 LTEXT "Bands",IDC_STATIC,11,86,21,8
169 EDITTEXT IDC_NAME,10,3,75,14,ES_AUTOHSCROLL
170END
171*/
2193517f 172void rc2xml::ParseControls()
88d42654 173{
2193517f
VS
174 wxString token;
175
176 token=GetToken();
177 while ((token!="END")&(token!="}"))
178 {
179 if (token=="LTEXT")
180 ParseStaticText();
181 else if (token=="EDITTEXT")
182 ParseTextCtrl();
183 else if (token=="PUSHBUTTON")
184 ParsePushButton();
185 else if (token=="DEFPUSHBUTTON")
186 ParsePushButton();
187 else if (token=="GROUPBOX")
188 ParseGroupBox();
189 else if (token=="COMBOBOX")
190 ParseComboBox();
191 else if (token=="CONTROL")
192 ParseControlMS();
193 else if (token=="LISTBOX")
194 ParseListBox();
195 else if (token=="ICON")
196 ParseIconStatic();
197 else if (token=="SCROLLBAR")
198 ParseScrollBar();
199 token=GetToken();
200 }
88d42654
VS
201
202}
203//LTEXT "Radius",IDC_STATIC,9,67,23,8
2193517f 204void rc2xml::ParseStaticText()
88d42654 205{
2193517f
VS
206 wxString token;
207 wxString phrase,varname;
208 phrase=GetQuoteField();
209 varname=GetToken();
210 int x,y,width,height;
211 ReadRect(x,y,width,height);
88d42654 212
e066e256 213 m_xmlfile.Write("\t\t<object class=\"wxStaticText\"");
2193517f 214 WriteBasicInfo(x,y,width,height,varname);WriteLabel(phrase);
e066e256 215 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
216
217}
218//EDITTEXT IDC_RADIUS,36,65,40,14,ES_AUTOHSCROLL
2193517f 219void rc2xml::ParseTextCtrl()
88d42654 220{
2193517f
VS
221 wxString token;
222 wxString varname,style;
223 varname=GetToken();
224 int x,y,width,height;
225 ReadRect(x,y,width,height);
88d42654
VS
226//TODO
227//style=GetToken();
e066e256 228 m_xmlfile.Write("\t\t<object class\"wxTextCtrl\"");
2193517f 229 WriteBasicInfo(x,y,width,height,varname);
e066e256 230 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
231
232}
233//PUSHBUTTON "Create/Update",IDC_CREATE,15,25,53,13,NOT WS_TABSTOP
2193517f 234void rc2xml::ParsePushButton()
88d42654 235{
2193517f
VS
236 wxString token;
237 wxString phrase,varname;
238 phrase=GetQuoteField();
239 varname=GetToken();
88d42654 240
2193517f
VS
241 int x,y,width,height;
242 ReadRect(x,y,width,height);
88d42654 243
2c99715a 244 m_xmlfile.Write("\t\t<object class=\"wxButton\"");
2193517f
VS
245 WriteBasicInfo(x,y,width,height,varname);
246 WriteLabel(phrase);
e066e256 247 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
248
249}
250
251
2193517f 252bool rc2xml::Seperator(int ch)
88d42654
VS
253{
254//if ((ch==' ')|(ch==',')|(ch==13)|(ch==10)|(ch=='|')|(ch=='\t'))
2193517f
VS
255 if ((ch==' ')|(ch==',')|(ch==13)|(ch==10)|(ch=='\t'))
256 return TRUE;
257
258 if (ch==EOF)
259 {
260 m_done=TRUE;
261 return TRUE;
262 }
263
264 return FALSE;
88d42654
VS
265}
266
2193517f 267void rc2xml::ParseGroupBox()
88d42654
VS
268{
269// GROUPBOX "Rotate",IDC_STATIC,1,1,71,79
2193517f
VS
270 wxString token;
271 wxString phrase,varname;
272 phrase=GetQuoteField();
273 varname=GetToken();
274 int x,y,width,height;
275 ReadRect(x,y,width,height);
276
e066e256 277 m_xmlfile.Write("\t\t<object class=\"wxStaticBox\"");
2193517f
VS
278 WriteBasicInfo(x,y,width,height,varname);
279 WriteLabel(phrase);
e066e256 280 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
281}
282
2193517f 283void rc2xml::ReadRect(int & x, int & y, int & width, int & height)
88d42654 284{
2193517f
VS
285 x=atoi(GetToken());
286 y=atoi(GetToken());
287 width=atoi(GetToken());
288 height=atoi(GetToken());
88d42654
VS
289}
290
2193517f 291wxString rc2xml::GetToken()
88d42654 292{
2193517f 293 wxString token="";
88d42654 294
2193517f
VS
295 if (m_rc.Eof())
296 {
297 m_done=TRUE;
298 return token;
88d42654
VS
299}
300
2193517f
VS
301 int ch=0;
302 ReadChar(ch);
303 if (ch==EOF)
304 {
305 m_done=TRUE;
306 return token;
307 }
88d42654 308
2193517f
VS
309 while (Seperator(ch))
310 {
311 ReadChar(ch);
312 if (m_done)
313 return token;
314 }
88d42654 315
2193517f
VS
316 if (ch==EOF)
317 {
318 m_done=TRUE;
319 }
88d42654
VS
320
321
2193517f
VS
322 while (!Seperator(ch))
323 {
324 token+=(char)ch;
325 ReadChar(ch);
326 }
88d42654 327
2193517f
VS
328 if (ch==EOF)
329 m_done=TRUE;
88d42654 330
2193517f 331 return token;
88d42654
VS
332}
333
2193517f 334wxString rc2xml::GetQuoteField()
88d42654 335{
2193517f
VS
336 wxString phrase;
337 //ASCII code 34 "
338 int ch=0;
339 ReadChar(ch);
88d42654 340
2193517f
VS
341 while (ch!=34)
342 ReadChar(ch);
88d42654 343
2193517f 344 ReadChar(ch);
88d42654 345
2193517f
VS
346 while (ch!=34)
347 {
348 phrase+=(char)ch;
349 ReadChar(ch);
350 }
351 return phrase;
88d42654
VS
352}
353
2193517f 354void rc2xml::ReadChar(int &ch)
88d42654 355{
2193517f
VS
356 int result;
357 result=m_rc.Tell();
88d42654 358
2193517f
VS
359 if((result>=m_filesize))
360 m_done=TRUE;
88d42654 361
2193517f 362 result=m_rc.Read(&ch,1);
88d42654 363
2193517f
VS
364 if((result==-1))
365 m_done=TRUE;
88d42654 366
2193517f
VS
367 if(ch==EOF)
368 m_done=TRUE;
88d42654
VS
369}
370
2193517f 371void rc2xml::ParseComboBox()
88d42654
VS
372{
373/* COMBOBOX IDC_SCALECOMBO,10,110,48,52,CBS_DROPDOWNLIST | CBS_SORT |
374 WS_VSCROLL | WS_TABSTOP */
2193517f
VS
375 wxString token;
376 wxString varname;
377 varname=GetToken();
378 int x,y,width,height;
379 ReadRect(x,y,width,height);
88d42654 380
e066e256 381 m_xmlfile.Write("\t\t<object class=\"wxComboBox\"");
2193517f 382 WriteBasicInfo(x,y,width,height,varname);
e066e256 383 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
384
385}
386
2193517f 387void rc2xml::ParseMenu(wxString varname)
88d42654 388{
2193517f
VS
389 wxString token="";
390
391 //Write menubar to xml file
e066e256 392 m_xmlfile.Write("\t<object class=\"wxMenuBar\"");
2193517f
VS
393 //Avoid duplicate names this way
394 varname.Replace("IDR_","MB_");
395 WriteName(varname);
396 m_xmlfile.Write(">\n");
2193517f
VS
397
398 while ((token!="BEGIN")&(token!="{"))
399 token=GetToken();
400
401 while ((token!="END")&(token!="}"))
402 {
403 token=GetToken();
404 if (token=="POPUP")
405 {
406 ParsePopupMenu();
407 }
408 }
e066e256 409 m_xmlfile.Write("\t</object>\n");
88d42654
VS
410}
411
2193517f 412void rc2xml::ParsePopupMenu()
88d42654 413{
2193517f
VS
414 static int menucount=0;
415 menucount++;
416 wxString token,name,msg,longhelp,tip;
417 token=GetQuoteField();
418
419//Remove \t because it causes problems
88d42654 420
2193517f
VS
421//spot=token.First("\\t");
422//token=token.Left(spot);
88d42654
VS
423
424//Write Menu item
425//Generate a fake name since RC menus don't have one
2193517f 426 name<<"Menu_"<<menucount;
e066e256 427 m_xmlfile.Write("\t\t<object class=\"wxMenu\"");
2193517f
VS
428 WriteName(name);
429 m_xmlfile.Write(">\n");
430 WriteLabel(token);
2193517f
VS
431
432 while ((token!="BEGIN")&(token!="{"))
433 token=GetToken();
434
435 while ((token!="END")&(token!="}"))
436 {
437 token=GetToken();
438 if (token=="POPUP")
439 ParsePopupMenu();
88d42654 440
2193517f
VS
441 if (token=="MENUITEM")
442 ParseMenuItem();
443 }
e066e256 444 m_xmlfile.Write("\t\t\t</object>\n");
88d42654
VS
445}
446
2193517f 447wxString rc2xml::PeekToken()
88d42654 448{
2193517f
VS
449 wxString token;
450 int p;
451 p=m_rc.Tell();
452 token=GetToken();
88d42654 453
2193517f
VS
454 m_rc.Seek(p);
455 return token;
88d42654
VS
456}
457//MS Windows pain in the butt CONTROL
2193517f 458void rc2xml::ParseControlMS()
88d42654 459{
2193517f
VS
460 wxString label,varname,kindctrl,token;
461 token=PeekToken();
88d42654 462
2193517f
VS
463 if (token.Contains("\""))
464 ParseNormalMSControl();
465 else
466 ParseWeirdMSControl();
88d42654
VS
467
468}
469
470/* CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH |
471 TBS_NOTICKS | WS_TABSTOP,52,73,100,15
472*/
473
2193517f 474void rc2xml::ParseSlider(wxString label, wxString varname)
88d42654 475{
2193517f
VS
476 wxString token,style;
477 ReadOrs(token);
478 if (token.Find("TBS_VERT")!=-1)
479 style+="wxSL_VERTICAL";
480 //MFC RC Default is horizontal
481 else
482 style+="wxSL_HORIZONTAL";
483
484 int x,y,width,height;
485 ReadRect(x,y,width,height);
e066e256 486 m_xmlfile.Write("\t\t<object class=\"wxSlider\"");
2193517f
VS
487 WriteBasicInfo(x,y,width,height,varname);
488 WriteStyle(style);
e066e256 489 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
490
491}
492/*
493CONTROL "Progress1",CG_IDC_PROGDLG_PROGRESS,"msctls_progress32",
494 WS_BORDER,15,52,154,13
495*/
2193517f 496void rc2xml::ParseProgressBar(wxString label, wxString varname)
88d42654 497{
2193517f
VS
498 wxString token,style;
499 ReadOrs(token);
500
501 int x,y,width,height;
502 ReadRect(x,y,width,height);
503
88d42654 504//Always horizontal in MFC
e066e256 505 m_xmlfile.Write("\t\t<object class=\"wxGauge\"");
2193517f
VS
506 WriteBasicInfo(x,y,width,height,varname);
507 WriteStyle(style);
e066e256 508 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
509}
510
2193517f 511bool rc2xml::ReadOrs(wxString & orstring)
88d42654 512{
2193517f
VS
513 wxString token;
514
515 token=PeekToken();
516 if (token.IsNumber())
517 return FALSE;
518 orstring=GetToken();
519
520 while(PeekToken()==_T("|"))
521 {
522 //Grab |
523 orstring+=GetToken();
524 //Grab next token
525 orstring+=GetToken();
526 }
527 return TRUE;
88d42654
VS
528}
529
530//Is it a check button or a radio button
2193517f 531void rc2xml::ParseCtrlButton(wxString label, wxString varname)
88d42654 532{
2193517f
VS
533 wxString token;
534 ReadOrs(token);
535 int x,y,width,height;
536
537 if (token.Find("BS_AUTOCHECKBOX")!=-1)
538 {
539 ReadRect(x,y,width,height);
e066e256 540 m_xmlfile.Write("\t\t<object class=\"wxCheckBox\"");
2193517f
VS
541 WriteBasicInfo(x,y,width,height,varname);
542 WriteLabel(label);
e066e256 543 m_xmlfile.Write("\t\t</object>\n");
2193517f
VS
544 }
545
546 if (token.Find("BS_AUTORADIOBUTTON")!=-1)
547 {
548 ReadRect(x,y,width,height);
e066e256 549 m_xmlfile.Write("\t\t<object class=\"wxRadioButton\"");
2193517f
VS
550 WriteBasicInfo(x,y,width,height,varname);
551 WriteLabel(label);
e066e256 552 m_xmlfile.Write("\t\t</object>\n");
2193517f 553 }
88d42654
VS
554
555}
556
557
2193517f 558void rc2xml::WriteSize(int width, int height)
88d42654 559{
2193517f
VS
560 wxString msg;
561 msg<<" <size>"<<width<<","<<height<<"d</size>";
562 m_xmlfile.Write(msg);
88d42654
VS
563}
564
2193517f 565void rc2xml::WritePosition(int x, int y)
88d42654 566{
2193517f
VS
567 wxString msg;
568 msg<<" <pos>"<<x<<","<<y<<"d</pos>";
569 m_xmlfile.Write(msg);
88d42654
VS
570}
571
2193517f 572void rc2xml::WriteTitle(wxString title)
88d42654 573{
2193517f
VS
574 wxString msg;
575 msg=_T("\t\t<title>"+title+"</title>\n");
576 m_xmlfile.Write(msg);
88d42654
VS
577}
578
2193517f 579void rc2xml::WriteName(wxString name)
88d42654
VS
580{
581
2193517f
VS
582//Try to convert any number ids into names
583name=LookUpId(name);
88d42654
VS
584//Replace common MS ids with wxWindows ids
585//I didn't do everyone of them
2193517f
VS
586 if (name=="IDOK")
587 name="wxID_OK";
588 else if (name=="IDCANCEL")
589 name="wxID_CANCEL";
590 else if (name=="IDAPPLY")
591 name="wxID_APPLY";
592 else if (name=="ID_FILE_OPEN")
593 name="wxID_OPEN";
594 else if (name=="ID_FILE_CLOSE")
595 name="wxID_CLOSE";
596 else if (name=="ID_FILE_SAVE")
597 name="wxID_SAVE";
598 else if (name=="ID_FILE_SAVE_AS")
599 name="wxID_SAVEAS";
600 else if (name=="ID_APP_EXIT")
601 name="wxID_EXIT";
602 else if (name=="ID_FILE_PRINT")
603 name="wxID_PRINT";
604 else if (name=="ID_FILE_PRINT_PREVIEW")
605 name="wxID_PREVIEW";
606 else if (name=="ID_FILE_PRINT_SETUP")
607 name="wxID_PRINT_SETUP";
608 else if (name=="ID_APP_ABOUT")
609 name="wxID_ABOUT";
610 else if (name=="ID_EDIT_UNDO")
611 name="wxID_UNDO";
612 else if (name=="ID_EDIT_CUT")
613 name="wxID_CUT";
614 else if (name=="ID_EDIT_COPY")
615 name="wxID_COPY";
616 else if (name=="ID_EDIT_PASTE")
617 name="wxID_PASTE";
618
619 m_xmlfile.Write(" name= \""+name+"\"");
88d42654
VS
620}
621
2193517f 622void rc2xml::WriteLabel(wxString label)
88d42654 623{
2193517f
VS
624 label.Replace("&","$");
625 m_xmlfile.Write("\t\t\t<label>"+label+"</label>\n");
88d42654
VS
626}
627
2193517f 628void rc2xml::WriteBasicInfo(int x, int y, int width, int height, wxString name)
88d42654 629{
2193517f
VS
630 WriteName(name);
631 m_xmlfile.Write(">\n");
632 m_xmlfile.Write("\t\t\t");
633 WritePosition(x,y);
634 WriteSize(width,height);
635 m_xmlfile.Write("\n");
88d42654
VS
636}
637
2193517f 638void rc2xml::WriteStyle(wxString style)
88d42654 639{
2193517f
VS
640 if (style.Length()==0)
641 return;
642 m_xmlfile.Write("\n\t\t<style>"+style+"</style>\n");
88d42654
VS
643}
644/*
645 LISTBOX IDC_LIST1,16,89,48,40,LBS_SORT | LBS_MULTIPLESEL |
646 LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
647*/
2193517f 648void rc2xml::ParseListBox()
88d42654 649{
2193517f
VS
650 wxString token;
651 wxString varname;
652 varname=GetToken();
653 int x,y,width,height;
654 ReadRect(x,y,width,height);
88d42654 655
e066e256 656 m_xmlfile.Write("\t\t<object class=\"wxListBox\"");
2193517f 657 WriteBasicInfo(x,y,width,height,varname);
e066e256 658 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
659
660}
661/*
662 CONTROL "",IDC_RICHEDIT1,"RICHEDIT",ES_AUTOHSCROLL | WS_BORDER |
663 WS_TABSTOP,103,110,40,14
664*/
2193517f 665void rc2xml::ParseRichEdit(wxString label, wxString varname)
88d42654 666{
2193517f
VS
667 wxString token;
668 //while (ReadOrs(token));
669 ReadOrs(token);
670 int x,y,width,height;
671 ReadRect(x,y,width,height);
672 wxString style;
88d42654 673//Make it a rich text control
2193517f 674 style+="wxTE_MULTILINE ";
e066e256 675 m_xmlfile.Write("\t\t<object class=\"wxTextCtrl\"");
2193517f
VS
676 WriteBasicInfo(x,y,width,height,varname);
677 WriteStyle(style);
e066e256 678 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
679
680}
681/*
682CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_ARROWKEYS,209,72,
683 19,26
684*/
2193517f 685void rc2xml::ParseSpinCtrl(wxString label, wxString varname)
88d42654 686{
2193517f
VS
687 wxString token,style;
688
689 ReadOrs(token);
690 if (token.Find("UDS_HORZ")!=-1)
691 style="wxSP_HORIZONTAL";
692 //MFC default
693 else
694 style="wxSP_VERTICAL";
695
696 int x,y,width,height;
697 ReadRect(x,y,width,height);
e066e256 698 m_xmlfile.Write("\t\t<object class=\"wxSpinButton\"");
2193517f
VS
699 WriteBasicInfo(x,y,width,height,varname);
700 WriteStyle(style);
e066e256 701 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
702
703}
704
2193517f 705void rc2xml::FirstPass()
88d42654 706{
2193517f
VS
707 wxString token,prevtok;
708 while (!m_done)
709 {
710 token=GetToken();
711 if (token=="BITMAP")
712 ParseBitmap(prevtok);
713 else if (token=="STRINGTABLE")
714 ParseStringTable(prevtok);
715 else if (token=="ICON")
716 ParseIcon(prevtok);
717
718 prevtok=token;
719 }
88d42654
VS
720}
721
2193517f 722void rc2xml::ParseBitmap(wxString varname)
88d42654 723{
2193517f
VS
724 wxString token,*bitmapfile;
725
726 token=PeekToken();
727 //Microsoft notation?
728 if (token=="DISCARDABLE")
729 {
730 token=GetToken();
731 token=PeekToken();
732 }
733 bitmapfile=new wxString;
734 *bitmapfile=GetQuoteField();
735 m_bitmaplist->Append(varname,bitmapfile);
88d42654
VS
736
737}
738
739
2193517f 740void rc2xml::SecondPass()
88d42654 741{
2193517f
VS
742 wxString token,prevtok;
743 while (!m_done)
744 {
745 token=GetToken();
746 if (token=="DIALOG")
747 ParseDialog(prevtok);
748 else if (token=="MENU")
749 ParseMenu(prevtok);
750 else if (token=="TOOLBAR")
751 ParseToolBar(prevtok);
752
753 prevtok=token;
754 }
88d42654
VS
755
756}
757
2193517f 758void rc2xml::ParseToolBar(wxString varname)
88d42654 759{
2193517f
VS
760 wxString token;
761 token=GetToken();
762 wxASSERT_MSG(token=="DISCARDABLE","Error in toolbar parsing");
88d42654 763//Look up bitmap for toolbar and load
2193517f
VS
764 wxNode *node=m_bitmaplist->Find(LookUpId(varname));
765 wxString *bitmappath;
766 bitmappath=(wxString *)node->Data();
767 wxBitmap bitmap;
768 if (!bitmap.LoadFile(*bitmappath,wxBITMAP_TYPE_BMP ))
769 wxLogError("Unable to load bitmap:"+*bitmappath);
88d42654
VS
770
771//Write toolbar to xml file
e066e256 772 m_xmlfile.Write(" <object class=\"wxToolBar\"");
88d42654 773//Avoid duplicate names this way
2193517f
VS
774 varname.Replace("IDR_","TB_");
775 WriteName(varname);
776 m_xmlfile.Write(">\n");
777 wxString style;
778 style+="wxTB_FLAT";
779 WriteStyle(style);
88d42654 780
88d42654
VS
781
782//Grab width and height
2193517f
VS
783 int width,height;
784 width=atoi(GetToken());
785 height=atoi(GetToken());
786
787 int c=0;
788 wxString buttonname,msg,tip,longhelp;
789 token=GetToken();
790 while ((token!="BEGIN"))
791 token=GetToken();
792
793 while ((token!="END")&(token!="}"))
794 {
795 if (token=="BUTTON")
796 {
797 buttonname=GetToken();
e066e256 798 m_xmlfile.Write("\t\t\t<object class=\"tool\"");
2193517f
VS
799 WriteName(buttonname);
800 m_xmlfile.Write(">\n");
801 //Write tool tip if any
802 if (LookUpString(buttonname,msg))
803 {
804 SplitHelp(msg,tip,longhelp);
805 m_xmlfile.Write("\t\t\t\t<tooltip>"+tip+"</tooltip>\n");
806 m_xmlfile.Write(" <longhelp>"+longhelp+"</longhelp>\n");
807 }
808 //Make a bitmap file name
809 buttonname=CleanName(buttonname);
810 buttonname+=".bmp";
811 m_xmlfile.Write("\t\t\t\t<bitmap>"+buttonname+"</bitmap>\n");
812 WriteToolButton(buttonname,c,width,height,bitmap);
e066e256 813 m_xmlfile.Write("\t\t\t</object>\n");
2193517f
VS
814 c++;
815 }
816 else if (token=="SEPARATOR")
817 {
e066e256 818 m_xmlfile.Write("\t\t\t<object class=\"separator\"/>\n");
2193517f
VS
819 }
820 token=GetToken();
821 }
e066e256 822 m_xmlfile.Write("\t</object>\n");
88d42654
VS
823}
824
825//Extract bitmaps from larger toolbar bitmap
2193517f 826void rc2xml::WriteToolButton(wxString name,int index, int width, int height, wxBitmap bitmap)
88d42654 827{
2193517f
VS
828 int x;
829 x=index*width;
830 wxRect r(x,0,width,height);
831 wxBitmap little;
832 little=bitmap.GetSubBitmap(r);
2c99715a 833 little.SaveFile(m_targetpath+name,wxBITMAP_TYPE_BMP);
88d42654
VS
834}
835
2193517f 836void rc2xml::ParseStringTable(wxString varname)
88d42654 837{
2193517f
VS
838 wxString token;
839 token=GetToken();
840 while ((token!="BEGIN"))
841 token=GetToken();
842 token=GetToken();
843 wxString *msg;
844
845 while ((token!="END")&(token!="}"))
846 {
847 msg=new wxString;
848 *msg=GetQuoteField();
849 m_stringtable->Append(token,msg);
850 token=GetToken();
851 }
88d42654
VS
852
853}
854
2193517f 855bool rc2xml::LookUpString(wxString strid,wxString & st)
88d42654 856{
2193517f
VS
857 wxNode *node=m_stringtable->Find(strid);
858 wxString *s;
859 if (node==NULL)
860 return FALSE;
88d42654 861
2193517f
VS
862 s=(wxString *)node->Data();
863 st=*s;
88d42654 864
2193517f 865 return TRUE;
88d42654
VS
866}
867
2193517f 868bool rc2xml::SplitHelp(wxString msg, wxString &shorthelp, wxString &longhelp)
88d42654 869{
2193517f
VS
870 int spot;
871 spot=msg.Find("\\n");
872 if (spot==-1)
873 {
874 shorthelp=msg;
875 longhelp=msg;
876 }
877
878 longhelp=msg.Left(spot);
879 spot=msg.Length()-spot-2;
880 shorthelp=msg.Right(spot);
881 return TRUE;
88d42654
VS
882}
883
2193517f 884void rc2xml::ParseMenuItem()
88d42654 885{
2193517f
VS
886 wxString token,name,msg,tip,longhelp;
887//int spot;
888 if (PeekToken()=="SEPARATOR")
889 {
e066e256 890 m_xmlfile.Write("\t\t\t<object class=\"separator\"/>\n");
2193517f
VS
891 return;
892 }
893
894 token=GetQuoteField();
895 name=GetToken();
896//Remove \t because it causes problems
897//spot=token.First("\\t");
898//token=token.Left(spot);
e066e256 899 m_xmlfile.Write("\t\t\t<object class=\"wxMenuItem\"");
2193517f
VS
900 WriteName(name);
901 m_xmlfile.Write(">\n");
902 WriteLabel(token);
88d42654 903//Look up help if any listed in stringtable
2193517f
VS
904 if (LookUpString(name,msg))
905 {
906 SplitHelp(msg,tip,longhelp);
907 m_xmlfile.Write("\t\t\t<help>"
908 +longhelp+"</help>\n");
909 }
88d42654 910//look for extra attributes like checked and break
2193517f
VS
911 wxString ptoken;
912 ptoken=PeekToken();
913 while ((ptoken!="MENUITEM")&(ptoken!="POPUP")&(ptoken!="END"))
914 {
915 token=GetToken();
916 if (token=="CHECKED")
917 m_xmlfile.Write("\t\t\t<checkable>1</checkable>\n");
918 else if (token=="MENUBREAK");
919//m_xmlfile.Write("\t\t\t</break>\n");
920 else if (token=="GRAYED");
921 else
922 wxLogError("Unknown Menu Item token:"+token);
923
924 ptoken=PeekToken();
925 }
e066e256 926 m_xmlfile.Write("\t\t\t</object>\n");
88d42654
VS
927
928}
929
930//ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
2193517f 931void rc2xml::ParseIconStatic()
88d42654 932{
2193517f
VS
933 wxString token;
934 wxString varname,iconname;
935 iconname=GetToken();
88d42654 936//Look up icon
2193517f 937 varname=GetToken();
88d42654 938
2193517f
VS
939 int x,y,width,height;
940 ReadRect(x,y,width,height);
88d42654 941
e066e256 942 m_xmlfile.Write("\t\t<object class=\"wxStaticBitmap\"");
2193517f 943 WriteBasicInfo(x,y,width,height,varname);
88d42654 944//Save icon as a bitmap
2193517f 945 WriteIcon(iconname);
e066e256 946 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
947
948}
949//IDR_MAINFRAME ICON DISCARDABLE "res\\mfcexample.ico"
2193517f 950void rc2xml::ParseIcon(wxString varname)
88d42654 951{
2193517f
VS
952 wxString token,*iconfile;
953 iconfile=new wxString;
954 token=PeekToken();
88d42654 955
2193517f
VS
956 *iconfile=GetQuoteField();
957 m_iconlist->Append(varname,iconfile);
958
88d42654
VS
959
960}
961
2193517f 962wxString rc2xml::CleanName(wxString name)
88d42654 963{
2193517f
VS
964 name.MakeLower();
965 name.Replace("id_","");
966 name.Replace("idr_","");
967 name.Replace("idb_","");
968 name.Replace("idc_","");
2c99715a
VS
969 name.Replace(".ico","");
970 name.Replace(".bmp","");
2193517f 971 return name;
88d42654
VS
972}
973// And the award for most messed up control goes to...
974// CONTROL IDB_FACE,IDC_STATIC,"Static",SS_BITMAP,26,62,32,30
2193517f 975void rc2xml::ParseStaticBitmap(wxString bitmapname, wxString varname)
88d42654 976{
2193517f
VS
977 wxString token;
978 //Grab SS_BITMAP
979 token=GetToken();
980
88d42654 981
88d42654 982
2193517f
VS
983 int x,y,width,height;
984 ReadRect(x,y,width,height);
985
e066e256 986 m_xmlfile.Write("\t\t<object class=\"wxStaticBitmap\"");
2193517f
VS
987 WriteBasicInfo(x,y,width,height,varname);
988 WriteBitmap(bitmapname);
e066e256 989 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
990
991}
992
2193517f 993void rc2xml::ParseNormalMSControl()
88d42654
VS
994{
995wxString label,varname,kindctrl;
996
997label=GetQuoteField();
998varname=GetToken();
999kindctrl=GetQuoteField();
1000kindctrl.MakeUpper();
1001
2193517f
VS
1002 if (kindctrl=="MSCTLS_UPDOWN32")
1003 ParseSpinCtrl(label,varname);
1004 if (kindctrl=="MSCTLS_TRACKBAR32")
1005 ParseSlider(label,varname);
1006 if (kindctrl=="MSCTLS_PROGRESS32")
1007 ParseProgressBar(label,varname);
1008 if (kindctrl=="SYSTREEVIEW32")
1009 ParseTreeCtrl(label,varname);
1010 if (kindctrl=="SYSMONTHCAL32")
1011 ParseCalendar(label,varname);
1012 if (kindctrl=="SYSLISTVIEW32")
1013 ParseListCtrl(label,varname);
1014 if (kindctrl=="BUTTON")
1015 ParseCtrlButton(label,varname);
1016 if (kindctrl=="RICHEDIT")
1017 ParseRichEdit(label,varname);
88d42654
VS
1018
1019}
1020
2193517f 1021void rc2xml::ParseWeirdMSControl()
88d42654 1022{
2193517f
VS
1023 wxString kindctrl;
1024 wxString varname;
1025 wxString id;
1026 id=GetToken();
1027 varname=GetToken();
1028 kindctrl=GetQuoteField();
1029 kindctrl.MakeUpper();
88d42654 1030// CONTROL IDB_FACE,IDC_STATIC,"Static",SS_BITMAP,26,62,32,30
2193517f
VS
1031 if (kindctrl=="STATIC")
1032 {
1033 if (PeekToken()=="SS_BITMAP")
1034 ParseStaticBitmap(id,varname);
1035 else
1036 wxLogError("Unknown MS Control Static token");
1037 }
88d42654
VS
1038
1039}
1040//SCROLLBAR IDC_SCROLLBAR1,219,56,10,40,SBS_VERT
1041
2193517f 1042void rc2xml::ParseScrollBar()
88d42654 1043{
2193517f
VS
1044 wxString token;
1045 wxString varname;
1046
1047 varname=GetToken();
1048 int x,y,width,height;
1049 ReadRect(x,y,width,height);
1050 wxString style;
1051
1052 ReadOrs(token);
1053
1054if (token.Find("SBS_VERT")!=-1)
1055 style=_T("wxSB_VERTICAL");
88d42654 1056//Default MFC style is horizontal
2193517f
VS
1057 else
1058 style=_T("wxSB_HORIZONTAL");
88d42654 1059
e066e256 1060 m_xmlfile.Write("\t\t<object class=\"wxScrollBar\"");
2193517f
VS
1061 WriteBasicInfo(x,y,width,height,varname);
1062 WriteStyle(style);
e066e256 1063 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
1064
1065}
1066// CONTROL "Tree1",IDC_TREE1,"SysTreeView32",WS_BORDER | WS_TABSTOP,
1067// 7,7,66,61
1068
2193517f 1069void rc2xml::ParseTreeCtrl(wxString label, wxString varname)
88d42654 1070{
2193517f
VS
1071 wxString token;
1072//while (ReadOrs(token));
1073 ReadOrs(token);
1074 int x,y,width,height;
1075 ReadRect(x,y,width,height);
e066e256 1076 m_xmlfile.Write("\t\t<object class=\"wxTreeCtrl\"");
2193517f 1077 WriteBasicInfo(x,y,width,height,varname);
e066e256 1078 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
1079
1080}
1081// CONTROL "MonthCalendar1",IDC_MONTHCALENDAR1,"SysMonthCal32",
1082 //MCS_NOTODAY | WS_TABSTOP,105,71,129,89
1083
2193517f 1084void rc2xml::ParseCalendar(wxString label, wxString varname)
88d42654 1085{
2193517f
VS
1086 wxString token;
1087//while (ReadOrs(token));
1088 ReadOrs(token);
1089 int x,y,width,height;
1090 ReadRect(x,y,width,height);
e066e256 1091 m_xmlfile.Write("\t\t<object class=\"wxCalendarCtrl\"");
2193517f 1092 WriteBasicInfo(x,y,width,height,varname);
e066e256 1093 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
1094}
1095// CONTROL "List1",IDC_LIST1,"SysListView32",WS_BORDER | WS_TABSTOP,
1096 // 7,89,68,71
1097
2193517f 1098void rc2xml::ParseListCtrl(wxString label, wxString varname)
88d42654 1099{
2193517f
VS
1100 wxString token;
1101 //while (ReadOrs(token));
1102 ReadOrs(token);
1103 int x,y,width,height;
1104 ReadRect(x,y,width,height);
e066e256 1105 m_xmlfile.Write("\t\t<object class=\"wxListCtrl\"");
2193517f 1106 WriteBasicInfo(x,y,width,height,varname);
e066e256 1107 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
1108
1109}
2193517f
VS
1110
1111void rc2xml::WriteBitmap(wxString bitmapname)
1112{
1113//Look up bitmap
1114 wxNode *node=m_bitmaplist->Find(LookUpId(bitmapname));
1115 if (node==NULL)
1116 {
1117 m_xmlfile.Write("\t\t\t<bitmap>missingfile</bitmap>\n");
1118 wxLogError("Unable to find bitmap:"+bitmapname);
1119 return;
1120 }
1121
1122 wxString *bitmappath;
1123 bitmappath=(wxString *)node->Data();
2c99715a 1124 bitmapname=wxFileNameFromPath(*bitmappath);
2193517f
VS
1125 wxBitmap bitmap;
1126 if (!bitmap.LoadFile(*bitmappath,wxBITMAP_TYPE_BMP ))
1127 wxLogError("Unable to load bitmap:"+*bitmappath);
1128
1129 //Make a bitmap file name
1130 bitmapname=CleanName(bitmapname);
1131 bitmapname+=".bmp";
1132 m_xmlfile.Write("\t\t\t<bitmap>"+bitmapname+"</bitmap>\n");
2c99715a 1133 bitmap.SaveFile(m_targetpath+bitmapname,wxBITMAP_TYPE_BMP);
2193517f
VS
1134}
1135
1136void rc2xml::WriteIcon(wxString iconname)
1137{
1138wxNode *node=m_iconlist->Find(iconname);
1139 if (node==NULL)
1140 {
1141 m_xmlfile.Write("\t\t\t<bitmap>missing_file</bitmap>\n");
1142 wxLogError("Unable to find icon:"+iconname);
1143 }
1144 wxString *iconpath;
1145 iconpath=(wxString *)node->Data();
1146 wxIcon icon;
1147 wxBitmap bitmap;
1148 if (!icon.LoadFile(*iconpath,wxBITMAP_TYPE_ICO ))
1149 wxLogError("Unable to load icon:"+*iconpath);
1150#ifdef __WXMSW__
1151 bitmap.CopyFromIcon(icon);
1152#else
1153 bitmap = icon;
1154#endif
2c99715a 1155 iconname=wxFileNameFromPath(*iconpath);
2193517f
VS
1156 //Make a bitmap file name
1157 iconname=CleanName(iconname);
1158 iconname+=".bmp";
1159 m_xmlfile.Write("\t\t\t<bitmap>"+iconname+"</bitmap>\n");
2c99715a 1160 bitmap.SaveFile(m_targetpath+iconname,wxBITMAP_TYPE_BMP);
2193517f
VS
1161
1162
1163}
1164/*Unfortunately sometimes the great MSVC Resource editor decides
1165to use numbers instead of the word id. I have no idea why they
1166do this, but that is the way it is.
1167*/
1168/* this is a quick and dirty way to parse the resource.h file
1169it will not recognize #ifdef so it can be easily fooled
1170*/
1171void rc2xml::ParseResourceHeader()
1172{
1173wxTextFile r;
1174//Attempt to load resource.h in current path
1175 if (!r.Open("resource.h"))
1176 {
1177 wxLogError("Warining Unable to load resource.h file");
1178 return;
1179 }
1180
1181 wxString str;
1182 wxString id,v;
1183 wxStringTokenizer tok;
1184 wxString *varname;
1185
1186
1187 long n;
1188
1189//Read through entire file
1190 for ( str = r.GetFirstLine(); !r.Eof(); str = r.GetNextLine() )
1191 {
1192 if (str.Find("#define")!=-1)
1193 {
1194 tok.SetString(str);
1195 //Just ignore #define token
1196 tok.GetNextToken();
1197 v=tok.GetNextToken();
1198 id=tok.GetNextToken();
1199 if (id.IsNumber())
1200 {
1201 varname=new wxString;
1202 id.ToLong(&n);
1203 *varname=v;
1204 m_resourcelist->Append(n,varname);
1205 }
1206 }
1207 }
1208
1209
1210
1211}
1212
1213
1214wxString rc2xml::LookUpId(wxString id)
1215{
1216wxString st;
1217
1218if (!id.IsNumber())
1219 return id;
1220long n;
1221id.ToLong(&n);
1222wxNode *node=m_resourcelist->Find(n);
1223 wxString *s;
1224 if (node==NULL)
1225 return id;
1226
1227 s=(wxString *)node->Data();
1228 st=*s;
1229return st;
1230}