]> git.saurik.com Git - wxWidgets.git/blame_incremental - contrib/utils/convertrc/rc2xml.cpp
Added wxDbTable::SetOrderByColNums() function
[wxWidgets.git] / contrib / utils / convertrc / rc2xml.cpp
... / ...
CommitLineData
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
23// For compilers that support precompilation, includes "wx/wx.h".
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
36
37#include "rc2xml.h"
38#include "wx/image.h"
39#include "wx/resource.h"
40#include <wx/textfile.h>
41#include <wx/tokenzr.h>
42
43
44
45//////////////////////////////////////////////////////////////////////
46// Construction/Destruction
47//////////////////////////////////////////////////////////////////////
48
49rc2xml::rc2xml()
50{
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);
56}
57
58rc2xml::~rc2xml()
59{
60 delete m_bitmaplist;
61 delete m_stringtable;
62 delete m_iconlist;
63 delete m_resourcelist;
64}
65
66bool rc2xml::Convert(wxString rcfile, wxString xmlfile)
67{
68 m_rc.Open(rcfile.c_str());
69 m_filesize=m_rc.Length();
70
71 m_workingpath=wxPathOnly(rcfile);
72 m_targetpath=wxPathOnly(xmlfile)+"\\";
73
74 wxSetWorkingDirectory(m_workingpath);
75
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;
81
82
83/* Write Basic header for XML file */
84 m_xmlfile.Write("<?xml version=\"1.0\" ?>\n");
85 m_xmlfile.Write("<resource>\n");
86
87//Read resource.h
88 ParseResourceHeader();
89//Gather all the resource we need for toolbars,menus, and etc
90 FirstPass();
91 m_done=FALSE;
92 m_rc.Seek(0);
93//Read in dialogs, toolbars,menus
94 SecondPass();
95
96 m_xmlfile.Write("</resource>\n");
97 m_xmlfile.Close();
98 m_rc.Close();
99
100return TRUE;
101}
102
103
104void rc2xml::ParseDialog(wxString dlgname)
105{
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;
122
123//Record x,y,width,height
124 int x,y,width,height;
125 ReadRect(x,y,width,height);
126//Get Title
127 token=GetToken();
128 wxString title;
129 wxString ptsize,face;
130
131 m_xmlfile.Write("\t<object class=\"wxDialog\"");
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 }
159
160 ParseControls();
161 m_xmlfile.Write("\t</object>\n");
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*/
172void rc2xml::ParseControls()
173{
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 }
201
202}
203//LTEXT "Radius",IDC_STATIC,9,67,23,8
204void rc2xml::ParseStaticText()
205{
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);
212
213 m_xmlfile.Write("\t\t<object class=\"wxStaticText\"");
214 WriteBasicInfo(x,y,width,height,varname);WriteLabel(phrase);
215 m_xmlfile.Write("\t\t</object>\n");
216
217}
218//EDITTEXT IDC_RADIUS,36,65,40,14,ES_AUTOHSCROLL
219void rc2xml::ParseTextCtrl()
220{
221 wxString token;
222 wxString varname,style;
223 varname=GetToken();
224 int x,y,width,height;
225 ReadRect(x,y,width,height);
226//TODO
227//style=GetToken();
228 m_xmlfile.Write("\t\t<object class\"wxTextCtrl\"");
229 WriteBasicInfo(x,y,width,height,varname);
230 m_xmlfile.Write("\t\t</object>\n");
231
232}
233//PUSHBUTTON "Create/Update",IDC_CREATE,15,25,53,13,NOT WS_TABSTOP
234void rc2xml::ParsePushButton()
235{
236 wxString token;
237 wxString phrase,varname;
238 phrase=GetQuoteField();
239 varname=GetToken();
240
241 int x,y,width,height;
242 ReadRect(x,y,width,height);
243
244 m_xmlfile.Write("\t\t<object class=\"wxButton\"");
245 WriteBasicInfo(x,y,width,height,varname);
246 WriteLabel(phrase);
247 m_xmlfile.Write("\t\t</object>\n");
248
249}
250
251
252bool rc2xml::Seperator(int ch)
253{
254//if ((ch==' ')|(ch==',')|(ch==13)|(ch==10)|(ch=='|')|(ch=='\t'))
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;
265}
266
267void rc2xml::ParseGroupBox()
268{
269// GROUPBOX "Rotate",IDC_STATIC,1,1,71,79
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
277 m_xmlfile.Write("\t\t<object class=\"wxStaticBox\"");
278 WriteBasicInfo(x,y,width,height,varname);
279 WriteLabel(phrase);
280 m_xmlfile.Write("\t\t</object>\n");
281}
282
283void rc2xml::ReadRect(int & x, int & y, int & width, int & height)
284{
285 x=atoi(GetToken());
286 y=atoi(GetToken());
287 width=atoi(GetToken());
288 height=atoi(GetToken());
289}
290
291wxString rc2xml::GetToken()
292{
293 wxString token="";
294
295 if (m_rc.Eof())
296 {
297 m_done=TRUE;
298 return token;
299}
300
301 int ch=0;
302 ReadChar(ch);
303 if (ch==EOF)
304 {
305 m_done=TRUE;
306 return token;
307 }
308
309 while (Seperator(ch))
310 {
311 ReadChar(ch);
312 if (m_done)
313 return token;
314 }
315
316 if (ch==EOF)
317 {
318 m_done=TRUE;
319 }
320
321
322 while (!Seperator(ch))
323 {
324 token+=(char)ch;
325 ReadChar(ch);
326 }
327
328 if (ch==EOF)
329 m_done=TRUE;
330
331 return token;
332}
333
334wxString rc2xml::GetQuoteField()
335{
336 wxString phrase;
337 //ASCII code 34 "
338 int ch=0;
339 ReadChar(ch);
340
341 while (ch!=34)
342 ReadChar(ch);
343
344 ReadChar(ch);
345
346 while (ch!=34)
347 {
348 phrase+=(char)ch;
349 ReadChar(ch);
350 }
351 return phrase;
352}
353
354void rc2xml::ReadChar(int &ch)
355{
356 int result;
357 result=m_rc.Tell();
358
359 if((result>=m_filesize))
360 m_done=TRUE;
361
362 result=m_rc.Read(&ch,1);
363
364 if((result==-1))
365 m_done=TRUE;
366
367 if(ch==EOF)
368 m_done=TRUE;
369}
370
371void rc2xml::ParseComboBox()
372{
373/* COMBOBOX IDC_SCALECOMBO,10,110,48,52,CBS_DROPDOWNLIST | CBS_SORT |
374 WS_VSCROLL | WS_TABSTOP */
375 wxString token;
376 wxString varname;
377 varname=GetToken();
378 int x,y,width,height;
379 ReadRect(x,y,width,height);
380
381 m_xmlfile.Write("\t\t<object class=\"wxComboBox\"");
382 WriteBasicInfo(x,y,width,height,varname);
383 m_xmlfile.Write("\n\t\t</object>\n");
384
385}
386
387void rc2xml::ParseMenu(wxString varname)
388{
389 wxString token="";
390
391 //Write menubar to xml file
392 m_xmlfile.Write("\t<object class=\"wxMenuBar\"");
393 //Avoid duplicate names this way
394 varname.Replace("IDR_","MB_");
395 WriteName(varname);
396 m_xmlfile.Write(">\n");
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 }
409 m_xmlfile.Write("\t</object>\n");
410}
411
412void rc2xml::ParsePopupMenu()
413{
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
420
421//spot=token.First("\\t");
422//token=token.Left(spot);
423
424//Write Menu item
425//Generate a fake name since RC menus don't have one
426 name<<"Menu_"<<menucount;
427 m_xmlfile.Write("\t\t<object class=\"wxMenu\"");
428 WriteName(name);
429 m_xmlfile.Write(">\n");
430 WriteLabel(token);
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();
440
441 if (token=="MENUITEM")
442 ParseMenuItem();
443 }
444 m_xmlfile.Write("\t\t\t</object>\n");
445}
446
447wxString rc2xml::PeekToken()
448{
449 wxString token;
450 int p;
451 p=m_rc.Tell();
452 token=GetToken();
453
454 m_rc.Seek(p);
455 return token;
456}
457//MS Windows pain in the butt CONTROL
458void rc2xml::ParseControlMS()
459{
460 wxString label,varname,kindctrl,token;
461 token=PeekToken();
462
463 if (token.Contains("\""))
464 ParseNormalMSControl();
465 else
466 ParseWeirdMSControl();
467
468}
469
470/* CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH |
471 TBS_NOTICKS | WS_TABSTOP,52,73,100,15
472*/
473
474void rc2xml::ParseSlider(wxString label, wxString varname)
475{
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);
486 m_xmlfile.Write("\t\t<object class=\"wxSlider\"");
487 WriteBasicInfo(x,y,width,height,varname);
488 WriteStyle(style);
489 m_xmlfile.Write("\n\t\t</object>\n");
490
491}
492/*
493CONTROL "Progress1",CG_IDC_PROGDLG_PROGRESS,"msctls_progress32",
494 WS_BORDER,15,52,154,13
495*/
496void rc2xml::ParseProgressBar(wxString label, wxString varname)
497{
498 wxString token,style;
499 ReadOrs(token);
500
501 int x,y,width,height;
502 ReadRect(x,y,width,height);
503
504//Always horizontal in MFC
505 m_xmlfile.Write("\t\t<object class=\"wxGauge\"");
506 WriteBasicInfo(x,y,width,height,varname);
507 WriteStyle(style);
508 m_xmlfile.Write("\t\t</object>\n");
509}
510
511bool rc2xml::ReadOrs(wxString & orstring)
512{
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;
528}
529
530//Is it a check button or a radio button
531void rc2xml::ParseCtrlButton(wxString label, wxString varname)
532{
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);
540 m_xmlfile.Write("\t\t<object class=\"wxCheckBox\"");
541 WriteBasicInfo(x,y,width,height,varname);
542 WriteLabel(label);
543 m_xmlfile.Write("\t\t</object>\n");
544 }
545
546 if (token.Find("BS_AUTORADIOBUTTON")!=-1)
547 {
548 ReadRect(x,y,width,height);
549 m_xmlfile.Write("\t\t<object class=\"wxRadioButton\"");
550 WriteBasicInfo(x,y,width,height,varname);
551 WriteLabel(label);
552 m_xmlfile.Write("\t\t</object>\n");
553 }
554
555}
556
557
558void rc2xml::WriteSize(int width, int height)
559{
560 wxString msg;
561 msg<<" <size>"<<width<<","<<height<<"d</size>";
562 m_xmlfile.Write(msg);
563}
564
565void rc2xml::WritePosition(int x, int y)
566{
567 wxString msg;
568 msg<<" <pos>"<<x<<","<<y<<"d</pos>";
569 m_xmlfile.Write(msg);
570}
571
572void rc2xml::WriteTitle(wxString title)
573{
574 wxString msg;
575 msg=_T("\t\t<title>"+title+"</title>\n");
576 m_xmlfile.Write(msg);
577}
578
579void rc2xml::WriteName(wxString name)
580{
581
582//Try to convert any number ids into names
583name=LookUpId(name);
584//Replace common MS ids with wxWindows ids
585//I didn't do everyone of them
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+"\"");
620}
621
622void rc2xml::WriteLabel(wxString label)
623{
624 label.Replace("&","$");
625 m_xmlfile.Write("\t\t\t<label>"+label+"</label>\n");
626}
627
628void rc2xml::WriteBasicInfo(int x, int y, int width, int height, wxString name)
629{
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");
636}
637
638void rc2xml::WriteStyle(wxString style)
639{
640 if (style.Length()==0)
641 return;
642 m_xmlfile.Write("\n\t\t<style>"+style+"</style>\n");
643}
644/*
645 LISTBOX IDC_LIST1,16,89,48,40,LBS_SORT | LBS_MULTIPLESEL |
646 LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
647*/
648void rc2xml::ParseListBox()
649{
650 wxString token;
651 wxString varname;
652 varname=GetToken();
653 int x,y,width,height;
654 ReadRect(x,y,width,height);
655
656 m_xmlfile.Write("\t\t<object class=\"wxListBox\"");
657 WriteBasicInfo(x,y,width,height,varname);
658 m_xmlfile.Write("\n\t\t</object>\n");
659
660}
661/*
662 CONTROL "",IDC_RICHEDIT1,"RICHEDIT",ES_AUTOHSCROLL | WS_BORDER |
663 WS_TABSTOP,103,110,40,14
664*/
665void rc2xml::ParseRichEdit(wxString label, wxString varname)
666{
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;
673//Make it a rich text control
674 style+="wxTE_MULTILINE ";
675 m_xmlfile.Write("\t\t<object class=\"wxTextCtrl\"");
676 WriteBasicInfo(x,y,width,height,varname);
677 WriteStyle(style);
678 m_xmlfile.Write("\t\t</object>\n");
679
680}
681/*
682CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_ARROWKEYS,209,72,
683 19,26
684*/
685void rc2xml::ParseSpinCtrl(wxString label, wxString varname)
686{
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);
698 m_xmlfile.Write("\t\t<object class=\"wxSpinButton\"");
699 WriteBasicInfo(x,y,width,height,varname);
700 WriteStyle(style);
701 m_xmlfile.Write("\n\t\t</object>\n");
702
703}
704
705void rc2xml::FirstPass()
706{
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 }
720}
721
722void rc2xml::ParseBitmap(wxString varname)
723{
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);
736
737}
738
739
740void rc2xml::SecondPass()
741{
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 }
755
756}
757
758void rc2xml::ParseToolBar(wxString varname)
759{
760 wxString token;
761 token=GetToken();
762 wxASSERT_MSG(token=="DISCARDABLE","Error in toolbar parsing");
763//Look up bitmap for toolbar and load
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);
770
771//Write toolbar to xml file
772 m_xmlfile.Write(" <object class=\"wxToolBar\"");
773//Avoid duplicate names this way
774 varname.Replace("IDR_","TB_");
775 WriteName(varname);
776 m_xmlfile.Write(">\n");
777 wxString style;
778 style+="wxTB_FLAT";
779 WriteStyle(style);
780
781
782//Grab width and height
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();
798 m_xmlfile.Write("\t\t\t<object class=\"tool\"");
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);
813 m_xmlfile.Write("\t\t\t</object>\n");
814 c++;
815 }
816 else if (token=="SEPARATOR")
817 {
818 m_xmlfile.Write("\t\t\t<object class=\"separator\"/>\n");
819 }
820 token=GetToken();
821 }
822 m_xmlfile.Write("\t</object>\n");
823}
824
825//Extract bitmaps from larger toolbar bitmap
826void rc2xml::WriteToolButton(wxString name,int index, int width, int height, wxBitmap bitmap)
827{
828 int x;
829 x=index*width;
830 wxRect r(x,0,width,height);
831 wxBitmap little;
832 little=bitmap.GetSubBitmap(r);
833 little.SaveFile(m_targetpath+name,wxBITMAP_TYPE_BMP);
834}
835
836void rc2xml::ParseStringTable(wxString varname)
837{
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 }
852
853}
854
855bool rc2xml::LookUpString(wxString strid,wxString & st)
856{
857 wxNode *node=m_stringtable->Find(strid);
858 wxString *s;
859 if (node==NULL)
860 return FALSE;
861
862 s=(wxString *)node->Data();
863 st=*s;
864
865 return TRUE;
866}
867
868bool rc2xml::SplitHelp(wxString msg, wxString &shorthelp, wxString &longhelp)
869{
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;
882}
883
884void rc2xml::ParseMenuItem()
885{
886 wxString token,name,msg,tip,longhelp;
887//int spot;
888 if (PeekToken()=="SEPARATOR")
889 {
890 m_xmlfile.Write("\t\t\t<object class=\"separator\"/>\n");
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);
899 m_xmlfile.Write("\t\t\t<object class=\"wxMenuItem\"");
900 WriteName(name);
901 m_xmlfile.Write(">\n");
902 WriteLabel(token);
903//Look up help if any listed in stringtable
904 if (LookUpString(name,msg))
905 {
906 SplitHelp(msg,tip,longhelp);
907 m_xmlfile.Write("\t\t\t<help>"
908 +longhelp+"</help>\n");
909 }
910//look for extra attributes like checked and break
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 }
926 m_xmlfile.Write("\t\t\t</object>\n");
927
928}
929
930//ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
931void rc2xml::ParseIconStatic()
932{
933 wxString token;
934 wxString varname,iconname;
935 iconname=GetToken();
936//Look up icon
937 varname=GetToken();
938
939 int x,y,width,height;
940 ReadRect(x,y,width,height);
941
942 m_xmlfile.Write("\t\t<object class=\"wxStaticBitmap\"");
943 WriteBasicInfo(x,y,width,height,varname);
944//Save icon as a bitmap
945 WriteIcon(iconname);
946 m_xmlfile.Write("\t\t</object>\n");
947
948}
949//IDR_MAINFRAME ICON DISCARDABLE "res\\mfcexample.ico"
950void rc2xml::ParseIcon(wxString varname)
951{
952 wxString token,*iconfile;
953 iconfile=new wxString;
954 token=PeekToken();
955
956 *iconfile=GetQuoteField();
957 m_iconlist->Append(varname,iconfile);
958
959
960}
961
962wxString rc2xml::CleanName(wxString name)
963{
964 name.MakeLower();
965 name.Replace("id_","");
966 name.Replace("idr_","");
967 name.Replace("idb_","");
968 name.Replace("idc_","");
969 name.Replace(".ico","");
970 name.Replace(".bmp","");
971 return name;
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
975void rc2xml::ParseStaticBitmap(wxString bitmapname, wxString varname)
976{
977 wxString token;
978 //Grab SS_BITMAP
979 token=GetToken();
980
981
982
983 int x,y,width,height;
984 ReadRect(x,y,width,height);
985
986 m_xmlfile.Write("\t\t<object class=\"wxStaticBitmap\"");
987 WriteBasicInfo(x,y,width,height,varname);
988 WriteBitmap(bitmapname);
989 m_xmlfile.Write("\t\t</object>\n");
990
991}
992
993void rc2xml::ParseNormalMSControl()
994{
995wxString label,varname,kindctrl;
996
997label=GetQuoteField();
998varname=GetToken();
999kindctrl=GetQuoteField();
1000kindctrl.MakeUpper();
1001
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);
1018
1019}
1020
1021void rc2xml::ParseWeirdMSControl()
1022{
1023 wxString kindctrl;
1024 wxString varname;
1025 wxString id;
1026 id=GetToken();
1027 varname=GetToken();
1028 kindctrl=GetQuoteField();
1029 kindctrl.MakeUpper();
1030// CONTROL IDB_FACE,IDC_STATIC,"Static",SS_BITMAP,26,62,32,30
1031 if (kindctrl=="STATIC")
1032 {
1033 if (PeekToken()=="SS_BITMAP")
1034 ParseStaticBitmap(id,varname);
1035 else
1036 wxLogError("Unknown MS Control Static token");
1037 }
1038
1039}
1040//SCROLLBAR IDC_SCROLLBAR1,219,56,10,40,SBS_VERT
1041
1042void rc2xml::ParseScrollBar()
1043{
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");
1056//Default MFC style is horizontal
1057 else
1058 style=_T("wxSB_HORIZONTAL");
1059
1060 m_xmlfile.Write("\t\t<object class=\"wxScrollBar\"");
1061 WriteBasicInfo(x,y,width,height,varname);
1062 WriteStyle(style);
1063 m_xmlfile.Write("\n\t\t</object>\n");
1064
1065}
1066// CONTROL "Tree1",IDC_TREE1,"SysTreeView32",WS_BORDER | WS_TABSTOP,
1067// 7,7,66,61
1068
1069void rc2xml::ParseTreeCtrl(wxString label, wxString varname)
1070{
1071 wxString token;
1072//while (ReadOrs(token));
1073 ReadOrs(token);
1074 int x,y,width,height;
1075 ReadRect(x,y,width,height);
1076 m_xmlfile.Write("\t\t<object class=\"wxTreeCtrl\"");
1077 WriteBasicInfo(x,y,width,height,varname);
1078 m_xmlfile.Write("\t\t</object>\n");
1079
1080}
1081// CONTROL "MonthCalendar1",IDC_MONTHCALENDAR1,"SysMonthCal32",
1082 //MCS_NOTODAY | WS_TABSTOP,105,71,129,89
1083
1084void rc2xml::ParseCalendar(wxString label, wxString varname)
1085{
1086 wxString token;
1087//while (ReadOrs(token));
1088 ReadOrs(token);
1089 int x,y,width,height;
1090 ReadRect(x,y,width,height);
1091 m_xmlfile.Write("\t\t<object class=\"wxCalendarCtrl\"");
1092 WriteBasicInfo(x,y,width,height,varname);
1093 m_xmlfile.Write("\t\t</object>\n");
1094}
1095// CONTROL "List1",IDC_LIST1,"SysListView32",WS_BORDER | WS_TABSTOP,
1096 // 7,89,68,71
1097
1098void rc2xml::ParseListCtrl(wxString label, wxString varname)
1099{
1100 wxString token;
1101 //while (ReadOrs(token));
1102 ReadOrs(token);
1103 int x,y,width,height;
1104 ReadRect(x,y,width,height);
1105 m_xmlfile.Write("\t\t<object class=\"wxListCtrl\"");
1106 WriteBasicInfo(x,y,width,height,varname);
1107 m_xmlfile.Write("\t\t</object>\n");
1108
1109}
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();
1124 bitmapname=wxFileNameFromPath(*bitmappath);
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");
1133 bitmap.SaveFile(m_targetpath+bitmapname,wxBITMAP_TYPE_BMP);
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
1155 iconname=wxFileNameFromPath(*iconpath);
1156 //Make a bitmap file name
1157 iconname=CleanName(iconname);
1158 iconname+=".bmp";
1159 m_xmlfile.Write("\t\t\t<bitmap>"+iconname+"</bitmap>\n");
1160 bitmap.SaveFile(m_targetpath+iconname,wxBITMAP_TYPE_BMP);
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}