Index: fact/Evidence/GUI.cc
===================================================================
--- fact/Evidence/GUI.cc	(revision 11289)
+++ fact/Evidence/GUI.cc	(revision 11360)
@@ -1,3 +1,2 @@
-
 /* ============================================================ 
 
@@ -28,5 +27,6 @@
 
   // Check if history service available
-  if (Hist == NULL || Hist->GetFormat() == NULL) {
+  if (strcmp(Service, "Edd/Rate_kBSec") == 0) Format = "F";
+  else if (Hist == NULL || Hist->GetFormat() == NULL) {
 	QMessageBox::warning(NULL, "Edd Message", QString("Could not retrieve history for service ") + Service ,QMessageBox::Ok);
   }
@@ -44,4 +44,5 @@
   M->setStatusBar(new QStatusBar(M));
   M->setAttribute(Qt::WA_DeleteOnClose);
+  M->setWindowTitle("Edd History - " + QString(Service));
   
   QWidget *W;
@@ -63,5 +64,5 @@
   QString Status;
 
-  if (Index != -1) Name = Name + "(" + QString::number(Index) + ")";
+  if (Index != -1) Name = Name + "[" + QString::number(Index) + "]";
 
   if (Time == -1) Status = QString("%1:  unavailable").arg(Name);
@@ -89,11 +90,8 @@
   setFrame(false);
   setAttribute(Qt::WA_DeleteOnClose);
-  setText("connecting...");
-  
-  // Connect to DIM handler
-  if (connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString)), Qt::QueuedConnection) == false) {
-    printf("Failed connection for %s\n", Name.toAscii().data());
-  }
-
+  QPalette Pal = palette();  
+  Pal.setColor(QPalette::Base, Qt::lightGray);
+  setPalette(Pal);
+  
   // Context menu
   Menu = new QMenu(this);
@@ -103,5 +101,5 @@
 
   // Subscribe to service
-  Handler->Subscribe(Name);
+  Handler->Subscribe(Name, this, Index);
 }
 
@@ -109,15 +107,13 @@
 EddLineDisplay::~EddLineDisplay() {
 
-  Handler->Unsubscribe(ServiceName);
+  Handler->Unsubscribe(ServiceName, this);
 }
 
 // Update widget
-void EddLineDisplay::Update(QString Name, int Time, QByteArray, QString Format, QString Text) {
-
-  if (ServiceName != Name) return;
+void EddLineDisplay::Update(const QString &, int Time, const QByteArray &, const QString &Format, const QString &Text, int) {
 
   // Check if service available
   QPalette Pal = palette();  
-  if (!SetStatus(this, Name, Time, Format, Index)) {
+  if (!SetStatus(this, ServiceName, Time, Format, Index)) {
     setText("n/a");
     Pal.setColor(QPalette::Base, Qt::lightGray);
@@ -128,5 +124,5 @@
 
   // Message service backgound colour determined by severity 
-  if (Name.endsWith("/Message")) {
+  if (ServiceName.endsWith("/Message")) {
     switch (Text.section(' ', 0, 0).toInt()) {
       case 0:  Pal.setColor(QPalette::Base, Qt::white); break;
@@ -136,9 +132,7 @@
       default: break;
     }
-	Text = Text.section(' ', 1);
-  }
-  else if (Format[0].toUpper() != 'C' && Format != "I:1;C") Text = Text.section(' ', Index, Index);
-
-  if (!ShowAsTime) setText(Text);
+	setText(Text.section(' ', 1));
+  }
+  else if (!ShowAsTime) setText(Text);
   else setText(QDateTime::fromTime_t(Text.toInt()).toString());
 
@@ -162,5 +156,5 @@
 
   // If not, open new plot
-  EddLineDisplay::MenuOpenHistory();
+  MenuOpenHistory();
 }
 
@@ -335,9 +329,4 @@
   connect(this, SIGNAL(legendClicked (QwtPlotItem *)), SLOT(LegendClicked(QwtPlotItem *)));
   
-  // Connect to DIM handler
-  if (connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString)), Qt::QueuedConnection) == false) {
-    printf("Failed connection for %s\n", Service.toAscii().data());
-  }
-
   // Additonal context menu items
   QAction* Action = Menu->addAction("Paste service", this, SLOT(MenuPasteService()));
@@ -380,5 +369,5 @@
 
   N.Name = Name;
-  N.Signal = NewCurve(Name+"("+QString::number(Index)+")");
+  N.Signal = NewCurve(Name+"["+QString::number(Index)+"]");
   N.Index = Index;
   List.append(N);
@@ -404,5 +393,5 @@
   }
   Handler->DropHistory(Name);
-  Handler->Subscribe(Name);
+  Handler->Subscribe(Name, this, Index);
   
   SingleShot->start(100);
@@ -410,13 +399,14 @@
 
 // Update widget (must happen in GUI thread)
-void EddPlot::Update(QString Name, int Time, QByteArray, QString Format, QString Text) {
-
-  for (int ItemNo=0; ItemNo<List.size(); ItemNo++) if (List[ItemNo].Name == Name) {
+void EddPlot::Update(const QString &Name, int Time, const QByteArray &, const QString &Format, const QString &Text, int Index) {
+
+  for (int ItemNo=0; ItemNo<List.size(); ItemNo++) if (List[ItemNo].Name==Name && List[ItemNo].Index==Index) {
 
  	// Append data if service available
 	if (SetStatus(this, Name, Time, Format)) {
-	  QString Txt = Text;
-	  Txt = Txt.section(' ', List[ItemNo].Index, List[ItemNo].Index);
-      AddPoint(ItemNo, Time, atof(Txt.toAscii().data()));
+	  //QString Txt = Text;
+	  //Txt = Txt.section(' ', List[ItemNo].Index, List[ItemNo].Index);
+      //AddPoint(ItemNo, Time, atof(Txt.toAscii().data()));
+      AddPoint(ItemNo, Time, atof(Text.toAscii().data()));
 	}
 
@@ -479,5 +469,5 @@
 
   setAxisScale(QwtPlot::xBottom, time(NULL)-60*60, time(NULL)+60);
-  setAxisAutoScale(QwtPlot::yLeft);
+  //setAxisAutoScale(QwtPlot::yLeft);
   replot();
 }
@@ -486,5 +476,5 @@
 
   setAxisScale(QwtPlot::xBottom, time(NULL)-24*3600, time(NULL)+3600);
-  setAxisAutoScale(QwtPlot::yLeft);
+  //setAxisAutoScale(QwtPlot::yLeft);
   replot();
 }
@@ -495,5 +485,5 @@
 
   for (int i=0; i<List.size(); i++) if (List[i].Signal == Curve) {
-    Handler->Unsubscribe(List[i].Name);
+    Handler->Unsubscribe(List[i].Name, this);
     List.removeAt(i);
   }
@@ -926,9 +916,4 @@
   Accumulate = true;
   
-  // Connect to DIM handler
-  if (connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString)), Qt::QueuedConnection) == false) {
-    printf("Failed connection for %s\n", Name.toAscii().data());
-  }
-
   if (!Pure) {
 	// Get history for this service
@@ -947,5 +932,5 @@
 
   // DIM client
-  Handler->Subscribe(Name);
+  Handler->Subscribe(Name, this);
 }
 
@@ -953,12 +938,11 @@
 EddText::~EddText() {
 
-  Handler->Unsubscribe(Name);
+  Handler->Unsubscribe(Name, this);
 }
 
 
 // Update widget (must happen in GUI thread)
-void EddText::Update(QString Name, int Time, QByteArray, QString Format, QString Text) {
-
-  if (this->Name != Name) return;
+void EddText::Update(const QString &, int Time, const QByteArray &, const QString &Format, const QString &Text, int) {
+
   QPalette Pal = palette();  
 
@@ -992,7 +976,7 @@
 EddDim::EddDim() {
 
-  Mutex = new QMutex(QMutex::Recursive);
   Volume = 0;
   Period = 10;
+  Mutex = new QMutex(QMutex::Recursive);
 
   // Timer to calculate data rates
@@ -1002,12 +986,7 @@
 
   // Connect to DIM handler
-  if (connect(this, SIGNAL(INT(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString))) == false) {
+  if (connect(this, SIGNAL(INT(QString, int, QByteArray, QString)), SLOT(Update(QString, int, QByteArray, QString))) == false) {
     printf("Failed connection in EddDim()\n");
   }
-
-  // To ensure responsiveness of GUI, subscriptions handled only when no GUI events (timeout 0)
-  Timer = new QTimer(this);
-  connect(Timer, SIGNAL(timeout()), SLOT(MakeSubscriptions()));
-  Timer->start();
 }
 
@@ -1017,31 +996,19 @@
   QList<QString> L = HistoryList.keys();
   for(int i=0; i<L.size(); i++) delete HistoryList[L[i]].HistClass;
-
   delete Mutex;
 }
 
-// Subscribe to DIM service (actual subscription handled in worker thread below)
-void EddDim::Subscribe(QString Name) {
+// Subscribe to DIM service
+void EddDim::Subscribe(QString Name, class EddWidget *Instance, int Index) {
 
   // Lock before accessing list
   QMutexLocker Locker(Mutex);
-  WaitingList.append(Name);
-}
-
-// Subscriptions handled only when no GUI events waiting (launched by timer, see constructor)
-void EddDim::MakeSubscriptions() {
-
-  // Lock before accessing list
-  QMutexLocker Locker(Mutex);
-
-  if (WaitingList.isEmpty()) return;
-
-  QString Name = WaitingList.first();
-  WaitingList.removeFirst();
-
-  // If already subscribed to service, increase usage count
+
+  // Check if already subscribed to service
   if (ServiceList.contains(Name)) {
-	ServiceList[Name].Count++;
-	//YEP(Name, ServiceList[Name].TimeStamp, ServiceList[Name].ByteArray, ServiceList[Name].Format, ServiceList[Name].Text);
+	ServiceList[Name].Subscribers[Instance] = Index;
+	if (Index>=0 && Index<ServiceList[Name].Items.size()) Instance->Update(Name, ServiceList[Name].TimeStamp, ServiceList[Name].ByteArray, ServiceList[Name].Format, ServiceList[Name].Items[Index]);
+	else Instance->Update(Name, ServiceList[Name].TimeStamp, ServiceList[Name].ByteArray, ServiceList[Name].Format, ServiceList[Name].Text);
+
 	return;
   }
@@ -1050,22 +1017,34 @@
   ServiceList[Name].ByteArray = QByteArray();
   ServiceList[Name].TimeStamp = -1;
-  ServiceList[Name].Count = 1;
+  ServiceList[Name].Subscribers[Instance] = Index;
   ServiceList[Name].DIMService = new DimStampedInfo(Name.toAscii().data(), INT_MAX, NO_LINK, this);
 }
 
 
-// Unsubsribe from DIM service
-void EddDim::Unsubscribe(QString Name) {
+// Unsubscribe from DIM service
+void EddDim::Unsubscribe(QString Name, class EddWidget *Instance) {
 
   // Lock before accessing list
   QMutexLocker Locker(Mutex);
 
-  if (ServiceList.contains(Name)) ServiceList[Name].Count--;
-
-  if (ServiceList[Name].Count == 0) {
+  if (!ServiceList.contains(Name)) return;
+  
+  if (ServiceList[Name].Subscribers.contains(Instance)) {
+	ServiceList[Name].Subscribers.remove(Instance);
+  }
+
+  if (ServiceList[Name].Subscribers.isEmpty()) {
 	delete ServiceList[Name].DIMService;
 	ServiceList.remove(Name);
 	return;
   }
+}
+
+// Ignore service in update
+void EddDim::Ignore(QString Name, bool Ignore) {
+
+  QMutexLocker Locker(&IgnoreMutex);
+
+  IgnoreMap[Name] = Ignore;
 }
 
@@ -1118,51 +1097,44 @@
   float Rate = Volume/1024.0/Period;
   Volume = 0;
-  YEP("Edd/Rate_kBSec", time(NULL), QByteArray::number(Rate), "F", QString::number(Rate));
-}
-
-// Force reemit of all buffered DIM data (work around for widget update problem)
-void EddDim::ForceEmit() {
+
+  // No unlock because Mutex is recursive  
+  Update("Edd/Rate_kBSec", time(NULL), QByteArray((char *) &Rate, sizeof(Rate)), "F");
+}
+
+
+// Store service information for usage by Subscribe(), update statistics and emit signal to widgets
+void EddDim::Update(QString Name, int Time, QByteArray Data, QString Format) {
 
   // Lock before accessing list
   QMutexLocker Locker(Mutex);
 
-  QMap<QString, struct Item>::const_iterator i = ServiceList.constBegin();
-
-  while (i != ServiceList.constEnd()) {
-	YEP(i.key(), i.value().TimeStamp, i.value().ByteArray, i.value().Format, i.value().Text);
-     ++i;
-  }
-}
-
-// Store service information for usage by Subscribe(), update statistics and emit signal to widgets
-void EddDim::Update(QString Name, int Time, QByteArray Data, QString Format, QString Text) {
-
-  // Lock before accessing list
-  QMutexLocker Locker(Mutex);
+  Volume += Data.size();
 
   // Store service data
   if (ServiceList.contains(Name)) {
-	  ServiceList[Name].TimeStamp = Time;
-	  ServiceList[Name].ByteArray = Data;
-	  ServiceList[Name].Format = Format;
-	  ServiceList[Name].Text = Text;
-  }
-
-  // Emit signal to all widgets
-  YEP(Name, Time, Data, Format, Text);
-}
-
-// Handling of DIM service update
-// No locking allowed. Signal triggers only EddDim::Update() when the main event loop is idle.
+	ServiceList[Name].TimeStamp = Time;
+	ServiceList[Name].ByteArray = Data;
+	ServiceList[Name].Format = Format;
+	ServiceList[Name].Text = QString::fromStdString(EvidenceServer::ToString(Format.toAscii().data(), Data.data(), Data.size()));
+	ServiceList[Name].Items = ServiceList[Name].Text.split(" ");
+
+	QMap<class EddWidget *, int>::const_iterator i = ServiceList[Name].Subscribers.constBegin();
+	while (i != ServiceList[Name].Subscribers.constEnd()) {
+	  if (i.value() >=0 && i.value() < ServiceList[Name].Items.size()) i.key()->Update(Name, Time, Data, Format, ServiceList[Name].Items[i.value()], i.value());
+	  else i.key()->Update(Name, Time, Data, Format, ServiceList[Name].Text, i.value());
+	  i++;
+	}
+  }  
+}
+
+// Handling of DIM service update (Data asynchronouly send to EddDim::Update())
 void EddDim::infoHandler() {
 
+  QMutexLocker Locker(&IgnoreMutex);
+  bool Ignore = IgnoreMap[getInfo()->getName()]; 
+  Locker.unlock();
+
   if (!EvidenceServer::ServiceOK(getInfo())) INT(getInfo()->getName(), -1);
-  else {
-    // Signal to EddDim::Update()
-	INT(getInfo()->getName(), getInfo()->getTimestamp(), QByteArray((char *) getInfo()->getData(), 
-		getInfo()->getSize()), getInfo()->getFormat(), QString::fromStdString(EvidenceServer::ToString(getInfo()->getFormat(), getInfo()->getData(), getInfo()->getSize())));
-	// No mutex protection for Volume (otherwise must be in Update())
-	Volume += getInfo()->getSize();
-  }
+  else if (!Ignore) INT(getInfo()->getName(), getInfo()->getTimestamp(), QByteArray((char *) getInfo()->getData(), getInfo()->getSize()), getInfo()->getFormat());
 }
 
Index: fact/Evidence/GUI.h
===================================================================
--- fact/Evidence/GUI.h	(revision 11289)
+++ fact/Evidence/GUI.h	(revision 11360)
@@ -34,4 +34,11 @@
 bool SetStatus(QWidget *, QString, int, QString, int = -1);
 
+// General Edd Widget: has Update() method called by DIM interface
+class EddWidget {
+
+  public:
+  	virtual void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int=-1) = 0;
+};
+
 // Base class for Edd plot
 // DeleteCurve() is pure virtual and needs to be implemented iin the application class
@@ -97,5 +104,5 @@
 		  
 // General indicator for DIM service
-class EddLineDisplay: public QLineEdit {
+class EddLineDisplay: public QLineEdit, public EddWidget {
     Q_OBJECT
 
@@ -112,11 +119,11 @@
 	
   public:
-    EddLineDisplay(QString, int=0, QWidget * = NULL);
+    EddLineDisplay(QString, int=-1, QWidget * = NULL);
     ~EddLineDisplay();
+	void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int = -1);
 
 	bool ShowAsTime;
 	
   private slots:
-	void Update(QString, int, QByteArray, QString, QString);
     void contextMenuEvent(QContextMenuEvent *);    
     void MenuOpenHistory();
@@ -143,5 +150,5 @@
 
 // Graph class for history display 
-class EddPlot: public EddBasePlot {
+class EddPlot: public EddBasePlot, public EddWidget {
     Q_OBJECT
 
@@ -190,7 +197,7 @@
     void AddService(QString, int = 0);
 	void DeleteCurve(QwtPlotCurve *);
-
-  private slots:
-	void Update(QString, int, QByteArray, QString, QString);
+	void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int = -1);
+
+  private slots:
 	void LegendClicked(QwtPlotItem *);
     void MenuPasteService();
@@ -201,5 +208,5 @@
 
 // Text history and output class
-class EddText: public QTextEdit {
+class EddText: public QTextEdit, public EddWidget {
   Q_OBJECT
 
@@ -211,9 +218,7 @@
     EddText(QString, bool = false, QWidget * = NULL);
     ~EddText();
+	void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int = -1);
 
 	bool Accumulate;
-
-  private slots:
-	void Update(QString, int, QByteArray, QString, QString);
 };
 
@@ -226,13 +231,14 @@
 	struct Item {
 	  DimStampedInfo *DIMService;
-	  int Count;
+	  QMap<class EddWidget *, int> Subscribers;
 	  int TimeStamp;
 	  QByteArray ByteArray;
 	  QString Format;
 	  QString Text;
+	  QStringList Items;
 	};
     QMap<QString, struct Item> ServiceList;
-    QMutex *Mutex;
-	QList<QString> WaitingList;
+	QMap<QString, bool> IgnoreMap;
+    QMutex *Mutex, IgnoreMutex;
 
 	struct HistItem {
@@ -249,7 +255,6 @@
 
   private slots:
-	void Update(QString, int, QByteArray, QString, QString);
+	void Update(QString, int, QByteArray, QString);
 	void UpdateStatistics();
-	void MakeSubscriptions();
 
   public:
@@ -257,13 +262,12 @@
     ~EddDim();
 
-	void Subscribe(QString);
-	void Unsubscribe (QString);
+	void Subscribe(QString, class EddWidget *, int = -1);
+	void Unsubscribe (QString, class EddWidget *);
+	void Ignore (QString, bool);
 	class EvidenceHistory *GetHistory(QString);
 	void DropHistory(QString);
-	void ForceEmit();
 
   signals:
-    void YEP(QString, int, QByteArray = QByteArray(), QString = QString(), QString = QString());
-    void INT(QString, int, QByteArray = QByteArray(), QString = QString(), QString = QString());
+    void INT(QString, int, QByteArray = QByteArray(), QString = QString());
 };
 
Index: fact/tools/Edd/Edd.cc
===================================================================
--- fact/tools/Edd/Edd.cc	(revision 11289)
+++ fact/tools/Edd/Edd.cc	(revision 11360)
@@ -111,14 +111,12 @@
   
 // Update event buffer
-void EventScope::Update(QString Name, int Time, QByteArray Data, QString Format, QString) {
-  
-  if (Name != this->Name) return;
+void EventScope::Update(const QString &, int Time, const QByteArray &Data, const QString &Format, const QString &, int) {
 
   // Check if service available
   if (!SetStatus(this, Name, Time, Format)) return;
   if (Data.size() < (int) sizeof(RunHeader)) return;
-  
-  // Disconnect while processing to avoid queing of events
-  disconnect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), this, SLOT(Update(QString, int, QByteArray, QString, QString)));
+
+  // Ignore further data while processing this one
+  Handler->Ignore(Name, true);
   
   // Clear temporary file and write event data to this file
@@ -132,7 +130,9 @@
   // Open temporary raw data file
   OpenRawFile(File.fileName());
- 
-  // Reconnect after processing
-  connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString)));
+
+
+  // Process all pending events, then allow data again
+  QApplication::processEvents();
+  Handler->Ignore(Name, false);
 }
 
@@ -191,5 +191,5 @@
   
   // Display first event
-  NewEventNum(0);
+  NewEventNum(DAQPage->Channel->value());
 }
 
@@ -316,12 +316,7 @@
 void EventScope::SetActive(bool State) {
 
-  if (State && !Active) {
-	Handler->Subscribe(DRSBoard+"/EventData");
-	connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString)));
-  }
-  if (!State && Active) {
-	Handler->Unsubscribe(DRSBoard+"/EventData");
-	disconnect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), this, SLOT(Update(QString, int, QByteArray, QString, QString)));
-  }
+  if (State && !Active) Handler->Subscribe(DRSBoard+"/EventData", this, -1);
+  if (!State && Active) Handler->Unsubscribe(DRSBoard+"/EventData", this);
+
   Active = State;
 }
@@ -929,7 +924,4 @@
   connect(Timer, SIGNAL(timeout()), this, SLOT(CheckAlarm()));
   Timer->start(5000);
-
-  // Force update of all widgets constructed (in thread for GUI responsiveness) 
-  QtConcurrent::run(Handler, &EddDim::ForceEmit);
 }  
     
Index: fact/tools/Edd/Edd.h
===================================================================
--- fact/tools/Edd/Edd.h	(revision 11289)
+++ fact/tools/Edd/Edd.h	(revision 11360)
@@ -11,5 +11,5 @@
 
 // Event oscilloscope
-class EventScope: public EddBasePlot, public PixelMap {
+class EventScope: public EddBasePlot, public PixelMap, public EddWidget {
   Q_OBJECT
 
@@ -34,5 +34,6 @@
     EventScope(class TP_DAQ *, QWidget * = NULL);
     ~EventScope();
-	
+
+	void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int=-1);
 	void UpdateFirst(int, int, int);
 	void AddTrace(int, int, int);
@@ -43,5 +44,4 @@
 
   private slots:
-	void Update(QString, int, QByteArray, QString, QString);
 	void PlotTraces();
 	void DeleteCurve(QwtPlotCurve *);
