#include #include #include #include #include #include #include #include #include #include #include #include class ImportGui : public TGTransientFrame { public: ImportGui(const char* file, TTree* tree) : TGTransientFrame(gClient->GetRoot()), fFileName(file), fContainerHints(kLHintsExpandX|kLHintsExpandY, 3, 3, 3, 3), fContainer(this, kVerticalFrame), fButtonsHints(kLHintsExpandX, 3, 3, 0, 3), fButtons(this, kHorizontalFrame), fCancel(&fButtons, "Cancel", kCancel), fOk(&fButtons, "OK", kOk), fTree(tree), fLines(0) { AddFrame(&fContainer, &fContainerHints); AddFrame(&fButtons, &fButtonsHints); fButtons.Connect("Clicked(Int_t","ImportGui", this, "HandleButtons(Int_t)"); if (!ScanFile()) return; MapSubwindows(); Resize(GetDefaultSize()); MapRaised(); fClient->WaitFor(this); } ~ImportGui() { for (std::vector::iterator i = fLines.begin(); i != fLines.end(); ++i) { delete *i; *i = 0; } } void HandleButtons(Int_t id) { if (id == kCancel) { DeleteWindow(); return; } std::stringstream descs; for (size_t i = 0; i < fLines.size(); i++) { if (i != 0) descs << ":"; descs << fLines[i]->Get().c_str(); } std::string desc(descs.str()); fTree->ReadFile(fFileName.c_str(), desc.c_str()); DeleteWindow(); } protected: Bool_t ScanFile() { std::ifstream in(fFileName.c_str()); if (in.bad()) return false; std::vector descs; // Check for a descriptor. std::string line; std::getline(in, line); bool comment = false; size_t i = 0; for (; i < line.size(); i++) { if (isspace(line[i])) continue; if (line[i] == '#') { i++; comment = true; } break; } std::string rline(line.substr(i, line.size()-i)); if (comment) { size_t i = 0; while (i < rline.size() && i != std::string::npos) { i = rline.find(':', i); if (i != std::string::npos) rline.replace(i, 1, "\t"); } } std::stringstream s(rline); // Got a descriptor while (!s.eof()) { std::string desc; s >> desc; if (comment) descs.push_back(desc); else descs.push_back(""); } // Now create the gui elements for (std::vector::iterator i = descs.begin(); i != descs.end(); ++i) { size_t slash = i->find('/'); std::string name; std::string type; if (slash == std::string::npos) { name = *i; if (i == descs.begin()) type = "F"; else type = ""; } else { name = i->substr(0,slash); type = i->substr(slash+1,i->size()-slash-1); } Line* line = new Line(fContainer, name, type); fLines.push_back(line); } in.close(); return kTRUE; } struct Line : public TGHorizontalFrame { enum { kSame, kFloat, kInt, kDouble, kString }; Line(TGCompositeFrame& c, const std::string& name, const std::string& type) : TGHorizontalFrame(&c), fLayout(kLHintsExpandX|kLHintsExpandY, 3, 3, 1, 2), fName(this, name.c_str()), fType(this) { c.AddFrame(this, &fLayout); AddFrame(&fName, &fLayout); AddFrame(&fType, &fLayout); fType.AddEntry("-Same-", kSame); fType.AddEntry("Float", kFloat); fType.AddEntry("Double", kDouble); fType.AddEntry("Int", kInt); fType.AddEntry("String", kString); int nt = 0; if (type == "F" || type == "f") nt = kFloat; else if (type == "D" || type == "d") nt = kDouble; else if (type == "I" || type == "i") nt = kInt; else if (type == "C" || type == "c") nt = kString; fType.Select(nt, kFALSE); } std::string Get() { std::stringstream s; s << fName.GetText(); if (fType.GetSelected() == kSame) return s.str(); s << "/"; switch (fType.GetSelected()) { case kInt: s << 'I'; break; case kFloat: s << 'F'; break; case kDouble: s << 'D'; break; case kString: s << 'S'; break; } return s.str(); } protected: TGLayoutHints fLayout; TGTextEntry fName; TGComboBox fType; bool fChanged; }; enum { kOk, kCancel }; std::string fFileName; TGLayoutHints fContainerHints; TGVerticalFrame fContainer; TGLayoutHints fButtonsHints; TGHButtonGroup fButtons; TGTextButton fCancel; TGTextButton fOk; TTree* fTree; std::vector fLines; }; void MakeTest(const char* file="test.dat", bool heading=false) { std::ofstream out(file); if (!out) return; if (heading) out << "# I/I:X/F:Y:Z:PID/I" << std::endl; for (size_t i = 0; i < 10; i++) { out << i << "\t" << (i+1)+.1 << "\t" << (i+1)+.2 << "\t" << (i+1)+.3 << "\t" << 10*(i+1) << "\n"; } out << std::flush; out.close(); } TTree* test1() { MakeTest("test1.dat", false); TTree* tree = new TTree("T1", "T1"); new ImportGui("test1.dat", tree); tree->Print(); return tree; } TTree* test2() { MakeTest("test2.dat", true); TTree* tree = new TTree("T2", "T2"); new ImportGui("test2.dat", tree); tree->Print(); return tree; } void drawit(TTree* t) { TCanvas* c = new TCanvas("glc", "C"); c->cd(); t->Draw("x:y:z", "pid", "glbox1"); }