Index: fact/tools/Edd/Edd.cc
===================================================================
--- fact/tools/Edd/Edd.cc	(revision 10642)
+++ fact/tools/Edd/Edd.cc	(revision 10904)
@@ -22,11 +22,22 @@
 
 // Constructor
-EventScope::EventScope(QWidget *P): EddBasePlot(P), PixelMap(PixelMapText, false) {
-
+EventScope::EventScope(class TP_DAQ *Page, QWidget *P): EddBasePlot(P), PixelMap(PixelMapText, false) {
+
+  // Initalise
+  LastPath = ".";
   Name = DRSBoard+"/EventData";
-
+  DAQPage = Page;
+  Active = false;
+
+  // Open temporary files
   Tmpfile = tmpfile();
   if(Tmpfile == NULL) {
     QMessageBox::warning(this, "Edd Message", "Could not open temporary file.", QMessageBox::Ok);
+	return;
+  }
+
+  if (!File.open()) {
+	QMessageBox::warning(this, "Edd Message","Could not open temporary file.",QMessageBox::Ok);
+	return;
   }
 
@@ -49,8 +60,4 @@
   AddTrace(0,0,0);
 
-  // Connect to DIM handler
-  if (connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString))) == false) {
-    printf("Failed connection for %s\n", Name.toAscii().data());
-  }
   SetActive(true);
 }
@@ -116,10 +123,6 @@
   disconnect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), this, SLOT(Update(QString, int, QByteArray, QString, QString)));
   
-  // Open tempory file and write event data to this file
-  QTemporaryFile File;
-  if (!File.open()) {
-	QMessageBox::warning(this, "Edd Message","Could not open temporary file.",QMessageBox::Ok);
-	return;
-  }
+  // Clear temporary file and write event data to this file
+  File.resize(0);
   if (File.write(Data) == -1) {
 	QMessageBox::warning(this, "Edd Message","Could not write data to temporary file.",QMessageBox::Ok);
@@ -127,23 +130,67 @@
   }
 
+  // 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)));
+}
+
+
+// New event number selected in raw data browser
+void EventScope::OpenRawFile(QString Filename) {
+
+  // Request filename to open if none given
+  if (Filename.isEmpty()) {
+    Filename = QFileDialog::getOpenFileName(this, "Open raw file", LastPath, "Raw data files (*.raw);; All files (*)");
+    if (Filename == NULL) return;
+  }
+
+  DAQPage->FilenameBox->setText(Filename);
+  LastPath = QFileInfo(Filename).absolutePath();
+  
   // Prepare temporary file for run header  
   ftruncate(fileno(Tmpfile), 0);
   rewind(Tmpfile);
 
-  // Open file with RawDataCTX
-  switch (ErrCode = RD->OpenDataFile(File.fileName().toAscii().data(), Tmpfile)) {
-    case CTX_FOPEN:		QMessageBox::warning(this, "Edd Message","Could not open file.",QMessageBox::Ok);
-						return;
-    case CTX_RHEADER:	QMessageBox::warning(this, "Edd Message","Could not read run header.",QMessageBox::Ok);
-		      			return;
-    case CTX_BSTRUCT:	QMessageBox::warning(this, "Edd Message","Could not read board structures.",QMessageBox::Ok);
-						return;
-	default: break;
-  }
-
-  // Emit signal containing run header
+  // Write run header to temporary file  
+  switch (ErrCode = RD->OpenDataFile(Filename.toAscii().data(), Tmpfile)) {
+    case CTX_FOPEN:   QMessageBox::warning(this, "Edd Message","Could not open file.",QMessageBox::Ok);
+                      return;
+    case CTX_RHEADER: QMessageBox::warning(this, "Edd Message","Could not read run header.",QMessageBox::Ok);
+					  return;
+    case CTX_BSTRUCT: QMessageBox::warning(this, "Edd Message","Could not read board structures.",QMessageBox::Ok);
+					  return;
+    default:		  break;
+  }
+  RunHeader *R = RD->RHeader;
+
+  if (R->MagicNum == MAGICNUM_OPEN) {
+    QMessageBox::warning(this, "Edd Message","Magic number in run header indicates that the file has not been closed properly.",QMessageBox::Ok);
+  }
+  if (R->MagicNum == MAGICNUM_ERROR) {
+    QMessageBox::warning(this, "Edd Message","Magic number in run header indicates that an error occurred while writing the file.",QMessageBox::Ok);
+  }
+  
+  // Print run header to display
   rewind(Tmpfile);
-  QTextStream Stream(Tmpfile);
-  emit(RunHeaderChanged(Stream.readAll()));
+  QTextStream in(Tmpfile);
+  QString text = in.readAll();
+  DAQPage->RunHeaderDisplay->setPlainText(text);
+
+  // Update spin box ranges on DAQ page  
+  DAQPage->Event->setRange(0, R->Events-1);
+  DAQPage->Event->setEnabled(true);
+
+  DAQPage->Channel->setRange(0, R->NChannels-1);
+  DAQPage->Chip->setRange(0, R->NChips-1);
+  DAQPage->Board->setRange(0, R->NBoards-1);
+  
+  // Display first event
+  NewEventNum(0);
+}
+
+// New event number selected in raw data browser
+void EventScope::NewEventNum(int Event) {
 
   // Prepare temporary file for event header  
@@ -151,27 +198,13 @@
   rewind(Tmpfile);
 
-  // Write event header text to file
-  if (RD->ReadEvent(0, Tmpfile) != CTX_OK) {
-    QMessageBox::warning(this, "Edd Warning","Could not read event.",QMessageBox::Ok);
+  // Read event
+  if (RD->ReadEvent(Event, Tmpfile) != CTX_OK) {
+    QMessageBox::warning(this, "Edd Message","Could not read event.",QMessageBox::Ok);
+    DAQPage->EventHeaderDisplay->clear();
     return;
   }
-
-  // Add trigger cells to file
-  fprintf(Tmpfile, "\nTrigger cells:");
-  int *TrigCells = (int *) RD->Data;
-  for (unsigned int i=0; i<RD->RHeader->NBoards; i++) {
-    fprintf(Tmpfile, "\n Board %d   ", i);
-	for (unsigned int j=0; j<RD->RHeader->NChips; j++) fprintf(Tmpfile, "%d ", *(TrigCells++));
-  }
-
-  // Emit signal containing run header
-  rewind(Tmpfile);
-  emit(EventHeaderChanged(Stream.readAll()));
-
-  // Update display
+  
+  // Plot traces for event
   PlotTraces();
-  
-  // Reconnect after processing
-  connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString)));
 }
 
@@ -182,7 +215,19 @@
   unsigned int Cell, Trig;
   static int Last = 0;
-  
+
   // Only process if valid data in RawDataCTX class
   if (ErrCode != CTX_OK) return;
+
+  // Print event header and trigger cell information from event data
+  rewind(Tmpfile);
+  QTextStream in(Tmpfile);
+  QString text = in.readAll();
+  
+  text.append("\nTrigger cells: ");
+  for (unsigned int i=0; i<RD->RHeader->NBoards*RD->RHeader->NChips; i++) {
+    QString a;
+    text.append(a.sprintf("%d ", *((int *)RD->Data + i)));
+  }
+  DAQPage->EventHeaderDisplay->setPlainText(text);
   
   // Set x axis title
@@ -268,8 +313,12 @@
 void EventScope::SetActive(bool State) {
 
-  static bool Active = false;
-
-  if (State && !Active) Handler->Subscribe(DRSBoard+"/EventData");
-  if (!State && Active) Handler->Unsubscribe(DRSBoard+"/EventData");
+  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)));
+  }
   Active = State;
 }
@@ -494,5 +543,5 @@
 // Event scope page
 //
-TP_DAQ::TP_DAQ() {
+TP_DAQ::TP_DAQ(bool IsBrowser) {
 
   EddLineDisplay *Line;
@@ -501,29 +550,41 @@
   QGridLayout *Layout = new QGridLayout(this);
 
-  // Run-related information 
-  Line = new EddLineDisplay("drsdaq/RunNumber");
-  Line->setMaximumWidth(100);
-  Layout->addWidget(Line, 0, 1, 1, 1);      
-  Line = new EddLineDisplay(DRSBoard+"/EventNumber");
-  Line->setMaximumWidth(100);
-  Layout->addWidget(Line, 0, 2, 1, 1);      
-  Line = new EddLineDisplay("drsdaq/RunSizeMB");
-  Line->setMaximumWidth(100);
-  Layout->addWidget(Line, 0, 3, 1, 1);      
-  Line = new EddLineDisplay("drsdaq/FileSizeMB");
-  Line->setMaximumWidth(100);
-  Layout->addWidget(Line, 0, 4, 1, 1);      
-  Line = new EddLineDisplay("drsdaq/FileName");
-  Line->setMaximumWidth(200);
-  Layout->addWidget(Line, 0, 5, 1, 1);      
-
-  // Message service
-  Line = new EddLineDisplay(DRSBoard+"/Message");
-  Line->setMaximumWidth(200);
-  Layout->addWidget(Line, 1, 1, 1, 2);      
-
   // Event scope
-  Scope = new EventScope;
+  Scope = new EventScope(this);
   Scope->setMinimumWidth(700);
+
+  if (IsBrowser) Scope->SetActive(false);
+
+  // FilenameBox must exist also for online browser (but not added to layout)
+  FilenameBox = new QLineEdit();
+
+  if (!IsBrowser) {
+	// Message service
+	Line = new EddLineDisplay(DRSBoard+"/Message");
+	Line->setMinimumWidth(500);
+	Layout->addWidget(Line, 0, 1, 1, 6);      
+
+	// Run-related information 
+	Line = new EddLineDisplay(DRSBoard+"/EventNumber");
+	Line->setMaximumWidth(100);
+	Layout->addWidget(Line, 0, 8, 1, 1);      
+	Line = new EddLineDisplay(DRSBoard+"/FileSizeMB");
+	Line->setMaximumWidth(100);
+	Layout->addWidget(Line, 0, 9, 1, 1);      
+  }
+  else {
+  	// Filename box
+	Layout->addWidget(FilenameBox, 0, 1, 1, 6);      
+	connect(FilenameBox, SIGNAL(returnPressed()), SLOT(OpenDataFile()));
+	FilenameBox->setToolTip("Raw data file name");
+
+    // Browse botton
+	QToolButton *LoadButton = new QToolButton();
+	LoadButton->setToolButtonStyle (Qt::ToolButtonTextOnly);
+	LoadButton->setText("...");
+	Layout->addWidget(LoadButton, 0, 7, 1, 1);      
+	connect(LoadButton, SIGNAL(clicked()), Scope, SLOT(OpenRawFile()));
+	LoadButton->setToolTip("Open file dialog to select raw data file");
+  }
 
   // Text boxes for run and event header
@@ -538,20 +599,20 @@
   TabWidget->addTab(RunHeaderDisplay, "&Run Header");
   TabWidget->addTab(EventHeaderDisplay, "&Event Header");
-  Layout->addWidget(TabWidget, 2, 1, 6, 5);
+  Layout->addWidget(TabWidget, 1, 1, 7, 12);
 
   // Channel number 
   Channel = new QSpinBox;
   connect(Channel, SIGNAL(valueChanged(int)), SLOT(UpdateScope(int)));
-  Channel->setToolTip("DRS channel number");
+  Channel->setToolTip("Channel number");
 
   // Chip number 
   Chip = new QSpinBox;
   connect(Chip, SIGNAL(valueChanged(int)), SLOT(UpdateScope(int)));
-  Chip->setToolTip("DRS chip number");
+  Chip->setToolTip("Chip number");
 
   // Board number 
   Board = new QSpinBox;
   connect(Board, SIGNAL(valueChanged(int)), SLOT(UpdateScope(int)));
-  Board->setToolTip("DRS board number");
+  Board->setToolTip("Board number");
 
   // Pixel ID
@@ -562,4 +623,10 @@
   connect(PixelID, SIGNAL(valueChanged(int)), SLOT(TranslatePixelID(int)));
   PixelID->setToolTip("Pixel identification");
+
+  // Add trace permanently
+  QPushButton *Button = new QPushButton("Keep trace");
+  Button->setToolTip("Keep trace in display");
+  Button->setMaximumWidth(80);
+  connect(Button, SIGNAL(clicked()), SLOT(KeepCurrent()));
   
   // Layout of pixel addressing widgets
@@ -570,14 +637,13 @@
   FormLayout->addRow("Channel", Channel);
   FormLayout->addRow("Pixel ID", PixelID);
+  FormLayout->addRow("", Button);
   Layout->addLayout(FormLayout, 0, 0, 4, 1);
-  
-  // Add trace permanently
-  QPushButton *Button = new QPushButton("Keep trace");
-  Button->setToolTip("Keep trace in display");
-  Button->setMaximumWidth(80);
-  Layout->addWidget(Button, 4, 0);
-  connect(Button, SIGNAL(clicked()), SLOT(KeepCurrent()));
-
-  // Stop/start
+
+  // Spin box for event number 
+  Event = new QSpinBox;
+  Event->setToolTip("Event number");
+  Event->setEnabled (false);
+  
+  // Stop/start button
   StartStopButton = new QPushButton("Stop");
   StartStopButton->setToolTip("Start/stop display");
@@ -589,8 +655,17 @@
   StartStopButton->setPalette(Palette);
   StartStopButton->setFont(QFont("Times", 10, QFont::Bold));
-  Layout->addWidget(StartStopButton, 6, 0);
-  connect(StartStopButton, SIGNAL(toggled(bool)), SLOT(StartStop(bool)));
-
-
+
+  if (IsBrowser) {
+	FormLayout = new QFormLayout();
+	FormLayout->setRowWrapPolicy(QFormLayout::WrapAllRows);
+	FormLayout->addRow("Event Num", Event);
+	Layout->addLayout(FormLayout, 6, 0);
+	connect(Event, SIGNAL(valueChanged(int)), Scope, SLOT(NewEventNum(int)));
+  }
+  else {
+	Layout->addWidget(StartStopButton, 6, 0);
+	connect(StartStopButton, SIGNAL(toggled(bool)), SLOT(StartStop(bool)));
+  }
+  
   // Event display page
   EddWindow *New = new EddWindow("Pixel display", "Edd - Event display");
@@ -620,8 +695,5 @@
 
   // Connect slots for updating displays
-  connect(Scope, SIGNAL(RunHeaderChanged(QString)), RunHeaderDisplay, SLOT(setPlainText(QString)));
-  connect(Scope, SIGNAL(EventHeaderChanged(QString)), EventHeaderDisplay, SLOT(setPlainText(QString)));
-
-  StartStop(false);
+  if (!IsBrowser) StartStop(false);
   connect(Scope, SIGNAL(PixelData(QVector<double>)), SLOT(SetPixelData(QVector<double>)));
 
@@ -662,6 +734,12 @@
   Scope->SetActive(!State);
   StartStopButton->setText(State ? "Start" : "Stop");
-  if (!State) connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), Scope, SLOT(Update(QString, int, QByteArray, QString, QString)));
-  else disconnect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), Scope, SLOT(Update(QString, int, QByteArray, QString, QString)));
+  //if (!State) connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), Scope, SLOT(Update(QString, int, QByteArray, QString, QString)));
+  //else disconnect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), Scope, SLOT(Update(QString, int, QByteArray, QString, QString)));
+}
+
+// Open raw data file
+void TP_DAQ::OpenDataFile() {
+
+  Scope->OpenRawFile(FilenameBox->text());
 }
 
@@ -794,5 +872,5 @@
   TabWidget->setTabsClosable(true);
   connect(TabWidget, SIGNAL(tabCloseRequested(int)), SLOT(DetachTab(int)));
-  TabWidget->addTab(new TP_DAQ, "Event scope");
+  TabWidget->addTab(new TP_DAQ(false), "Event scope");
   TabWidget->addTab(new TP_FADctrl, "FADctrl");
   TabWidget->addTab(new TP_Bias, "Bias");
@@ -803,5 +881,5 @@
   // Set features of main window
   setStatusBar(new QStatusBar(this));
-  setWindowTitle("Edd - Evidence Data Display - Node: " + QString(getenv("DIM_DNS_NODE")));
+  setWindowTitle("Edd - Evidence Data Display - Node: " + QString(DimServer::getDnsNode()) + ":" + QString::number(DimServer::getDnsPort()));
   setCentralWidget(TabWidget);
 
@@ -809,4 +887,5 @@
   QMenu* Menu = menuBar()->addMenu("&Menu");
   Menu->addAction("New history plot", this, SLOT(MenuNewHistory()));
+  Menu->addAction("Raw data browser", this, SLOT(MenuRawDataBrowser()));
   Menu->addSeparator();
   Menu->addAction("About", this, SLOT(MenuAbout()));
@@ -820,5 +899,5 @@
   //setMaximumSize(QApplication::desktop()->screenGeometry(this).size()*0.9);
   TabWidget->resize(Size);
-TabWidget->setMaximumSize(QApplication::desktop()->screenGeometry(this).size()*0.9);
+  TabWidget->setMaximumSize(QApplication::desktop()->screenGeometry(this).size()*0.9);
   show();
 
@@ -867,6 +946,12 @@
 }
 
+// Raw data browser
+void GUI::MenuRawDataBrowser() {
+
+  DetachTab(0, true);
+}
+
 // Open tab as separate window
-void GUI::DetachTab(int Tab) {
+void GUI::DetachTab(int Tab, bool IsDAQBrowser) {
 
   QWidget *W = NULL;
@@ -877,9 +962,10 @@
 
   switch(Tab) {
-	case 0:	W = new TP_DAQ; break;
-	case 1: W = new TP_Bias; break;
-	case 2: W = new TP_Feedback; break;
-	case 3: W = new TP_Environment; break;
-	case 4: W = new TP_Evidence; break;
+	case 0:	W = new TP_DAQ(IsDAQBrowser); break;
+	case 1:	W = new TP_FADctrl; break;
+	case 2: W = new TP_Bias; break;
+	case 3: W = new TP_Feedback; break;
+	case 4: W = new TP_Environment; break;
+	case 5: W = new TP_Evidence; break;
 	default: break;
   }
@@ -892,7 +978,11 @@
 
   W->setParent(M);
+  W->resize(size());
   M->resize(size());
-  M->setWindowTitle("Edd - " + TabWidget->tabText(Tab));
+  if (!IsDAQBrowser) M->setWindowTitle("Edd - " + TabWidget->tabText(Tab));
+  else M->setWindowTitle("Edd - Raw Data Browser");
   M->show();
+  
+  return;
 }
 
Index: fact/tools/Edd/Edd.h
===================================================================
--- fact/tools/Edd/Edd.h	(revision 10642)
+++ fact/tools/Edd/Edd.h	(revision 10904)
@@ -7,4 +7,6 @@
 
 #define SVN_REVISION "$Revision: 10143 $"
+
+class TP_DAQ;
 
 // Event oscilloscope
@@ -20,13 +22,15 @@
     QList<struct ItemDetails> List;
 
+	class TP_DAQ *DAQPage;
     QString Name;
-	RawDataCTX *RD;
-	CTX_ErrCode ErrCode;
+	bool Active;
 	QAction *PhysPipeAction;
 	QAction *PersistanceAction;
 	FILE *Tmpfile;
+	QTemporaryFile File;
+	QString LastPath;
 
   public:
-    EventScope(QWidget * = NULL);
+    EventScope(class TP_DAQ *, QWidget * = NULL);
     ~EventScope();
 	
@@ -35,4 +39,6 @@
 	void SetActive(bool);
 	QString ToPixel(unsigned int, unsigned int, unsigned int, unsigned int);
+	RawDataCTX *RD;
+	CTX_ErrCode ErrCode;
 
   private slots:
@@ -40,8 +46,10 @@
 	void PlotTraces();
 	void DeleteCurve(QwtPlotCurve *);
+	void NewEventNum(int);
+
+  public slots:
+	void OpenRawFile(QString=QString());
 	
   signals:
-	void RunHeaderChanged(QString);
-	void EventHeaderChanged(QString);
 	void PixelData(QVector<double>);
 };
@@ -82,8 +90,4 @@
 
   private:
-	EventScope *Scope;
-    QPlainTextEdit *RunHeaderDisplay, *EventHeaderDisplay;
-
- 	QSpinBox *Channel, *Chip, *Board, *PixelID;
  	QFormLayout *FormLayout;
 	QWidget *Display;
@@ -98,8 +102,14 @@
 	void ShowPixelDisplay();
 	void SetPixelData(QVector<double>);
+	void OpenDataFile();
 
   public:
-	TP_DAQ();	
-	~TP_DAQ();	
+	TP_DAQ(bool);	
+	~TP_DAQ();
+	
+	EventScope *Scope;
+ 	QSpinBox *Channel, *Chip, *Board, *PixelID, *Event;
+    QPlainTextEdit *RunHeaderDisplay, *EventHeaderDisplay;
+	QLineEdit *FilenameBox;
 };
 
@@ -132,5 +142,6 @@
     void MenuAbout();
     void MenuNewHistory();
-	void DetachTab(int);
+    void MenuRawDataBrowser();
+	void DetachTab(int, bool=false);
 	void CheckAlarm();
 };
