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