1 module gladeparser; 2 3 import std.stdio; 4 import std.file; 5 import std.exception; 6 7 import dxml.dom; 8 9 private { 10 void checkAppWindow(DOMEntity!string root){ 11 bool isAppIdFound = false; 12 bool isAppClassFound = false; 13 14 foreach(i; 0..root.children.length){ 15 auto child = root.children[i]; 16 if(child.name == "object"){ 17 if(child.hasAttr("id")) 18 isAppIdFound = true; 19 if (child.hasAttr("class")){ 20 foreach(attr; child.attributes) 21 if((attr.value == "GtkApplicationWindow") || (attr.value == "GtkWindow")) 22 isAppClassFound = true; 23 24 } 25 } 26 } 27 28 if((!isAppClassFound) || (!isAppIdFound)) 29 throw new Exception("root element must contain an object field with attributes of class and id."); 30 } 31 32 33 bool hasAttr(DOMEntity!string entity, string aname){ 34 if(entity.attributes.length == 0) 35 return false; 36 foreach(attr; entity.attributes){ 37 if(attr.name == aname ) return true; 38 } 39 return false; 40 } 41 } 42 43 auto getWidgetObjects(string gstr){ 44 auto dom = parseDOM(gstr); 45 46 DOMEntity!string iroot; 47 48 foreach(i; 0 .. dom.children.length) 49 if(dom.children[i].type != EntityType.comment) 50 if(dom.children[i].name == "interface") 51 iroot = dom.children[i]; 52 53 checkAppWindow(iroot); 54 55 string[string][] objects; 56 57 void parseObjects(DOMEntity!string root){ 58 try{ 59 if((root.type == EntityType.elementEmpty) || (root.type == EntityType.text)) return; 60 foreach(i; 0 .. root.children.length){ 61 auto child = root.children[i]; 62 if((child.type == EntityType.elementEmpty) || (child.type == EntityType.text)) continue; 63 if ((child.name == "object") && (child.hasAttr("id"))){ 64 string id = ""; 65 string cname = ""; 66 foreach(attr; child.attributes){ 67 if(attr.name == "id") 68 id = attr.value; 69 if(attr.name == "class") 70 cname = attr.value; 71 } 72 auto el = ["class": cname, "id": id]; 73 el.writeln; 74 objects ~= el; 75 } 76 77 parseObjects(child); 78 } 79 } catch (Exception exc) { 80 return; 81 } 82 } 83 84 parseObjects(iroot); 85 return objects; 86 }