| //===-- TVFrame.cpp - Main window class for LLVM-TV -----------------------===// |
| // |
| // The gui for llvm-tv. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "CallGraphDrawer.h" |
| #include "CFGGraphDrawer.h" |
| #include "CodeViewer.h" |
| #include "DSAGraphDrawer.h" |
| #include "PictureFrame.h" |
| #include "TVApplication.h" |
| #include "TVFrame.h" |
| #include "TVTextCtrl.h" |
| #include "TVTreeItem.h" |
| #include "llvm-tv/Config.h" |
| #include <cassert> |
| #include <dirent.h> |
| #include <errno.h> |
| #include <sstream> |
| |
| /// TreeCtrl constructor - creates the root and adds it to the tree |
| /// |
| TVTreeCtrl::TVTreeCtrl(wxWindow *parent, TVFrame *frame, const wxWindowID id, |
| const wxPoint& pos, const wxSize& size, |
| long style) |
| : wxTreeCtrl(parent, id, pos, size, style), myFrame (frame) { |
| wxTreeItemId rootId = AddRoot("Snapshots", -1, -1,TVTreeRootItem::instance()); |
| } |
| |
| /// AddSnapshotsToTree - Given a list of snapshots the tree is populated |
| /// |
| void TVTreeCtrl::AddSnapshotsToTree(TVSnapshotList *list) { |
| wxTreeItemId rootId = GetRootItem(); |
| for (TVSnapshotList::iterator I = list->begin(), E = list->end(); |
| I != E; ++I) { |
| // Get the Module associated with this snapshot and add it to the tree |
| Module *M = I->getModule(); |
| wxTreeItemId id = AppendItem(rootId, I->label(), -1, -1, |
| new TVTreeModuleItem(I->label(), M)); |
| |
| // Loop over functions in the module and add them to the tree as children |
| for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { |
| Function *F = I; |
| if (!F->isExternal()) { |
| const char *FuncName = F->getName().c_str(); |
| AppendItem(id, FuncName, -1, -1, new TVTreeFunctionItem(FuncName, I)); |
| } |
| } |
| } |
| } |
| |
| /// updateSnapshotList - Update the tree with the current snapshot list |
| /// |
| void TVTreeCtrl::updateSnapshotList(TVSnapshotList *myList) { |
| DeleteChildren(GetRootItem()); |
| AddSnapshotsToTree(myList); |
| } |
| |
| /// GetSelectedItemData - Return the currently-selected visualizable |
| /// object (TVTreeItemData object). |
| /// |
| TVTreeItemData *TVTreeCtrl::GetSelectedItemData () { |
| return dynamic_cast<TVTreeItemData *> (GetItemData (GetSelection ())); |
| } |
| |
| /// OnSelChanged - Inform the parent frame that the selection has changed, |
| /// and pass the newly selected item to it. |
| /// |
| void TVTreeCtrl::OnSelChanged(wxTreeEvent &event) { |
| myFrame->updateDisplayedItem (GetSelectedItemData ()); |
| } |
| |
| BEGIN_EVENT_TABLE(TVTreeCtrl, wxTreeCtrl) |
| EVT_TREE_SEL_CHANGED(LLVM_TV_TREE_CTRL, TVTreeCtrl::OnSelChanged) |
| END_EVENT_TABLE () |
| |
| ///==---------------------------------------------------------------------==/// |
| |
| void TVTextCtrl::displayItem (TVTreeItemData *item) { |
| std::ostringstream Out; |
| item->print (Out); |
| myTextCtrl->SetValue (""); |
| myTextCtrl->AppendText (Out.str ().c_str ()); |
| myTextCtrl->ShowPosition (0); |
| myTextCtrl->SetInsertionPoint (0); |
| } |
| |
| ///==---------------------------------------------------------------------==/// |
| |
| /// updateDisplayedItem - Updates right-hand pane with a view of the item that |
| /// is now selected. |
| /// |
| void TVFrame::updateDisplayedItem (TVTreeItemData *newlySelectedItem) { |
| // Tell the current visualizer widget to display the selected |
| // LLVM object in its window, which is displayed inside the notebook. |
| assert (newlySelectedItem |
| && "newlySelectedItem was null in updateDisplayedItem()"); |
| notebook->SetSelectedItem (newlySelectedItem); |
| } |
| |
| void TVFrame::refreshSnapshotList () { |
| |
| if (!myApp->getSnapshotList()->refreshList()) |
| FatalErrorBox ("trying to open directory " + myApp->getSnapshotList()->getSnapshotDirName() + ": " |
| + strerror(errno)); |
| if (myTreeCtrl != 0) |
| myTreeCtrl->updateSnapshotList(myApp->getSnapshotList()); |
| } |
| |
| void TVFrame::initializeSnapshotListAndView () { |
| refreshSnapshotList (); |
| SetStatusText ("Snapshot list has been loaded."); |
| } |
| |
| //==------------------------------------------------------------------------==// |
| |
| void TVNotebook::displaySelectedItemOnPage (int page) { |
| if (selectedItem) |
| displayers[page]->displayItem (selectedItem); |
| } |
| |
| void TVNotebook::SetSelectedItem (TVTreeItemData *newSelectedItem) { |
| selectedItem = newSelectedItem; |
| displaySelectedItemOnPage (GetSelection ()); |
| } |
| |
| bool TVNotebook::AddItemDisplayer (ItemDisplayer *displayer) { |
| int pageIndex = GetPageCount (); |
| displayers.resize (1 + pageIndex); |
| displayers[pageIndex] = displayer; |
| return AddPage (displayer->getWindow (), |
| displayer->getDisplayTitle (0).c_str (), true); |
| } |
| |
| void TVNotebook::OnSelChanged (wxNotebookEvent &event) { |
| int newPage = event.GetSelection (); |
| displayers[newPage]->getWindow ()->SetSizeHints (-1, -1, -1, -1, -1, -1); |
| displaySelectedItemOnPage (newPage); |
| event.Skip (); |
| } |
| |
| BEGIN_EVENT_TABLE (TVNotebook, wxNotebook) |
| EVT_NOTEBOOK_PAGE_CHANGED(LLVM_TV_NOTEBOOK, TVNotebook::OnSelChanged) |
| END_EVENT_TABLE () |
| |
| //==------------------------------------------------------------------------==// |
| |
| static const wxString Explanation |
| ("Click on a Module or Function in the left-hand pane\n" |
| "to display its code in the right-hand pane. Then, you\n" |
| "can choose from the View menu to see graphical code views.\n"); |
| |
| /// TVFrame constructor - used to set up typical appearance of visualizer's |
| /// top-level window. |
| /// |
| TVFrame::TVFrame (TVApplication *app, const char *title) |
| : wxFrame (NULL, -1, title), myApp (app) { |
| // Set up appearance |
| CreateStatusBar (); |
| SetSize (wxRect (100, 100, 500, 200)); |
| Show (FALSE); |
| splitterWindow = new wxSplitterWindow(this, LLVM_TV_SPLITTER_WINDOW, |
| wxDefaultPosition, wxDefaultSize, |
| wxSP_3D); |
| |
| // Create tree view of snapshots |
| myTreeCtrl = new TVTreeCtrl(splitterWindow, this, LLVM_TV_TREE_CTRL); |
| Resize(); |
| |
| // Create right-hand pane's display widget and stick it in a notebook control. |
| notebook = new TVNotebook (splitterWindow); |
| notebook->AddItemDisplayer (new TVTextCtrl (notebook, Explanation)); |
| notebook->AddItemDisplayer (new TDGraphDrawer (notebook)); |
| notebook->AddItemDisplayer (new BUGraphDrawer (notebook)); |
| notebook->AddItemDisplayer (new LocalGraphDrawer (notebook)); |
| notebook->AddItemDisplayer (new TVCodeViewer (notebook)); |
| |
| // Split window vertically |
| splitterWindow->SplitVertically(myTreeCtrl, notebook, 200); |
| Show (TRUE); |
| } |
| |
| /// OnHelp - display the help dialog |
| /// |
| void TVFrame::OnHelp (wxCommandEvent &event) { |
| wxMessageBox (Explanation, "Help with LLVM-TV"); |
| } |
| |
| /// OnExit - respond to a request to exit the program. |
| /// |
| void TVFrame::OnExit (wxCommandEvent &event) { |
| myApp->Quit (); |
| } |
| |
| /// OnExit - respond to a request to display the About box. |
| /// |
| void TVFrame::OnAbout (wxCommandEvent &event) { |
| wxMessageBox("LLVM Visualization Tool\n\n" |
| "By Misha Brukman, Tanya Brethour, and Brian Gaeke\n" |
| "Copyright (C) 2004 University of Illinois at Urbana-Champaign\n" |
| "http://llvm.cs.uiuc.edu", "About LLVM-TV"); |
| } |
| |
| /// OnRefresh - respond to a request to refresh the list |
| /// |
| void TVFrame::OnRefresh (wxCommandEvent &event) { |
| refreshSnapshotList (); |
| } |
| |
| void TVFrame::OnOpen (wxCommandEvent &event) { |
| wxFileDialog d (this, "Choose a bytecode file to display"); |
| int result = d.ShowModal (); |
| if (result == wxID_CANCEL) return; |
| // FIXME: the rest of this method can be moved into the "snapshots |
| // list" object |
| std::string command = std::string("cp ") + std::string(d.GetPath ().c_str ()) + " " + snapshotsPath; |
| system (command.c_str ()); |
| refreshSnapshotList (); |
| } |
| |
| void TVFrame::Resize() { |
| wxSize size = GetClientSize(); |
| myTreeCtrl->SetSize(0, 0, size.x, 2*size.y/3); |
| } |
| |
| // This method of TVApplication is placed in this file so that it can |
| // be instantiated by all its callers. |
| template<class Grapher> |
| void TVApplication::OpenGraphView (TVTreeItemData *item) { |
| PictureFrame *wind = new PictureFrame (this); |
| allMyWindows.push_back (wind); |
| ItemDisplayer *drawer = new Grapher (wind); |
| wind->SetTitle (drawer->getDisplayTitle (item).c_str ()); |
| allMyDisplayers.push_back (drawer); |
| drawer->displayItem (item); |
| } |
| |
| void TVFrame::CallGraphView(wxCommandEvent &event) { |
| // Get the selected LLVM object and open up a new call graph view window. |
| myApp->OpenGraphView<CallGraphDrawer> (myTreeCtrl->GetSelectedItemData ()); |
| } |
| |
| void TVFrame::CFGView(wxCommandEvent &event) { |
| // Get the selected LLVM object and open up a new CFG view window. |
| myApp->OpenGraphView<CFGGraphDrawer> (myTreeCtrl->GetSelectedItemData ()); |
| } |
| |
| void TVFrame::BUDSView(wxCommandEvent &event) { |
| // Get the selected LLVM object and open up a new BUDS view window. |
| myApp->OpenGraphView<BUGraphDrawer> (myTreeCtrl->GetSelectedItemData ()); |
| } |
| |
| void TVFrame::TDDSView(wxCommandEvent &event) { |
| // Get the selected LLVM object and open up a new TDDS view window. |
| myApp->OpenGraphView<TDGraphDrawer> (myTreeCtrl->GetSelectedItemData ()); |
| } |
| |
| void TVFrame::LocalDSView(wxCommandEvent &event) { |
| // Get the selected LLVM object and open up a new Local DS view window. |
| myApp->OpenGraphView<LocalGraphDrawer> (myTreeCtrl->GetSelectedItemData ()); |
| } |
| |
| void TVFrame::CodeView(wxCommandEvent &event) { |
| // Get the selected LLVM object and open up a new CodeViewer window. |
| myApp->OpenGraphView<TVCodeViewer> (myTreeCtrl->GetSelectedItemData ()); |
| } |
| |
| BEGIN_EVENT_TABLE (TVFrame, wxFrame) |
| EVT_MENU (wxID_OPEN, TVFrame::OnOpen) |
| EVT_MENU (LLVM_TV_REFRESH, TVFrame::OnRefresh) |
| EVT_MENU (wxID_EXIT, TVFrame::OnExit) |
| |
| EVT_MENU (wxID_HELP_CONTENTS, TVFrame::OnHelp) |
| EVT_MENU (wxID_ABOUT, TVFrame::OnAbout) |
| |
| EVT_MENU (LLVM_TV_CALLGRAPHVIEW, TVFrame::CallGraphView) |
| EVT_MENU (LLVM_TV_CFGVIEW, TVFrame::CFGView) |
| EVT_MENU (LLVM_TV_BUDS_VIEW, TVFrame::BUDSView) |
| EVT_MENU (LLVM_TV_TDDS_VIEW, TVFrame::TDDSView) |
| EVT_MENU (LLVM_TV_LOCALDS_VIEW, TVFrame::LocalDSView) |
| EVT_MENU (LLVM_TV_CODEVIEW, TVFrame::CodeView) |
| END_EVENT_TABLE () |