MNE-CPP  beta 0.1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mainwindow.cpp
1 //=============================================================================================================
38 //*************************************************************************************************************
39 //=============================================================================================================
40 // INCLUDES
41 //=============================================================================================================
42 
43 #include "mainwindow.h"
44 
45 
46 //*************************************************************************************************************
47 //=============================================================================================================
48 // USED NAMESPACES
49 //=============================================================================================================
50 
51 using namespace MNEBrowseRawQt;
52 
53 
54 //*************************************************************************************************************
55 //=============================================================================================================
56 // DEFINE MEMBER METHODS
57 //=============================================================================================================
58 
59 MainWindow::MainWindow(QWidget *parent)
60 : QMainWindow(parent)
61 , m_qFileRaw("./MNE-sample-data/MEG/sample/sample_audvis_raw.fif")
62 , m_qSettings()
63 , m_rawSettings()
64 {
65  //setup MVC
66  setupModel();
67  setupDelegate();
68  setupView();
69  setupLayout();
70 
71  createMenus();
72 
73  createLogDockWindow();
74 
75  setWindow();
76  setWindowStatus();
77 }
78 
79 
80 //*************************************************************************************************************
81 
83 {
84 }
85 
86 
87 //*************************************************************************************************************
88 
89 void MainWindow::setupModel()
90 {
91 // m_pRawModel = new RawModel(this);
92  m_pRawModel = new RawModel(m_qFileRaw,this);
93 }
94 
95 
96 //*************************************************************************************************************
97 
98 void MainWindow::setupDelegate()
99 {
100  m_pRawDelegate = new RawDelegate(this);
101 }
102 
103 
104 //*************************************************************************************************************
105 
106 void MainWindow::setupView()
107 {
108  m_pTableView = new QTableView;
109 
110  m_pTableView->setModel(m_pRawModel); //set custom model
111  m_pTableView->setItemDelegate(m_pRawDelegate); //set custom delegate
112 
113  //TableView settings
114  setupViewSettings();
115 
116 }
117 
118 
119 //*************************************************************************************************************
120 
121 void MainWindow::setupLayout() {
122  //set vertical layout
123  QVBoxLayout *mainlayout = new QVBoxLayout;
124 
125  mainlayout->addWidget(m_pTableView);
126 
127  //set layouts
128  QWidget *window = new QWidget();
129  window->setLayout(mainlayout);
130 
131  setCentralWidget(window);
132 }
133 
134 
135 //*************************************************************************************************************
136 
137 void MainWindow::setupViewSettings() {
138  //set some size settings for m_pTableView
139  m_pTableView->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
140 
141  m_pTableView->setShowGrid(false);
142  m_pTableView->horizontalHeader()->hide();
143  m_pTableView->verticalHeader()->setDefaultSectionSize(m_pRawDelegate->m_dDefaultPlotHeight);
144 
145  m_pTableView->setAutoScroll(false);
146  m_pTableView->setColumnHidden(0,true); //because content is plotted jointly with column=1
147 
148  m_pTableView->resizeColumnsToContents();
149 
150  m_pTableView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
151 
152  //set context menu
153  m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu);
154  connect(m_pTableView,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(customContextMenuRequested(QPoint)));
155 
156  //activate kinetic scrolling
157  QScroller::grabGesture(m_pTableView,QScroller::MiddleMouseButtonGesture);
158 
159  //connect QScrollBar with model in order to reload data samples
160  connect(m_pTableView->horizontalScrollBar(),SIGNAL(valueChanged(int)),m_pRawModel,SLOT(updateScrollPos(int)));
161 
162  //connect other signals
163  connect(m_pRawModel,SIGNAL(scrollBarValueChange(int)),this,SLOT(setScrollBarPosition(int)));
164 }
165 
166 
167 //*************************************************************************************************************
168 
169 void MainWindow::createMenus() {
170  //File
171  QMenu *fileMenu = new QMenu(tr("&File"), this);
172 
173  QAction *openAction = fileMenu->addAction(tr("&Open..."));
174  openAction->setShortcuts(QKeySequence::Open);
175  connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));
176 
177  QAction *writeAction = fileMenu->addAction(tr("&Save As..."));
178  openAction->setShortcuts(QKeySequence::SaveAs);
179  connect(writeAction, SIGNAL(triggered()), this, SLOT(writeFile()));
180 
181  QAction *quitAction = fileMenu->addAction(tr("E&xit"));
182  quitAction->setShortcuts(QKeySequence::Quit);
183  connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
184 
185  //Help
186  QMenu *helpMenu = new QMenu(tr("&Help"), this);
187 
188  QAction *aboutAction = helpMenu->addAction(tr("&About"));
189  connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
190 
191  //add to menub
192  menuBar()->addMenu(fileMenu);
193  menuBar()->addMenu(helpMenu);
194 }
195 
196 
197 //*************************************************************************************************************
198 
199 void MainWindow::setWindow() {
200  //set Window functions
201  resize(m_qSettings.value("MainWindow/size").toSize());
202  this->move(50,50);
203 }
204 
205 
206 //*************************************************************************************************************
207 
208 void MainWindow::setWindowStatus() {
209  QString title;
210 
211  //request status
212  if(m_pRawModel->m_bFileloaded) {
213  int idx = m_qFileRaw.fileName().lastIndexOf("/");
214  QString filename = m_qFileRaw.fileName().remove(0,idx+1);
215  title = QString("%1, (File loaded: %2)").arg(CInfo::AppNameShort()).arg(filename);
216  }
217  else {
218  title = QString("%1, (No File Loaded)").arg(CInfo::AppNameShort());
219  }
220 
221  //set title
222  setWindowTitle(title);
223 
224  //let the view update (ScrollBars etc.)
225  m_pTableView->resizeColumnsToContents();
226 }
227 
228 
229 //*************************************************************************************************************
230 //Log
231 void MainWindow::createLogDockWindow()
232 {
233  //Log TextBrowser
234  m_pDockWidget_Log = new QDockWidget(tr("Log"), this);
235 
236  m_pTextBrowser_Log = new QTextBrowser(m_pDockWidget_Log);
237 
238  m_pDockWidget_Log->setWidget(m_pTextBrowser_Log);
239 
240  m_pDockWidget_Log->setAllowedAreas(Qt::BottomDockWidgetArea);
241  addDockWidget(Qt::BottomDockWidgetArea, m_pDockWidget_Log);
242 
243  //Set standard LogLevel
244  setLogLevel(_LogLvMax);
245 }
246 
247 
248 //*************************************************************************************************************
249 
250 void MainWindow::writeToLog(const QString& logMsg, LogKind lgknd, LogLevel lglvl)
251 {
252  if(lglvl<=m_eLogLevelCurrent) {
253  if(lgknd == _LogKndError)
254  m_pTextBrowser_Log->insertHtml("<font color=red><b>Error:</b> "+logMsg+"</font>");
255  else if(lgknd == _LogKndWarning)
256  m_pTextBrowser_Log->insertHtml("<font color=blue><b>Warning:</b> "+logMsg+"</font>");
257  else
258  m_pTextBrowser_Log->insertHtml(logMsg);
259  m_pTextBrowser_Log->insertPlainText("\n"); // new line
260  //scroll down to the latest entry
261  QTextCursor c = m_pTextBrowser_Log->textCursor();
262  c.movePosition(QTextCursor::End);
263  m_pTextBrowser_Log->setTextCursor(c);
264 
265  m_pTextBrowser_Log->verticalScrollBar()->setValue(m_pTextBrowser_Log->verticalScrollBar()->maximum());
266  }
267 }
268 
269 
270 //*************************************************************************************************************
271 
272 void MainWindow::setLogLevel(LogLevel lvl)
273 {
274  switch(lvl) {
275  case _LogLvMin:
276  writeToLog(tr("minimal log level set"), _LogKndMessage, _LogLvMin);
277  break;
278  case _LogLvNormal:
279  writeToLog(tr("normal log level set"), _LogKndMessage, _LogLvMin);
280  break;
281  case _LogLvMax:
282  writeToLog(tr("maximum log level set"), _LogKndMessage, _LogLvMin);
283  break;
284  }
285 
286  m_eLogLevelCurrent = lvl;
287 }
288 
289 
290 //*************************************************************************************************************
291 // SLOTS
292 void MainWindow::openFile()
293 {
294  QString filename = QFileDialog::getOpenFileName(this,QString("Open fiff data file"),QString("./MNE-sample-data/MEG/sample/"),tr("fif data files (*.fif)"));
295  if(m_qFileRaw.isOpen())
296  m_qFileRaw.close();
297  m_qFileRaw.setFileName(filename);
298 
299  if(m_pRawModel->loadFiffData(m_qFileRaw)) {
300  qDebug() << "Fiff data file" << filename << "loaded.";
301  }
302  else
303  qDebug("ERROR loading fiff data file %s",filename.toLatin1().data());
304 
305  setWindowStatus();
306 
307  //set position of QScrollArea
308  setScrollBarPosition(0);
309 }
310 
311 
312 //*************************************************************************************************************
313 
314 void MainWindow::writeFile()
315 {
316  QString filename = QFileDialog::getSaveFileName(this,QString("Write fiff data file"),QString("./MNE-sample-data/MEG/sample/"),tr("fif data files (*.fif)"));
317  QFile t_fileRaw(filename);
318 
319  if(!m_pRawModel->writeFiffData(t_fileRaw))
320  qDebug() << "MainWindow: ERROR writing fiff data file" << t_fileRaw.fileName() << "!";
321 }
322 
323 
324 //*************************************************************************************************************
325 
326 void MainWindow::customContextMenuRequested(QPoint pos)
327 {
328  //obtain index where index was clicked
329  QModelIndex index = m_pTableView->indexAt(pos);
330 
331  //get selected items
332  QModelIndexList selected = m_pTableView->selectionModel()->selectedIndexes();
333 
334  //create custom context menu and actions
335  QMenu *menu = new QMenu(this);
336 
337  //**************** Marking ****************
338  QMenu *markingSubMenu = new QMenu("Mark channels",menu);
339 
340  QAction* doMarkChBad = markingSubMenu->addAction(tr("Mark as bad"));
341  connect(doMarkChBad,&QAction::triggered, [=](){
342  m_pRawModel->markChBad(selected,1);
343  });
344 
345  QAction* doMarkChGood = markingSubMenu->addAction(tr("Mark as good"));
346  connect(doMarkChGood,&QAction::triggered, [=](){
347  m_pRawModel->markChBad(selected,0);
348  });
349 
350  //**************** FilterOperators ****************
351  //selected channels
352  QMenu *filtOpSubMenu = new QMenu("Apply FilterOperator to selected channel",menu);
353  QMutableMapIterator<QString,QSharedPointer<MNEOperator> > it(m_pRawModel->m_Operators);
354  while(it.hasNext()) {
355  it.next();
356  QAction* doApplyFilter = filtOpSubMenu->addAction(tr("%1").arg(it.key()));
357 
358  connect(doApplyFilter,&QAction::triggered, [=](){
359  m_pRawModel->applyOperator(selected,it.value());
360  });
361  }
362 
363  //all channels
364  QMenu *filtOpAllSubMenu = new QMenu("Apply FilterOperator to all channels",menu);
365  it.toFront();
366  while(it.hasNext()) {
367  it.next();
368  QAction* doApplyFilter = filtOpAllSubMenu->addAction(tr("%1").arg(it.key()));
369 
370  connect(doApplyFilter,&QAction::triggered, [=](){
371  m_pRawModel->applyOperator(QModelIndexList(),it.value());
372  });
373  }
374 
375  //undoing filtering
376  QMenu *undoFiltOpSubMenu = new QMenu("Undo filtering",menu);
377  QMenu *undoFiltOpSelSubMenu = new QMenu("to selected channels",undoFiltOpSubMenu);
378 
379  //undo certain FilterOperators to selected channels
380  it.toFront();
381  while(it.hasNext()) {
382  it.next();
383  QAction* undoApplyFilter = undoFiltOpSelSubMenu->addAction(tr("%1").arg(it.key()));
384 
385  connect(undoApplyFilter,&QAction::triggered, [=](){
386  m_pRawModel->undoFilter(selected,it.value());
387  });
388  }
389 
390  undoFiltOpSubMenu->addMenu(undoFiltOpSelSubMenu);
391 
392  //undo all filterting to selected channels
393  QAction* undoApplyFilterSel = undoFiltOpSubMenu->addAction(tr("Undo FilterOperators to selected channels"));
394  connect(undoApplyFilterSel,&QAction::triggered, [=](){
395  m_pRawModel->undoFilter(selected);
396  });
397 
398  //undo all filtering to all channels
399  QAction* undoApplyFilterAll = undoFiltOpSubMenu->addAction(tr("Undo FilterOperators to all channels"));
400  connect(undoApplyFilterAll,&QAction::triggered, [=](){
401  m_pRawModel->undoFilter();
402  });
403 
404  //add everything to main contextmenu
405  menu->addMenu(markingSubMenu);
406  menu->addMenu(filtOpSubMenu);
407  menu->addMenu(filtOpAllSubMenu);
408  menu->addMenu(undoFiltOpSubMenu);
409 
410  //show context menu
411  menu->popup(m_pTableView->viewport()->mapToGlobal(pos));
412 }
413 
414 
415 //*************************************************************************************************************
416 
417 void MainWindow::setScrollBarPosition(int pos)
418 {
419  m_pTableView->horizontalScrollBar()->setValue(pos);
420  qDebug() << "MainWindow: m_iAbsFiffCursor position set to" << (m_pRawModel->firstSample()+pos);
421 }
422 
423 
424 //*************************************************************************************************************
425 
426 void MainWindow::about()
427 {
428  QMessageBox::about(this, CInfo::AppNameShort()+ ", "+tr("Version ")+CInfo::AppVersion(),
429  tr("Copyright (C) 2014 Florian Schlembach, Christoph Dinh, Matti Hamalainen, Jens Haueisen. All rights reserved.\n\n"
430  "Redistribution and use in source and binary forms, with or without modification, are permitted provided that"
431  " the following conditions are met:\n"
432  "\t* Redistributions of source code must retain the above copyright notice, this list of conditions and the"
433  " following disclaimer.\n"
434  "\t* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and"
435  " the following disclaimer in the documentation and/or other materials provided with the distribution.\n"
436  "\t* Neither the name of the Massachusetts General Hospital nor the names of its contributors may be used"
437  " to endorse or promote products derived from this software without specific prior written permission.\n\n"
438  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED"
439  " WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A"
440  " PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MASSACHUSETTS GENERAL HOSPITAL BE LIABLE FOR ANY DIRECT,"
441  " INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,"
442  " PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"
443  " HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"
444  " NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"
445  " POSSIBILITY OF SUCH DAMAGE."));
446 }
virtual ~MainWindow()
Definition: mainwindow.cpp:134
static const QString AppNameShort()
Definition: info.h:103
static const QString AppVersion()
Definition: info.h:169
void writeToLog(const QString &logMsg, LogKind lgknd=_LogKndMessage, LogLevel lglvl=_LogLvNormal)
Definition: mainwindow.cpp:558