// tableVisiTcl.C // Ariel Tamches /* * $Log: tableVisiTcl.C,v $ * Revision 1.7 1995/12/22 22:44:33 tamches * selection * deletion * sort foci by value * * Revision 1.6 1995/12/19 00:47:06 tamches * call to tableVisi::setSigFigs now resizes if changes occurred. * * Revision 1.5 1995/12/08 05:52:35 tamches * removed some warnings * * Revision 1.4 1995/12/03 21:09:29 newhall * changed units labeling to match type of data being displayed * * Revision 1.3 1995/11/15 01:07:15 tamches * redrawing of a cell takes place as soon as new data arrives for it; we no * longer redraw only last-common-bucket-among-all-mids * * Revision 1.2 1995/11/08 21:56:05 tamches * when-idle routine does a tryFirst() * fold, invalidmetrics, phasename callbacks gone since unused * sigFigChangeCommand reads from tcl vrble SignificantDigits instead * of argv * removed unInstallTableVisiCommands, since not useful * * Revision 1.1 1995/11/04 00:48:25 tamches * First version of new table visi * */ #include #include "tcl.h" #include "tk.h" #include "tkTools.h" #include "tableVisi.h" #include "visi/h/visualization.h" #include "tableVisiTcl.h" /* ************************************************************* */ extern tableVisi *theTableVisi; // our main data structure extern bool xsynch_flag; unsigned currFormat=0; // 0 --> current; 1 --> averages; 2 --> totals bool profileMode = false; /* ************************************************************* */ void tableWhenIdleDrawRoutine(ClientData) { if (theTableVisi->tryFirst()) theTableVisi->draw(xsynch_flag); } tkInstallIdle tableDrawWhenIdle(&tableWhenIdleDrawRoutine); /* ************************************************************* */ int Dg2NewDataCallback(int) { // This callback implies that new data has arrived for each valid metric/focus // pair; hence, it's time to update the screen! if (theTableVisi == NULL) { cout << "Dg2NewDataCallback tableVisi: missed an early sample since not yet initialized" << endl; return TCL_OK; } // This should give the number of _enabled_ metrics & foci: const unsigned numMetrics = theTableVisi->getNumMetrics(); const unsigned numFoci = theTableVisi->getNumFoci(); // Loop through the enabled metrics: for (unsigned metriclcv=0; metriclcv < numMetrics; metriclcv++) { const unsigned metId = theTableVisi->metric2MetId(metriclcv); visi_GridHistoArray &metricValues = dataGrid[metId]; // Loop through the enabled foci for (unsigned focuslcv=0; focuslcv < numFoci; focuslcv++) { const unsigned resId = theTableVisi->focus2ResId(focuslcv); visi_GridCellHisto &theCell = metricValues[resId]; // const unsigned bucketToUse = lastBucket; const unsigned bucketToUse = theCell.LastBucketFilled(); if (!theCell.Valid) theTableVisi->invalidateCell(metriclcv, focuslcv); else if (currFormat==0) // current values theTableVisi->setCellValidData(metriclcv, focuslcv, theCell.Value(bucketToUse)); else if (currFormat==1) // average values theTableVisi->setCellValidData(metriclcv, focuslcv, dataGrid.AggregateValue(metId, resId)); else if (currFormat==2) // total values theTableVisi->setCellValidData(metriclcv, focuslcv, dataGrid.SumValue(metId, resId)); } } // Now, if we are sorting foci by values (profile-table-mode), then it's // time to resort! if (profileMode) if (!theTableVisi->sortFociByValues()) { // could not sort because not exactly 1 column/metric was selected //cout << "table visi; cannot sort foci by value (profile mode) when not exactly 1 column is selected" << endl; } tableDrawWhenIdle.install(NULL); return TCL_OK; } int Dg2AddMetricsCallback(int) { // completely rethink metrics and resources // very ugly; necessary because the visilib interface // is rather crude in this area. // Nevertheless, an improved version of this routine can avoid // rethinking everything, by making a pass over the dataGrid to // _manually_ compute what has actually changed. extern Tcl_Interp *mainInterp; theTableVisi->clearMetrics(mainInterp); unsigned newNumMetrics = dataGrid.NumMetrics(); // not necessarily the correct value; metric(s) may be disabled for (unsigned metriclcv=0; metriclcv < newNumMetrics; metriclcv++) { // Is this metric enabled? Boils down to "is this metric enabled for // at least one focus?" bool enabled = false; for (unsigned focuslcv=0; focuslcv < dataGrid.NumResources(); focuslcv++) { if (dataGrid[metriclcv][focuslcv].Enabled()) { enabled = true; break; } } if (!enabled) continue; if (currFormat==0) // current values theTableVisi->addMetric(metriclcv, dataGrid.MetricName(metriclcv), dataGrid.MetricLabel(metriclcv)); else if (currFormat==1) // average values theTableVisi->addMetric(metriclcv, dataGrid.MetricName(metriclcv), dataGrid.MetricAveLabel(metriclcv)); else if (currFormat==2) // total values theTableVisi->addMetric(metriclcv, dataGrid.MetricName(metriclcv), dataGrid.MetricSumLabel(metriclcv)); } theTableVisi->clearFoci(mainInterp); unsigned newNumFoci = dataGrid.NumResources(); // not necessarily the correct value; foci may be disabled for (unsigned focuslcv=0; focuslcv < newNumFoci; focuslcv++) { // is this focus enabled? bool enabled = false; for (unsigned metriclcv=0; metriclcv < newNumMetrics; metriclcv++) if (dataGrid[metriclcv][focuslcv].Enabled()) { enabled = true; break; } if (!enabled) continue; theTableVisi->addFocus(focuslcv, dataGrid.ResourceName(focuslcv)); } // now update the sorting, as applicable char *sortMetricsStr = Tcl_GetVar(mainInterp, "sortMetrics", TCL_GLOBAL_ONLY); int sortMetricsFlag = atoi(sortMetricsStr); if (sortMetricsFlag==0) theTableVisi->sortMetrics(); else theTableVisi->unsortMetrics(); char *sortFociStr = Tcl_GetVar(mainInterp, "sortFoci", TCL_GLOBAL_ONLY); int sortFociFlag = atoi(sortFociStr); if (sortFociFlag==0) theTableVisi->sortFoci(); else if (sortFociFlag==1) theTableVisi->unsortFoci(); else theTableVisi->sortFociByValues(); theTableVisi->resize(mainInterp); tableDrawWhenIdle.install(NULL); return TCL_OK; } //int Dg2Fold(int) { // cout << "welcome to Dg2Fold" << endl; // tableDrawWhenIdle.install(NULL); // // return TCL_OK; //} //int Dg2InvalidMetricsOrResources(int) { // cout << "welcome to Dg2InvalidMetricsOrResources" << endl; //// myTclEval(MainInterp, "DgInvalidCallback"); // tableDrawWhenIdle.install(NULL); // // return TCL_OK; //} //int Dg2PhaseNameCallback(int) { // cout << "welcome to Dg2PhaseNameCallback" << endl; //// myTclEval(MainInterp, "DgPhaseCallback"); // tableDrawWhenIdle.install(NULL); // // return TCL_OK; //} /* ************************************************************* */ void dummyDeleteProc(ClientData) {} int tableVisiNewVertScrollPositionCommand(ClientData, Tcl_Interp *interp, int argc, char **argv) { // The arguments will be one of: // 1) moveto [fraction] // 2) scroll [num-units] unit (num-units is always either -1 or 1) // 3) scroll [num-pages] page (num-pages is always either -1 or 1) // we let processScrollCallback handle 'em float newFirst; bool anyChanges = processScrollCallback(interp, argc, argv, ".vertScrollbar", theTableVisi->get_offset_y(), theTableVisi->get_total_cell_y_pix(), theTableVisi->get_visible_y_pix(), newFirst); if (anyChanges) anyChanges = theTableVisi->adjustVertSBOffset(interp, newFirst); if (anyChanges) tableDrawWhenIdle.install(NULL); return TCL_OK; } int tableVisiNewHorizScrollPositionCommand(ClientData, Tcl_Interp *interp, int argc, char **argv) { // The arguments will be one of: // 1) moveto [fraction] // 2) scroll [num-units] unit (num-units is always either -1 or 1) // 3) scroll [num-pages] page (num-pages is always either -1 or 1) // we let processScrollCallback handle 'em float newFirst; bool anyChanges = processScrollCallback(interp, argc, argv, ".horizScrollbar", theTableVisi->get_offset_x(), theTableVisi->get_total_cell_x_pix(), theTableVisi->get_visible_x_pix(), newFirst); if (anyChanges) anyChanges = theTableVisi->adjustHorizSBOffset(interp, newFirst); if (anyChanges) tableDrawWhenIdle.install(NULL); return TCL_OK; } int tableVisiConfigureCommand(ClientData, Tcl_Interp *interp, int, char **) { assert(theTableVisi->tryFirst()); theTableVisi->resize(interp); // adjusts scrollbar tableDrawWhenIdle.install(NULL); return TCL_OK; } int tableVisiExposeCommand(ClientData, Tcl_Interp *, int, char **) { assert(theTableVisi->tryFirst()); tableDrawWhenIdle.install(NULL); return TCL_OK; } void tableVisiUpdateDeleteMenu(Tcl_Interp *interp) { const string &menuPrefix = ".top.left.menubar.acts.m entryconfigure 2 "; if (theTableVisi->getSelection()==tableVisi::none) myTclEval(interp, menuPrefix + "-label \"Delete Selected Entry\" -state disabled"); else if (theTableVisi->getSelection()==tableVisi::cell) myTclEval(interp, menuPrefix + "-label \"Delete Selected Cell\" -state normal -command DeleteSelection"); else if (theTableVisi->getSelection()==tableVisi::rowOnly) myTclEval(interp, menuPrefix + "-label \"Delete Selected Focus (entire row)\" -state normal -command DeleteSelection"); else if (theTableVisi->getSelection()==tableVisi::colOnly) myTclEval(interp, menuPrefix + "-label \"Delete Selected Metric (entire column)\" -state normal -command DeleteSelection "); else assert(false); } int tableVisiClickCommand(ClientData, Tcl_Interp *interp, int argc, char **argv) { assert(theTableVisi->tryFirst()); assert(argc == 3); int x = atoi(argv[1]); int y = atoi(argv[2]); if (!theTableVisi->processClick(x, y)) return TCL_OK; // Now we need to update the delete menu item of the actions menu. tableVisiUpdateDeleteMenu(interp); tableDrawWhenIdle.install(NULL); return TCL_OK; } int tableVisiDeleteSelectionCommand(ClientData, Tcl_Interp *interp, int, char **) { assert(theTableVisi->tryFirst()); switch(theTableVisi->getSelection()) { case tableVisi::none: assert(false); case tableVisi::cell: { unsigned theMetId = theTableVisi->getSelectedMetId(); unsigned theResId = theTableVisi->getSelectedResId(); //cout << "tableVisiDeleteSelectionCommand: about to delete a cell..." << endl; //cout << "...whose resource name is " << dataGrid.ResourceName(theResId) << endl; //cout << "...and whose metric name is " << dataGrid.MetricName(theMetId) << endl; StopMetRes(theMetId, theResId); unsigned theRow = theTableVisi->getSelectedRow(); unsigned theCol = theTableVisi->getSelectedCol(); theTableVisi->invalidateCell(theCol, theRow); break; } case tableVisi::rowOnly: { unsigned theResId = theTableVisi->getSelectedResId(); //cout << "tableVisiDeleteSelectionCommand: about to delete a row..." << endl; //cout << "...whose resource name is " << dataGrid.ResourceName(theResId) << endl; for (unsigned collcv=0; collcv < theTableVisi->getNumMetrics(); collcv++) { unsigned theMetId = theTableVisi->col2MetId(collcv); StopMetRes(theMetId, theResId); } unsigned theRow = theTableVisi->getSelectedRow(); theTableVisi->deleteFocus(theRow); break; } case tableVisi::colOnly: { unsigned theMetId = theTableVisi->getSelectedMetId(); //cout << "tableVisiDeleteSelectionCommand: about to delete a column..." << endl; //cout << "...whose metric name is " << dataGrid.MetricName(theMetId) << endl; for (unsigned rowlcv=0; rowlcv < theTableVisi->getNumFoci(); rowlcv++) { unsigned theResId = theTableVisi->row2ResId(rowlcv); StopMetRes(theMetId, theResId); } unsigned theCol = theTableVisi->getSelectedCol(); theTableVisi->deleteMetric(theCol); break; } default: break; } tableVisiUpdateDeleteMenu(interp); theTableVisi->resize(interp); tableDrawWhenIdle.install(NULL); return TCL_OK; } int updateNamesCommand(ClientData, Tcl_Interp *interp, int argc, char **argv) { assert(argc==2); assert(theTableVisi->tryFirst()); if (theTableVisi->setFocusNameMode(interp, (bool)atoi(argv[1]))) tableDrawWhenIdle.install(NULL); return TCL_OK; } int sigFigChangeCommand(ClientData, Tcl_Interp *interp, int argc, char **) { assert(argc == 1); char *sigFigStr = Tcl_GetVar(interp, "SignificantDigits", TCL_GLOBAL_ONLY); if (sigFigStr == NULL) tclpanic(interp, "could not find vrble SignificantDigits"); int newNumSigFigs = atoi(sigFigStr); assert(theTableVisi->tryFirst()); if (theTableVisi->setSigFigs(newNumSigFigs)) { // resizing may have occurred theTableVisi->resize(interp); tableDrawWhenIdle.install(NULL); } return TCL_OK; } int sortMetricsCommand(ClientData, Tcl_Interp *, int, char **) { theTableVisi->sortMetrics(); if (theTableVisi->tryFirst()) tableDrawWhenIdle.install(NULL); return TCL_OK; } int unsortMetricsCommand(ClientData, Tcl_Interp *, int, char **) { theTableVisi->unsortMetrics(); if (theTableVisi->tryFirst()) tableDrawWhenIdle.install(NULL); return TCL_OK; } int sortFociCommand(ClientData, Tcl_Interp *, int, char **) { profileMode = false; theTableVisi->sortFoci(); if (theTableVisi->tryFirst()) tableDrawWhenIdle.install(NULL); return TCL_OK; } int sortFociByValuesCommand(ClientData, Tcl_Interp *, int, char **) { profileMode = true; theTableVisi->sortFociByValues(); if (theTableVisi->tryFirst()) tableDrawWhenIdle.install(NULL); return TCL_OK; } int unsortFociCommand(ClientData, Tcl_Interp *, int, char **) { profileMode = false; theTableVisi->unsortFoci(); if (theTableVisi->tryFirst()) tableDrawWhenIdle.install(NULL); return TCL_OK; } int formatChangedCommand(ClientData, Tcl_Interp *interp, int, char **) { char *dataFormatStr = Tcl_GetVar(interp, "DataFormat", TCL_GLOBAL_ONLY); if (dataFormatStr == NULL) tclpanic(interp, "could not find DataFormat tcl vrble"); int dataFormat = atoi(dataFormatStr); currFormat = dataFormat; for (unsigned i =0; i < dataGrid.NumMetrics(); i++){ if (currFormat==0) // current values theTableVisi->changeUnitsLabel(i, dataGrid.MetricLabel(i)); else if (currFormat==1) // average values theTableVisi->changeUnitsLabel(i, dataGrid.MetricAveLabel(i)); else // total values theTableVisi->changeUnitsLabel(i, dataGrid.MetricSumLabel(i)); } Dg2AddMetricsCallback(0); return TCL_OK; } void installTableVisiCommands(Tcl_Interp *interp) { Tcl_CreateCommand(interp, "horizScrollbarNewScrollPosition", tableVisiNewHorizScrollPositionCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "vertScrollbarNewScrollPosition", tableVisiNewVertScrollPositionCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "tableVisiConfigure", tableVisiConfigureCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "tableVisiExpose", tableVisiExposeCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "tableVisiClick", tableVisiClickCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "DeleteSelection", tableVisiDeleteSelectionCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "updateNames", updateNamesCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "sigFigChange", sigFigChangeCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "sortMetrics", sortMetricsCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "unsortMetrics", unsortMetricsCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "sortFoci", sortFociCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "sortFociByValues", sortFociByValuesCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "unsortFoci", unsortFociCommand, NULL, dummyDeleteProc); Tcl_CreateCommand(interp, "formatChanged", formatChangedCommand, NULL, dummyDeleteProc); }