]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/wxrc/wxrc.cpp
BIG CHANGE: added parsing of base classes; now CompareClasses() is much smarter since...
[wxWidgets.git] / utils / wxrc / wxrc.cpp
index c07224810ed12f9c5f87afaa2cca229b8467a8d6..fef806dec4516408526bfb93e25d5d81dca59d6c 100644 (file)
@@ -30,6 +30,7 @@
 #include "wx/utils.h"
 #include "wx/hashset.h"
 #include "wx/mimetype.h"
+#include "wx/vector.h"
 
 WX_DECLARE_HASH_SET(wxString, wxStringHash, wxStringEqual, StringSet);
 
@@ -65,8 +66,8 @@ private:
         while (node)
         {
             if (node->GetName() == _T("object")
-                && node->GetPropVal(_T("class"),&classValue)
-                && node->GetPropVal(_T("name"),&nameValue))
+                && node->GetAttribute(_T("class"),&classValue)
+                && node->GetAttribute(_T("name"),&nameValue))
             {
                 m_wdata.Add(XRCWidgetData(nameValue,classValue));
             }
@@ -201,6 +202,22 @@ public:
 WX_DECLARE_OBJARRAY(XRCWndClassData,ArrayOfXRCWndClassData);
 WX_DEFINE_OBJARRAY(ArrayOfXRCWndClassData)
 
+struct ExtractedString
+{
+    ExtractedString() : lineNo(-1) {}
+    ExtractedString(const wxString& str_,
+                    const wxString& filename_, int lineNo_)
+        : str(str_), filename(filename_), lineNo(lineNo_)
+    {}
+
+    wxString str;
+
+    wxString filename;
+    int      lineNo;
+};
+
+typedef wxVector<ExtractedString> ExtractedStrings;
+
 
 class XmlResApp : public wxAppConsole
 {
@@ -222,8 +239,8 @@ private:
     void MakePackagePython(const wxArrayString& flist);
 
     void OutputGettext();
-    wxArrayString FindStrings();
-    wxArrayString FindStrings(wxXmlNode *node);
+    ExtractedStrings FindStrings();
+    ExtractedStrings FindStrings(const wxString& filename, wxXmlNode *node);
 
     bool flagVerbose, flagCPP, flagPython, flagGettext;
     wxString parOutput, parFuncname, parOutputPath;
@@ -241,23 +258,22 @@ int XmlResApp::OnRun()
 {
     static const wxCmdLineEntryDesc cmdLineDesc[] =
     {
-        { wxCMD_LINE_SWITCH, _T("h"), _T("help"),  _T("show help message"),
-              wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
-        { wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose"), (wxCmdLineParamType)0, 0 },
-        { wxCMD_LINE_SWITCH, _T("e"), _T("extra-cpp-code"),  _T("output C++ header file with XRC derived classes"), (wxCmdLineParamType)0, 0 },
-        { wxCMD_LINE_SWITCH, _T("c"), _T("cpp-code"),  _T("output C++ source rather than .rsc file"), (wxCmdLineParamType)0, 0 },
-        { wxCMD_LINE_SWITCH, _T("p"), _T("python-code"),  _T("output wxPython source rather than .rsc file"), (wxCmdLineParamType)0, 0 },
-        { wxCMD_LINE_SWITCH, _T("g"), _T("gettext"),  _T("output list of translatable strings (to stdout or file if -o used)"), (wxCmdLineParamType)0, 0 },
-        { wxCMD_LINE_OPTION, _T("n"), _T("function"),  _T("C++/Python function name (with -c or -p) [InitXmlResource]"), (wxCmdLineParamType)0, 0 },
-        { wxCMD_LINE_OPTION, _T("o"), _T("output"),  _T("output file [resource.xrs/cpp]"), (wxCmdLineParamType)0, 0 },
+        { wxCMD_LINE_SWITCH, "h", "help",  "show help message", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
+        { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
+        { wxCMD_LINE_SWITCH, "e", "extra-cpp-code",  "output C++ header file with XRC derived classes" },
+        { wxCMD_LINE_SWITCH, "c", "cpp-code",  "output C++ source rather than .rsc file" },
+        { wxCMD_LINE_SWITCH, "p", "python-code",  "output wxPython source rather than .rsc file" },
+        { wxCMD_LINE_SWITCH, "g", "gettext",  "output list of translatable strings (to stdout or file if -o used)" },
+        { wxCMD_LINE_OPTION, "n", "function",  "C++/Python function name (with -c or -p) [InitXmlResource]" },
+        { wxCMD_LINE_OPTION, "o", "output",  "output file [resource.xrs/cpp]" },
 #if 0 // not yet implemented
-        { wxCMD_LINE_OPTION, _T("l"), _T("list-of-handlers"),  _T("output list of necessary handlers to this file"), (wxCmdLineParamType)0, 0 },
+        { wxCMD_LINE_OPTION, "l", "list-of-handlers",  "output list of necessary handlers to this file" },
 #endif
-        { wxCMD_LINE_PARAM,  NULL, NULL, _T("input file(s)"),
+        { wxCMD_LINE_PARAM,  NULL, NULL, "input file(s)",
               wxCMD_LINE_VAL_STRING,
               wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_OPTION_MANDATORY },
 
-        { wxCMD_LINE_NONE, NULL, NULL, NULL, (wxCmdLineParamType)0, 0 }
+        wxCMD_LINE_DESC_END 
     };
 
     wxCmdLineParser parser(cmdLineDesc, argc, argv);
@@ -284,14 +300,14 @@ int XmlResApp::OnRun()
 
 void XmlResApp::ParseParams(const wxCmdLineParser& cmdline)
 {
-    flagGettext = cmdline.Found(_T("g"));
-    flagVerbose = cmdline.Found(_T("v"));
-    flagCPP = cmdline.Found(_T("c"));
-    flagPython = cmdline.Found(_T("p"));
-    flagH = flagCPP && cmdline.Found(_T("e"));
+    flagGettext = cmdline.Found("g");
+    flagVerbose = cmdline.Found("v");
+    flagCPP = cmdline.Found("c");
+    flagPython = cmdline.Found("p");
+    flagH = flagCPP && cmdline.Found("e");
 
 
-    if (!cmdline.Found(_T("o"), &parOutput))
+    if (!cmdline.Found("o", &parOutput))
     {
         if (flagGettext)
             parOutput = wxEmptyString;
@@ -314,7 +330,7 @@ void XmlResApp::ParseParams(const wxCmdLineParser& cmdline)
     }
     if (!parOutputPath) parOutputPath = _T(".");
 
-    if (!cmdline.Found(_T("n"), &parFuncname))
+    if (!cmdline.Found("n", &parFuncname))
         parFuncname = _T("InitXmlResource");
 
     for (size_t i = 0; i < cmdline.GetParamCount(); i++)
@@ -409,8 +425,8 @@ wxArrayString XmlResApp::PrepareTempFiles()
                 wxString classValue,nameValue;
                 while(node){
                     if(node->GetName() == _T("object")
-                     && node->GetPropVal(_T("class"),&classValue)
-                     && node->GetPropVal(_T("name"),&nameValue)){
+                     && node->GetAttribute(_T("class"),&classValue)
+                     && node->GetAttribute(_T("name"),&nameValue)){
 
                       aXRCWndClassData.Add(
                         XRCWndClassData(nameValue,classValue,node)
@@ -441,29 +457,35 @@ static bool NodeContainsFilename(wxXmlNode *node)
    if ( name == _T("icon") )
        return true;
 
-   // URLs in wxHtmlWindow:
-   if ( name == _T("url") )
-       return true;
-
    // wxBitmapButton:
    wxXmlNode *parent = node->GetParent();
    if (parent != NULL &&
-       parent->GetPropVal(_T("class"), _T("")) == _T("wxBitmapButton") &&
+       parent->GetAttribute(_T("class"), _T("")) == _T("wxBitmapButton") &&
        (name == _T("focus") ||
         name == _T("disabled") ||
+        name == _T("hover") ||
         name == _T("selected")))
        return true;
 
    // wxBitmap or wxIcon toplevel resources:
    if ( name == _T("object") )
    {
-       wxString klass = node->GetPropVal(_T("class"), wxEmptyString);
+       wxString klass = node->GetAttribute(_T("class"), wxEmptyString);
        if (klass == _T("wxBitmap") ||
                klass == _T("wxIcon") ||
                 klass == _T("data") )
            return true;
    }
 
+   // URLs in wxHtmlWindow:
+   if ( name == _T("url") &&
+        parent != NULL &&
+        parent->GetAttribute(_T("class"), _T("")) == _T("wxHtmlWindow") )
+   {
+       // FIXME: this is wrong for e.g. http:// URLs
+       return true;
+   }
+
    return false;
 }
 
@@ -559,7 +581,8 @@ static wxString FileToCppArray(wxString filename, int num)
     wxASSERT_MSG( offset >= 0 , wxT("Invalid file length") );
 
     const size_t lng = wx_truncate_cast(size_t, offset);
-    wxASSERT_MSG( lng == offset, wxT("Huge file not supported") );
+    wxASSERT_MSG( wx_static_cast(wxFileOffset, lng) == offset,
+                  wxT("Huge file not supported") );
 
     snum.Printf(_T("%i"), num);
     output.Printf(_T("static size_t xml_res_size_") + snum + _T(" = %i;\n"), lng);
@@ -651,12 +674,17 @@ void XmlResApp::MakePackageCPP(const wxArrayString& flist)
         wxString ext = wxFileName(flist[i]).GetExt();
         if ( ext.Lower() == _T("xrc") )
             mime = _T("text/xml");
+#if wxUSE_MIMETYPE
         else
         {
             wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
             if ( ft )
+            {
                 ft->GetMimeType(&mime);
+                delete ft;
+            }
         }
+#endif // wxUSE_MIMETYPE
 
         s.Printf("    XRC_ADD_FILE(wxT(\"XRC_resource/" + flist[i] +
                  "\"), xml_res_file_%i, xml_res_size_%i, _T(\"%s\"));\n",
@@ -707,7 +735,8 @@ static wxString FileToPythonArray(wxString filename, int num)
     wxASSERT_MSG( offset >= 0 , wxT("Invalid file length") );
 
     const size_t lng = wx_truncate_cast(size_t, offset);
-    wxASSERT_MSG( offset == lng, wxT("Huge file not supported") );
+    wxASSERT_MSG( wx_static_cast(wxFileOffset, lng) == offset,
+                  wxT("Huge file not supported") );
 
     snum.Printf(_T("%i"), num);
     output = "    xml_res_file_" + snum + " = '''\\\n";
@@ -804,7 +833,7 @@ void XmlResApp::MakePackagePython(const wxArrayString& flist)
 
 void XmlResApp::OutputGettext()
 {
-    wxArrayString str = FindStrings();
+    ExtractedStrings str = FindStrings();
 
     wxFFile fout;
     if (parOutput.empty())
@@ -812,17 +841,23 @@ void XmlResApp::OutputGettext()
     else
         fout.Open(parOutput, wxT("wt"));
 
-    for (size_t i = 0; i < str.GetCount(); i++)
-        fout.Write("_(\"" + str[i] + "\");\n");
+    for (ExtractedStrings::const_iterator i = str.begin(); i != str.end(); ++i)
+    {
+        wxString s;
+
+        s.Printf("#line %d \"%s\"\n", i->lineNo, i->filename);
+        fout.Write(s);
+        fout.Write("_(\"" + i->str + "\");\n");
+    }
 
     if (!parOutput) fout.Detach();
 }
 
 
 
-wxArrayString XmlResApp::FindStrings()
+ExtractedStrings XmlResApp::FindStrings()
 {
-    wxArrayString arr, a2;
+    ExtractedStrings arr, a2;
 
     for (size_t i = 0; i < parFiles.GetCount(); i++)
     {
@@ -836,7 +871,8 @@ wxArrayString XmlResApp::FindStrings()
             retCode = 1;
             continue;
         }
-        a2 = FindStrings(doc.GetRoot());
+        a2 = FindStrings(parFiles[i], doc.GetRoot());
+
         WX_APPEND_ARRAY(arr, a2);
     }
 
@@ -883,9 +919,10 @@ static wxString ConvertText(const wxString& str)
 }
 
 
-wxArrayString XmlResApp::FindStrings(wxXmlNode *node)
+ExtractedStrings
+XmlResApp::FindStrings(const wxString& filename, wxXmlNode *node)
 {
-    wxArrayString arr;
+    ExtractedStrings arr;
 
     wxXmlNode *n = node;
     if (n == NULL) return arr;
@@ -912,16 +949,24 @@ wxArrayString XmlResApp::FindStrings(wxXmlNode *node)
             // ...and known to contain translatable string
         {
             if (!flagGettext ||
-                node->GetPropVal(_T("translate"), _T("1")) != _T("0"))
+                node->GetAttribute(_T("translate"), _T("1")) != _T("0"))
             {
-                arr.Add(ConvertText(n->GetContent()));
+                arr.push_back
+                    (
+                        ExtractedString
+                        (
+                            ConvertText(n->GetContent()),
+                            filename,
+                            n->GetLineNumber()
+                        )
+                    );
             }
         }
 
         // subnodes:
         if (n->GetType() == wxXML_ELEMENT_NODE)
         {
-            wxArrayString a2 = FindStrings(n);
+            ExtractedStrings a2 = FindStrings(filename, n);
             WX_APPEND_ARRAY(arr, a2);
         }