Changeset 12940 for fact/Evidence
- Timestamp:
- 02/24/12 20:43:27 (13 years ago)
- Location:
- fact/Evidence
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/Evidence/GUI.cc
r12910 r12940 23 23 QString Format; 24 24 DimBrowser Browser; 25 class EvidenceHistory *Hist = Handler->GetHistory(Service);25 struct EddDim::HistItem Hist = Handler->GetHistory(Service); 26 26 char *Name, *Fmt; 27 27 28 28 // Check if history service available 29 29 if (strcmp(Service, "Edd/Rate_kBSec") == 0) Format = "F"; 30 else if (Hist == NULL || Hist->GetFormat() == NULL) { 31 printf("Edd Message: Could not retrieve history for service %s\n", Service); 32 } 33 else Format = Hist->GetFormat(); 30 else Format = Hist.Format; 34 31 35 32 // If service currently available, take its format … … 37 34 if (Browser.getNextService(Name, Fmt) != 0) Format = QString(Fmt); 38 35 39 Handler->DropHistory(Service);40 41 36 // Open new window 42 37 QMainWindow *M = new QMainWindow; … … 51 46 else { 52 47 EddPlot *W = new EddPlot(Service, FromIndex); 53 for (int i=FromIndex+1; i<=ToIndex; i++) { 54 W->AddService(Service,i); 55 Layout->addWidget(new EddLineDisplay(Service, i), 1 + (i-FromIndex)/5, (i-FromIndex)%5); 56 } 48 for (int i=FromIndex+1; i<=ToIndex; i++) W->AddService(Service,i); 49 57 50 Layout->addWidget(W, 0, 0, 1, 5); 58 51 } 59 52 60 Layout->addWidget(new EddLineDisplay(Service, FromIndex), 1, 0);61 53 M->resize(400,450); 62 54 M->show(); … … 70 62 QString Status; 71 63 72 if (Index != -1) Name = Name + " [" + QString::number(Index) + "]";64 if (Index != -1) Name = Name + ":" + QString::number(Index); 73 65 74 66 if (Time == -1) Status = QString("%1: unavailable").arg(Name); … … 332 324 connect(axisWidget(QwtPlot::xBottom), SIGNAL(scaleDivChanged()), SLOT(update())); 333 325 334 legend()->setItemMode(QwtLegend::ClickableItem);335 connect(this, SIGNAL(legendClicked (QwtPlotItem *)), SLOT(LegendClicked(QwtPlotItem *)));336 337 326 // Additonal context menu items 338 327 QAction* Action = Menu->addAction("Paste service", this, SLOT(MenuPasteService())); … … 344 333 Action = Menu->addAction("Show last day", this, SLOT(MenuShowLastDay())); 345 334 Menu->insertAction(Menu->actions().value(8), Action); 335 336 Action = Menu->addAction("All as text", this, SLOT(MenuAllAsText())); 337 Menu->insertAction(Menu->actions().value(10), Action); 346 338 347 339 // Set timer to regularly update plot if new data available … … 357 349 EddPlot::~EddPlot() { 358 350 359 while (!List.isEmpty()) DeleteCurve(List.last().Signal);360 } 361 362 // Add historyservice to plot351 while (!List.isEmpty()) RemoveService(List.last().Curve); 352 } 353 354 // Add service to plot 363 355 void EddPlot::AddService(QString Name, int Index) { 364 356 … … 375 367 376 368 N.Name = Name; 377 N.Signal = NewCurve(Name+"["+QString::number(Index)+"]");378 369 N.Index = Index; 370 N.Curve = NewCurve(Name+":"+QString::number(Index)); 379 371 List.append(N); 380 372 381 // Request new history buffer 382 const struct EvidenceHistory::Item *R; 383 class EvidenceHistory *Hist; 384 385 if ((Hist = Handler->GetHistory(Name)) != NULL) { 386 double Number=0; 387 while ((R=Hist->Next()) != NULL) { 388 std::vector<std::string> Data = EvidenceServer::Tokenize(EvidenceServer::ToString(Hist->GetFormat(), R->Data, R->Size)); 389 if (N.Index > 0 && N.Index < (int) Data.size()) Number = atof(Data[N.Index].c_str()); 390 AddPoint(List.size()-1, R->Time, Number); 391 } 392 } 393 Handler->DropHistory(Name); 373 // Use custom legend widget 374 EddLegend *Legend = new EddLegend(N.Curve, this); 375 legend()->remove(N.Curve); 376 legend()->insert(N.Curve, (QWidget *) Legend); 377 378 // Context menu might delete curve and legend -> seg fault if using direct connection, as legend item deleted 379 connect(Legend, SIGNAL(DeleteCurve(QwtPlotCurve *)), this, SLOT(RemoveService(QwtPlotCurve *)), Qt::QueuedConnection); 380 381 // Get history 382 struct EddDim::HistItem Hist = Handler->GetHistory(Name); 383 384 for (int i=0; i<Hist.DataText.size(); i++) { 385 AddPoint(List.size()-1, Hist.DataText[i].first, Hist.DataText[i].second.at(N.Index).toFloat()); 386 } 387 388 // Subscribe to service and start updating plot after 100 ms (to allow addition of other curves) 394 389 Handler->Subscribe(Name, this, Index); 395 396 390 SingleShot->start(100); 397 391 } … … 407 401 } 408 402 } 409 410 403 411 404 // Add text indicating time range to plot … … 435 428 } 436 429 437 void EddPlot::LegendClicked(QwtPlotItem *Item) {438 439 QString D(Item->title().text());440 D.replace('(',' ').chop(1);441 442 QDrag *Drag = new QDrag(this);443 QMimeData *MimeData = new QMimeData;444 QByteArray Data;445 MimeData->setData("Edd/Service", Data.append(D));446 Drag->setMimeData(MimeData);447 Drag->exec();448 }449 450 430 // Add new service by pasting name 451 431 void EddPlot::MenuPasteService() { … … 462 442 463 443 setAxisScale(QwtPlot::xBottom, time(NULL)-60*60, time(NULL)+60); 464 //setAxisAutoScale(QwtPlot::yLeft);465 444 replot(); 466 445 } … … 469 448 470 449 setAxisScale(QwtPlot::xBottom, time(NULL)-24*3600, time(NULL)+3600); 471 //setAxisAutoScale(QwtPlot::yLeft);472 450 replot(); 473 451 } 474 452 475 476 // Remove list entry 477 void EddPlot::DeleteCurve(QwtPlotCurve *Curve) { 478 479 for (int i=0; i<List.size(); i++) if (List[i].Signal == Curve) { 480 Handler->Unsubscribe(List[i].Name, this, List[i].Index); 481 List.removeAt(i); 482 } 453 void EddPlot::MenuAllAsText() { 454 455 QMainWindow *M = new QMainWindow; 456 M->setCentralWidget(new QWidget(M)); 457 M->setStatusBar(new QStatusBar(M)); 458 M->setAttribute(Qt::WA_DeleteOnClose); 459 M->setWindowTitle("Edd Services"); 460 461 QGridLayout *Layout = new QGridLayout(M->centralWidget()); 462 463 for (int i=0; i<List.size(); i++) { 464 Layout->addWidget(new EddLineDisplay(List[i].Name, List[i].Index), i/10, i%10); 465 } 466 467 M->resize(400,450); 468 M->show(); 469 } 470 471 472 // Remove subscription 473 void EddPlot::RemoveService(QwtPlotCurve *Curve) { 474 475 for (int i=0; i<List.size(); i++) if (List[i].Curve == Curve) { 476 Handler->Unsubscribe(List[i].Name, this, List[i].Index); 477 List.removeAt(i); 478 DeleteCurve(Curve); 479 break; 480 } 483 481 } 484 482 … … 543 541 StatisticsAction->setCheckable(true); 544 542 Menu->addAction("Zoom out", this, SLOT(MenuZoomOut())); 545 Menu->addAction("Single trace", this, SLOT(MenuSingleTrace()));546 543 Menu->addSeparator(); 547 544 Menu->addAction("Set update rate", this, SLOT(MenuSetUpdateRate())); … … 561 558 EddBasePlot::~EddBasePlot() { 562 559 563 for (int i=0; i<Items.size(); i++) delete Items[i].Signal;564 560 delete Grid; 565 561 } … … 739 735 // Selection region outside all axis? 740 736 if (R.right() < 0 && R.top() > plotLayout()->canvasRect().height()) return; 737 738 // If selected rectangle completely inside canvas taken care of by zoomer 739 if (plotLayout()->canvasRect().contains(P.boundingRect())) return; 741 740 742 741 // Rescale both axis if selected rectangle encompasses canvas completely … … 803 802 } 804 803 805 // Remove all items except one 806 void EddBasePlot::MenuSingleTrace() { 807 808 while (Items.size() > 1) { 809 DeleteCurve(Items.last().Signal); 810 delete Items.last().Signal; 811 Items.takeLast(); 804 805 // Remove item 806 void EddBasePlot::DeleteCurve(QwtPlotCurve *Curve) { 807 808 for (int i=0; i<Items.size(); i++) if (Items[i].Signal == Curve) { 809 delete Curve; 810 Items.takeAt(i); 811 break; 812 812 } 813 813 UpdatePlot(); … … 893 893 } 894 894 895 896 //////////////// 897 // Edd Legend // 898 //////////////// 899 900 EddLegend::EddLegend(QwtPlotCurve *Curve, EddPlot *Plot): Curve(Curve), Plot(Plot) { 901 902 // Context menu 903 Menu = new QMenu(this); 904 Menu->addAction("Open in new history", this, SLOT(MenuOpenHistory())); 905 Menu->addAction("Copy service", this, SLOT(MenuCopyService())); 906 Menu->addAction("Normal line", this, SLOT(MenuNormalLine())); 907 Menu->addAction("Thick line", this, SLOT(MenuThickLine())); 908 Menu->addAction("Remove curve", this, SLOT(MenuRemove())); 909 } 910 911 // 912 // Opening context menu 913 // 914 void EddLegend::contextMenuEvent(QContextMenuEvent *Event) { 915 916 Menu->exec(Event->globalPos()); 917 } 918 919 // Handling of mouse press event: Register start position for drag 920 void EddLegend::mousePressEvent(QMouseEvent *Event) { 921 922 if (Event->button() == Qt::LeftButton) dragStart = Event->pos(); 923 } 924 925 // Handling of dragging (Drag and MimeData will be deleted by Qt) 926 void EddLegend::mouseMoveEvent(QMouseEvent *Event) { 927 928 if ((Event->buttons() & Qt::LeftButton) == 0) return; 929 if ((Event->pos()-dragStart).manhattanLength() < QApplication::startDragDistance()) return; 930 931 QString D(text().text()); 932 D.replace(':',' '); 933 934 QDrag *Drag = new QDrag(this); 935 QMimeData *MimeData = new QMimeData; 936 QByteArray Data; 937 MimeData->setData("Edd/Service", Data.append(D)); 938 Drag->setMimeData(MimeData); 939 Drag->exec(); 940 } 941 942 // Handling of mouse release event: Open history 943 void EddLegend::mouseReleaseEvent(QMouseEvent *Event) { 944 945 if (Event->button() != Qt::LeftButton) return; 946 947 QString D(text().text()); 948 D.replace(':',' '); 949 QStringList A = D.split(" "); 950 951 OpenHistory(A[0].toAscii().data(), A[1].toInt()); 952 } 953 954 // Menu: Open history plot 955 void EddLegend::MenuOpenHistory() { 956 957 QString D(text().text()); 958 D.replace(':',' '); 959 QStringList A = D.split(" "); 960 961 OpenHistory(A[0].toAscii().data(), A[1].toInt()); 962 } 963 964 // Menu: Copy service name 965 void EddLegend::MenuCopyService() { 966 967 QString D(text().text()); 968 D.replace(':',' '); 969 970 QMimeData *MimeData = new QMimeData; 971 QByteArray Data; 972 MimeData->setData("Edd/Service", Data.append(D)); 973 QApplication::clipboard()->setMimeData(MimeData); 974 } 975 976 // Menu: Normal line width 977 void EddLegend::MenuNormalLine() { 978 979 QPen Pen = Curve->pen(); 980 Pen.setWidth(1); 981 Curve->setPen(Pen); 982 Curve->plot()->replot(); 983 } 984 985 // Menu: Normal line width 986 void EddLegend::MenuThickLine() { 987 988 QPen Pen = Curve->pen(); 989 Pen.setWidth(4); 990 Curve->setPen(Pen); 991 Curve->plot()->replot(); 992 } 993 994 // Menu: Normal line width 995 void EddLegend::MenuRemove() { 996 997 emit(DeleteCurve(Curve)); 998 } 999 895 1000 ////////////////////////////////////// 896 1001 // History text box for DIM service // … … 905 1010 setAttribute(Qt::WA_DeleteOnClose); 906 1011 setAutoFillBackground(true); 907 setText("connecting...");1012 //setText("connecting..."); 908 1013 document()->setMaximumBlockCount(1000); 909 1014 Accumulate = true; 910 1015 1016 // Get history for this service 911 1017 if (!Pure) { 912 // Get history for this service 913 const struct EvidenceHistory::Item *R; 914 class EvidenceHistory *Hist; 915 916 if ((Hist = Handler->GetHistory(Name)) != NULL) { 917 while ((R=Hist->Next()) != NULL) { 918 moveCursor (QTextCursor::Start); 919 insertPlainText(QString("(")+QDateTime::fromTime_t(R->Time).toString()+") " + 920 QString::fromStdString(EvidenceServer::ToString(Hist->GetFormat(), (void *) R->Data, R->Size)) + "\n"); 921 } 922 } 923 Handler->DropHistory(Name); 1018 struct EddDim::HistItem Hist = Handler->GetHistory(Name); 1019 1020 for (int i=0; i<Hist.DataText.size(); i++) { 1021 moveCursor (QTextCursor::Start); 1022 insertPlainText(QString("(")+QDateTime::fromTime_t(Hist.DataText[i].first).toString()+") " + 1023 QString(Hist.DataRaw[i].second) + "\n"); 1024 } 924 1025 } 925 1026 … … 987 1088 EddDim::~EddDim() { 988 1089 989 QList<QString> L = HistoryList.keys();990 for(int i=0; i<L.size(); i++) delete HistoryList[L[i]].HistClass;991 1090 delete Mutex; 992 1091 } … … 1043 1142 1044 1143 QMutexLocker Locker(&IgnoreMutex); 1045 1046 1144 IgnoreMap[Name] = Ignore; 1047 1145 } 1048 1146 1049 1147 // Get history buffer 1050 class EvidenceHistory *EddDim::GetHistory(QString Name) { 1051 1052 // History already available (only request again if too old) 1053 if (HistoryList.contains(Name)) { 1054 HistoryList[Name].Count++; 1055 1056 if (time(NULL)-HistoryList[Name].LastUpdate < 5) { 1057 HistoryList[Name].HistClass->Rewind(); 1058 return HistoryList[Name].HistClass; 1059 } 1060 HistoryList[Name].LastUpdate = time(NULL); 1061 if (HistoryList[Name].HistClass->GetHistory()) return HistoryList[Name].HistClass; 1062 else return NULL; 1063 } 1064 1065 // Create new history class 1066 HistoryList[Name].HistClass = new EvidenceHistory(Name.toStdString()); 1067 HistoryList[Name].Count = 1; 1068 HistoryList[Name].LastUpdate = time(NULL); 1069 1070 if (HistoryList[Name].HistClass->GetHistory()) return HistoryList[Name].HistClass; 1071 else return NULL; 1072 } 1073 1074 // Reduce history usage counter 1075 void EddDim::DropHistory(QString Name) { 1076 1077 if (HistoryList.contains(Name)) HistoryList[Name].Count--; 1078 } 1148 struct EddDim::HistItem EddDim::GetHistory(QString Name) { 1149 1150 // History already available? 1151 if (HistoryList.contains(Name)) return HistoryList[Name]; 1152 1153 // Create history class to retrieve history data 1154 const struct EvidenceHistory::Item *R; 1155 class EvidenceHistory *Hist = new EvidenceHistory(Name.toStdString()); 1156 Hist->GetHistory(); 1157 HistoryList[Name].Time = time(NULL); 1158 HistoryList[Name].Format = Hist->GetFormat(); 1159 1160 while ((R = Hist->Next()) != NULL) { 1161 HistoryList[Name].DataRaw.push_back(QPair<int, QByteArray>(R->Time, QByteArray(R->Data, R->Size))); 1162 HistoryList[Name].DataText.push_back(QPair<int, QStringList>(R->Time, QString::fromStdString(EvidenceServer::ToString(Hist->GetFormat(), R->Data, R->Size)).split(' '))); 1163 } 1164 1165 delete Hist; 1166 1167 return HistoryList[Name]; 1168 } 1169 1079 1170 1080 1171 // Update throughput statistics and clear up history memory … … 1087 1178 QList<QString> L = HistoryList.keys(); 1088 1179 for(int i=0; i<L.size(); i++) { 1089 if ((HistoryList[L[i]].Count <= 0) && (time(NULL)-HistoryList[L[i]].LastUpdate) > 5) { 1090 delete HistoryList[L[i]].HistClass; 1091 HistoryList.remove(L[i]); 1092 } 1180 if ((time(NULL)-HistoryList[L[i]].Time) > 60) HistoryList.remove(L[i]); 1093 1181 } 1094 1182 -
fact/Evidence/GUI.h
r12894 r12940 11 11 #include <qwt_plot_magnifier.h> 12 12 #include <qwt_plot_panner.h> 13 #include <qwt_picker_machine.h> 13 14 #include <qwt_scale_engine.h> 14 15 #include <qwt_analog_clock.h> … … 40 41 virtual void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int=-1) = 0; 41 42 }; 43 42 44 43 45 // Base class for Edd plot … … 82 84 bool NewData; 83 85 QwtPlotCurve *NewCurve(QwtText); 86 void DeleteCurve(QwtPlotCurve *); 84 87 void ClearCurve(unsigned int); 85 88 void AddPoint(unsigned int, double, double); 86 virtual void DeleteCurve(QwtPlotCurve *) = 0;87 89 88 90 protected slots: … … 94 96 void MouseSelection(const QwtPolygon &); 95 97 void contextMenuEvent(QContextMenuEvent *); 96 void MenuSingleTrace();97 98 void MenuSetUpdateRate(); 98 99 void MenuZoomOut(); … … 180 181 QString Name; 181 182 int Index; 182 QwtPlotCurve *Signal; 183 QwtPlotCurve *Curve; 183 184 }; 184 185 QList<struct ItemDetails> List; … … 187 188 QwtLegend *Legend; 188 189 QTimer *SingleShot; 190 QPoint dragStart; 189 191 190 192 void dragEnterEvent(QDragEnterEvent *); … … 196 198 ~EddPlot(); 197 199 void AddService(QString, int = 0); 198 void DeleteCurve(QwtPlotCurve *);199 200 void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int = -1); 200 201 201 private slots: 202 void LegendClicked(QwtPlotItem *); 202 public slots: 203 void RemoveService(QwtPlotCurve *); 204 205 private slots: 203 206 void MenuPasteService(); 204 207 void MenuShowLastHour(); 205 208 void MenuShowLastDay(); 206 }; 207 209 void MenuAllAsText(); 210 }; 211 212 213 // Legend 214 class EddLegend: public QwtLegendItem { 215 Q_OBJECT 216 217 QMenu *Menu; 218 QPoint dragStart; 219 QwtPlotCurve *Curve; 220 EddPlot *Plot; 221 222 public: 223 EddLegend(QwtPlotCurve *, EddPlot *); 224 225 void contextMenuEvent(QContextMenuEvent *); 226 void mousePressEvent(QMouseEvent *); 227 void mouseReleaseEvent(QMouseEvent *); 228 void mouseMoveEvent(QMouseEvent *); 229 230 private slots: 231 void MenuOpenHistory(); 232 void MenuCopyService(); 233 void MenuNormalLine(); 234 void MenuThickLine(); 235 void MenuRemove(); 236 237 signals: 238 void DeleteCurve(QwtPlotCurve *); 239 }; 208 240 209 241 // Text history and output class … … 227 259 class EddDim: public QObject, public DimInfo { 228 260 Q_OBJECT 261 262 public: 263 struct HistItem { 264 int Time; 265 QVector<QPair<int, QByteArray> > DataRaw; 266 QVector<QPair<int, QStringList> > DataText; 267 QString Format; 268 }; 229 269 230 270 private: … … 238 278 QStringList Items; 239 279 }; 280 240 281 QMap<QString, struct Item> ServiceList; 241 282 QMap<QString, bool> IgnoreMap; 242 283 QMutex *Mutex, IgnoreMutex; 243 244 struct HistItem {245 int Count;246 int LastUpdate;247 class EvidenceHistory *HistClass;248 };249 284 QMap<QString, struct HistItem> HistoryList; 250 285 … … 265 300 void Unsubscribe (QString, class EddWidget *, int = -1); 266 301 void Ignore (QString, bool); 267 class EvidenceHistory *GetHistory(QString); 268 void DropHistory(QString); 302 struct HistItem GetHistory(QString); 269 303 270 304 signals: -
fact/Evidence/History.cc
r12910 r12940 52 52 53 53 DimInfo *ServerList; 54 DimService *Service; 54 55 char *Directory; 55 56 … … 72 73 EvidenceServer(SERVER_NAME), 73 74 Directory(Dir) { 74 75 75 // Get/initialize configuration 76 76 GetConfig("minchange", " "); … … 80 80 GetConfig("exclude", ""); 81 81 82 // Create services for information about subscribed services 83 Service = new DimService(SERVER_NAME "/Subscriptions", "C", NULL, 0); 84 82 85 // Subscribe to top-level server list 83 86 ServerList = new DimInfo((char *) "DIS_DNS/SERVER_LIST", NO_LINK, this); … … 90 93 delete ServerList; 91 94 while (Map.size() != 0) RemoveService((*Map.begin()).first); 95 96 delete Service; 92 97 } 93 98 … … 96 101 void History::infoHandler() { 97 102 103 static string List; 104 98 105 DimInfo *I = getInfo(); 99 106 100 107 // Check if service available 101 108 if (!ServiceOK(I)) return; 102 109 103 110 // ====== Part A: Handle service subscriptions === 104 111 … … 138 145 Name = strtok(NULL, "|"); 139 146 } 147 148 // Update service subscription list 149 static stringstream Stream; 150 151 for (map<string, struct Item>::const_iterator i=Map.begin(); i!=Map.end(); i++) { 152 Stream << i->first << ':' << i->second.MinAbsChange << '|'; 153 } 154 List = Stream.str(); 155 Service->updateService((void *) List.c_str(), List.size()+1); 156 140 157 return; 141 158 } -
fact/Evidence/readme.txt
r12910 r12940 61 61 value of indices a to b) 62 62 20/2/2012 Disabled padding per default in Evidence class constructor, and also in History and DColl 63 servers. EvidenceServer::ToString() can because of this now handle all format strings. 63 servers. EvidenceServer::ToString() can because of this now handle all format strings. 64 24/2/2012 Improved interactive behaviour of legend items (drag&drop, context menu). Handling of histories in 65 Edd much faster now. Made a new version Edd:LP for La Palma. History server publishes a list of 66 services subscribed to.
Note:
See TracChangeset
for help on using the changeset viewer.