43 #include "mainwindow.h"
51 using namespace MNEBrowseRawQt;
59 MainWindow::MainWindow(QWidget *parent)
61 , m_qFileRaw(
"./MNE-sample-data/MEG/sample/sample_audvis_raw.fif")
73 createLogDockWindow();
89 void MainWindow::setupModel()
92 m_pRawModel =
new RawModel(m_qFileRaw,
this);
98 void MainWindow::setupDelegate()
106 void MainWindow::setupView()
108 m_pTableView =
new QTableView;
110 m_pTableView->setModel(m_pRawModel);
111 m_pTableView->setItemDelegate(m_pRawDelegate);
121 void MainWindow::setupLayout() {
123 QVBoxLayout *mainlayout =
new QVBoxLayout;
125 mainlayout->addWidget(m_pTableView);
128 QWidget *window =
new QWidget();
129 window->setLayout(mainlayout);
131 setCentralWidget(window);
137 void MainWindow::setupViewSettings() {
139 m_pTableView->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
141 m_pTableView->setShowGrid(
false);
142 m_pTableView->horizontalHeader()->hide();
143 m_pTableView->verticalHeader()->setDefaultSectionSize(m_pRawDelegate->m_dDefaultPlotHeight);
145 m_pTableView->setAutoScroll(
false);
146 m_pTableView->setColumnHidden(0,
true);
148 m_pTableView->resizeColumnsToContents();
150 m_pTableView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
153 m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu);
154 connect(m_pTableView,SIGNAL(customContextMenuRequested(QPoint)),
this,SLOT(customContextMenuRequested(QPoint)));
157 QScroller::grabGesture(m_pTableView,QScroller::MiddleMouseButtonGesture);
160 connect(m_pTableView->horizontalScrollBar(),SIGNAL(valueChanged(
int)),m_pRawModel,SLOT(updateScrollPos(
int)));
163 connect(m_pRawModel,SIGNAL(scrollBarValueChange(
int)),
this,SLOT(setScrollBarPosition(
int)));
169 void MainWindow::createMenus() {
171 QMenu *fileMenu =
new QMenu(tr(
"&File"),
this);
173 QAction *openAction = fileMenu->addAction(tr(
"&Open..."));
174 openAction->setShortcuts(QKeySequence::Open);
175 connect(openAction, SIGNAL(triggered()),
this, SLOT(openFile()));
177 QAction *writeAction = fileMenu->addAction(tr(
"&Save As..."));
178 openAction->setShortcuts(QKeySequence::SaveAs);
179 connect(writeAction, SIGNAL(triggered()),
this, SLOT(writeFile()));
181 QAction *quitAction = fileMenu->addAction(tr(
"E&xit"));
182 quitAction->setShortcuts(QKeySequence::Quit);
183 connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
186 QMenu *helpMenu =
new QMenu(tr(
"&Help"),
this);
188 QAction *aboutAction = helpMenu->addAction(tr(
"&About"));
189 connect(aboutAction, SIGNAL(triggered()),
this, SLOT(about()));
192 menuBar()->addMenu(fileMenu);
193 menuBar()->addMenu(helpMenu);
199 void MainWindow::setWindow() {
201 resize(m_qSettings.value(
"MainWindow/size").toSize());
208 void MainWindow::setWindowStatus() {
212 if(m_pRawModel->m_bFileloaded) {
213 int idx = m_qFileRaw.fileName().lastIndexOf(
"/");
214 QString filename = m_qFileRaw.fileName().remove(0,idx+1);
222 setWindowTitle(title);
225 m_pTableView->resizeColumnsToContents();
231 void MainWindow::createLogDockWindow()
234 m_pDockWidget_Log =
new QDockWidget(tr(
"Log"),
this);
236 m_pTextBrowser_Log =
new QTextBrowser(m_pDockWidget_Log);
238 m_pDockWidget_Log->setWidget(m_pTextBrowser_Log);
240 m_pDockWidget_Log->setAllowedAreas(Qt::BottomDockWidgetArea);
241 addDockWidget(Qt::BottomDockWidgetArea, m_pDockWidget_Log);
244 setLogLevel(_LogLvMax);
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>");
258 m_pTextBrowser_Log->insertHtml(logMsg);
259 m_pTextBrowser_Log->insertPlainText(
"\n");
261 QTextCursor c = m_pTextBrowser_Log->textCursor();
262 c.movePosition(QTextCursor::End);
263 m_pTextBrowser_Log->setTextCursor(c);
265 m_pTextBrowser_Log->verticalScrollBar()->setValue(m_pTextBrowser_Log->verticalScrollBar()->maximum());
272 void MainWindow::setLogLevel(LogLevel lvl)
276 writeToLog(tr(
"minimal log level set"), _LogKndMessage, _LogLvMin);
279 writeToLog(tr(
"normal log level set"), _LogKndMessage, _LogLvMin);
282 writeToLog(tr(
"maximum log level set"), _LogKndMessage, _LogLvMin);
286 m_eLogLevelCurrent = lvl;
292 void MainWindow::openFile()
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())
297 m_qFileRaw.setFileName(filename);
299 if(m_pRawModel->loadFiffData(m_qFileRaw)) {
300 qDebug() <<
"Fiff data file" << filename <<
"loaded.";
303 qDebug(
"ERROR loading fiff data file %s",filename.toLatin1().data());
308 setScrollBarPosition(0);
314 void MainWindow::writeFile()
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);
319 if(!m_pRawModel->writeFiffData(t_fileRaw))
320 qDebug() <<
"MainWindow: ERROR writing fiff data file" << t_fileRaw.fileName() <<
"!";
326 void MainWindow::customContextMenuRequested(QPoint pos)
329 QModelIndex index = m_pTableView->indexAt(pos);
332 QModelIndexList selected = m_pTableView->selectionModel()->selectedIndexes();
335 QMenu *menu =
new QMenu(
this);
338 QMenu *markingSubMenu =
new QMenu(
"Mark channels",menu);
340 QAction* doMarkChBad = markingSubMenu->addAction(tr(
"Mark as bad"));
341 connect(doMarkChBad,&QAction::triggered, [=](){
342 m_pRawModel->markChBad(selected,1);
345 QAction* doMarkChGood = markingSubMenu->addAction(tr(
"Mark as good"));
346 connect(doMarkChGood,&QAction::triggered, [=](){
347 m_pRawModel->markChBad(selected,0);
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()) {
356 QAction* doApplyFilter = filtOpSubMenu->addAction(tr(
"%1").arg(it.key()));
358 connect(doApplyFilter,&QAction::triggered, [=](){
359 m_pRawModel->applyOperator(selected,it.value());
364 QMenu *filtOpAllSubMenu =
new QMenu(
"Apply FilterOperator to all channels",menu);
366 while(it.hasNext()) {
368 QAction* doApplyFilter = filtOpAllSubMenu->addAction(tr(
"%1").arg(it.key()));
370 connect(doApplyFilter,&QAction::triggered, [=](){
371 m_pRawModel->applyOperator(QModelIndexList(),it.value());
376 QMenu *undoFiltOpSubMenu =
new QMenu(
"Undo filtering",menu);
377 QMenu *undoFiltOpSelSubMenu =
new QMenu(
"to selected channels",undoFiltOpSubMenu);
381 while(it.hasNext()) {
383 QAction* undoApplyFilter = undoFiltOpSelSubMenu->addAction(tr(
"%1").arg(it.key()));
385 connect(undoApplyFilter,&QAction::triggered, [=](){
386 m_pRawModel->undoFilter(selected,it.value());
390 undoFiltOpSubMenu->addMenu(undoFiltOpSelSubMenu);
393 QAction* undoApplyFilterSel = undoFiltOpSubMenu->addAction(tr(
"Undo FilterOperators to selected channels"));
394 connect(undoApplyFilterSel,&QAction::triggered, [=](){
395 m_pRawModel->undoFilter(selected);
399 QAction* undoApplyFilterAll = undoFiltOpSubMenu->addAction(tr(
"Undo FilterOperators to all channels"));
400 connect(undoApplyFilterAll,&QAction::triggered, [=](){
401 m_pRawModel->undoFilter();
405 menu->addMenu(markingSubMenu);
406 menu->addMenu(filtOpSubMenu);
407 menu->addMenu(filtOpAllSubMenu);
408 menu->addMenu(undoFiltOpSubMenu);
411 menu->popup(m_pTableView->viewport()->mapToGlobal(pos));
417 void MainWindow::setScrollBarPosition(
int pos)
419 m_pTableView->horizontalScrollBar()->setValue(pos);
420 qDebug() <<
"MainWindow: m_iAbsFiffCursor position set to" << (m_pRawModel->firstSample()+pos);
426 void MainWindow::about()
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."));
static const QString AppNameShort()
static const QString AppVersion()
void writeToLog(const QString &logMsg, LogKind lgknd=_LogKndMessage, LogLevel lglvl=_LogLvNormal)