import std.stdio; import std.string; import std.conv : to; import gtk.Main; import gtk.MainWindow; import gtk.TreeView; import gtk.ListStore; import gtk.TreeViewColumn; import gtk.TreeIter; import gtk.Label; import gtk.Entry; import gtk.CellRenderer; import gtk.CellRendererText; import gtk.CellRendererSpin; void[] Serialize(VT...)(VT data){ void[] ret; foreach(d ; data){ ret~=cast(void[])([d]); } return ret; } void main(string[] args) { auto twoda = new TwoDA("test.2da"); Main.init(args); auto window = new MainWindow("2DA-Edit"); GType type[]; type~=GType.STRING; foreach(i;1..twoda.header.length)type~=GType.STRING; auto store = new ListStore(type); auto tree = new TreeView(store); window.add(tree); tree.setHeadersVisible(true); tree.setEnableSearch(true); tree.setModel(store); tree.setProperty("enable-grid-lines", GtkTreeViewGridLines.VERTICAL); foreach(index, s ; twoda.header){ CellRendererText cr; if(index==0){ cr = new CellRendererText(); cr.setProperty("editable", true); cr.setProperty("background-rgba", cast(ulong)(new GdkRGBA(0.36, 0.13, 0.4, 1.0))); cr.setProperty("background-set", true); } else{ cr = new CellRendererText(); cr.setProperty("editable", true); cr.addOnEdited((string path, string newval, CellRendererText crt){ TreeIter t = new TreeIter(tree.getModel(), path); store.setValue(t, cast(int)crt.getData("colnumber"), newval); }); } cr.setData("colnumber", cast(void*)cast(int)index); //cr.setSensitive(true); auto col = new TreeViewColumn(s, cr, "text", cast(int)index); col.setResizable(true); //if(index!=0) col.setReorderable(true); tree.appendColumn(col); } TreeIter iter = new TreeIter(); for(int i=0 ; i<=twoda.lastLine ; i++){ store.append(iter); store.setValue(iter, 0, i); if(i in twoda.values){ foreach(index, v ; twoda.values[i]){ store.setValue(iter, cast(int)index+1, v); } } else{ foreach(index ; 1..twoda.header.length){ store.setValue(iter, cast(int)index+1, "_"); } } } tree.columnsAutosize(); window.showAll(); Main.run(); } class TwoDA{ import std.regex; import std.file; this(string filepath){ lastLine = 0; foreach(index, line ; readText(filepath).splitLines()){ string data[]; auto results = matchAll(line, rgxField); foreach(res ; results){ string s; if(res[0][0]=='"') data~= res[2]; else data~= res[1]; } if(index==0){ header = data; //writeln(header); } else{ int nLine = data[0].to!int; values[nLine] = data[1..$]; //writeln(values[nLine]); if(nLine > lastLine) lastLine = nLine; } } } string[] header; string[][uint] values; uint lastLine; enum rgxField = ctRegex!"(?:\\b([^\\s]+?)\\b|\"([^\"]+?)\")"; }