v2.0.0
Loading...
Searching...
No Matches
channelselectionview.cpp
Go to the documentation of this file.
1//=============================================================================================================
16
17//=============================================================================================================
18// INCLUDES
19//=============================================================================================================
20
22#include "ui_channelselectionview.h"
26
27#include <mne/mne_layout.h>
28#include <utils/selectionio.h>
29#include <utils/layoutmaker.h>
30
31#include <fiff/fiff.h>
32
33//=============================================================================================================
34// STL INCLUDES
35//=============================================================================================================
36
37#include <iostream>
38
39//=============================================================================================================
40// QT INCLUDES
41//=============================================================================================================
42
43#include <QDate>
44#include <QVector3D>
45#include <QFileDialog>
46#include <QFileInfo>
47#include <QListWidgetItem>
48#include <QSettings>
49#include <QApplication>
50#include <QKeyEvent>
51#include <QSignalBlocker>
52
53//=============================================================================================================
54// EIGEN INCLUDES
55//=============================================================================================================
56
57//=============================================================================================================
58// USED NAMESPACES
59//=============================================================================================================
60
61using namespace DISPLIB;
62using namespace FIFFLIB;
63using namespace UTILSLIB;
64
65//=============================================================================================================
66// DEFINE MEMBER METHODS
67//=============================================================================================================
68
69ChannelSelectionView::ChannelSelectionView(const QString& sSettingsPath,
70 QWidget* parent,
71 ChannelInfoModel::SPtr pChannelInfoModel,
72 Qt::WindowType f)
73: AbstractView(parent, f)
74, m_pUi(new Ui::ChannelSelectionViewWidget)
75, m_pChannelInfoModel(pChannelInfoModel)
76, m_bSetup(false)
77{
78 m_sSettingsPath = sSettingsPath;
79 m_pUi->setupUi(this);
80
81 //Init gui elements
82 initListWidgets();
83 initSelectionSceneView();
84 initComboBoxes();
85 initButtons();
86 initCheckBoxes();
87
89
90 m_bSetup = true;
91
92 setCurrentlyMappedFiffChannels(m_pChannelInfoModel->getMappedChannelsList());
93}
94
95//=============================================================================================================
96
98{
99 // saveSettings();
100
101 delete m_pUi;
102}
103
104//=============================================================================================================
105
106void ChannelSelectionView::initListWidgets()
107{
108 //Install event filter to receive key press events
109 m_pUi->m_listWidget_userDefined->installEventFilter(this);
110 m_pUi->m_listWidget_selectionGroups->installEventFilter(this);
111
112 //Connect list widgets to update themselves and other list widgets when changed
113 connect(m_pUi->m_listWidget_selectionGroups, &QListWidget::currentItemChanged,
114 this, &ChannelSelectionView::updateSelectionGroupsList);
115
116 //Update data view whenever a drag and drop item movement is performed
117 //TODO: This is inefficient because updateDataView is called everytime the list's viewport is entered
118 connect(m_pUi->m_listWidget_userDefined->model(), &QAbstractTableModel::dataChanged,
120}
121
122//=============================================================================================================
123
124void ChannelSelectionView::initSelectionSceneView()
125{
126 //Create layout scene and set to view
127 m_pSelectionScene = new SelectionScene(m_pUi->m_graphicsView_layoutPlot);
128 m_pUi->m_graphicsView_layoutPlot->setScene(m_pSelectionScene);
129
130 connect(m_pSelectionScene, &QGraphicsScene::selectionChanged,
131 this, &ChannelSelectionView::updateUserDefinedChannelsList);
132}
133
134//=============================================================================================================
135
136void ChannelSelectionView::initComboBoxes()
137{
138 m_pUi->m_comboBox_layoutFile->clear();
139 m_pUi->m_comboBox_layoutFile->insertItems(0, QStringList() << "babymeg-mag-inner-layer.lout"
140 << "babymeg-mag-outer-layer.lout"
141 // << "babymeg-mag-ref.lout"
142 << "Vectorview-grad.lout"
143 << "Vectorview-all.lout"
144 << "Vectorview-mag.lout"
145 << "standard_waveguard64_duke.lout"
146 // << "CTF-275.lout"
147 // << "magnesWH3600.lout"
148 );
149
150 connect(m_pUi->m_comboBox_layoutFile, &QComboBox::currentTextChanged,
151 this, &ChannelSelectionView::onComboBoxLayoutChanged);
152
153 //Initialise layout as neuromag vectorview with all channels
154 QString selectionName("Vectorview-all.lout");
155 //loadLayout(QCoreApplication::applicationDirPath() + selectionName.prepend("/../resources/general/2DLayouts/"));
156 setCurrentLayoutFile(selectionName);
157
158 //Load selection groups again because they need to be reinitialised every time a new layout hase been loaded
159 selectionName = QString("mne_browse_raw_vv.sel");
160 loadSelectionGroups(QCoreApplication::applicationDirPath() + selectionName.prepend("/../resources/general/selectionGroups/"));
161}
162
163//=============================================================================================================
164
165void ChannelSelectionView::initButtons()
166{
167 connect(m_pUi->m_pushButton_saveSelection, &QPushButton::clicked,
168 this, &ChannelSelectionView::onBtnSaveUserSelection);
169
170 connect(m_pUi->m_pushButton_loadSelection, &QPushButton::clicked,
171 this, &ChannelSelectionView::onBtnLoadUserSelection);
172
173 connect(m_pUi->m_pushButton_addToSelectionGroups, &QPushButton::clicked,
174 this, &ChannelSelectionView::onBtnAddToSelectionGroups);
175}
176
177//=============================================================================================================
178
179void ChannelSelectionView::initCheckBoxes()
180{
181 connect(m_pUi->m_checkBox_showBadChannelsAsRed, &QCheckBox::clicked,
183}
184
185//=============================================================================================================
186
187void ChannelSelectionView::setCurrentlyMappedFiffChannels(const QStringList& mappedLayoutChNames)
188{
189 m_currentlyLoadedFiffChannels = mappedLayoutChNames;
190
191 //Clear the visible channel list
192 m_pUi->m_listWidget_visibleChannels->clear();
193
194 //Keep the entry All in the selection list and m_selectionGroupsMap -> delete the rest
195 m_pUi->m_listWidget_selectionGroups->clear();
196
197 //Create group 'All' manually (because this group depends on the loaded channels from the fiff data file, not on the loaded selection file)
198 auto it = m_selectionGroupsMap.find("All");
199 if (it != m_selectionGroupsMap.end()) {
200 m_selectionGroupsMap.erase(it);
201 }
202 m_selectionGroupsMap.insert("All", m_currentlyLoadedFiffChannels);
203
204 //Add selection groups to list widget
205 for (auto i = m_selectionGroupsMap.constBegin(); i != m_selectionGroupsMap.constEnd(); i++) {
206 m_pUi->m_listWidget_selectionGroups->insertItem(m_pUi->m_listWidget_selectionGroups->count(), i.key());
207 }
208
209 //Set group all as slected item
210 m_pUi->m_listWidget_selectionGroups->setCurrentItem(getItemForChName(m_pUi->m_listWidget_selectionGroups, "All"), QItemSelectionModel::Select);
211
212 //Update selection
213 updateSelectionGroupsList(getItemForChName(m_pUi->m_listWidget_selectionGroups, "All"), new QListWidgetItem());
214}
215
216//=============================================================================================================
217
218void ChannelSelectionView::highlightChannels(QModelIndexList channelIndexList)
219{
220 QStringList channelList;
221 for (int i = 0; i < channelIndexList.size(); i++) {
222 QModelIndex nameIndex = m_pChannelInfoModel->index(channelIndexList.at(i).row(), 3);
223 channelList << m_pChannelInfoModel->data(nameIndex, ChannelInfoModelRoles::GetMappedLayoutChName).toString();
224 }
225
226 QList<QGraphicsItem*> allSceneItems = m_pSelectionScene->items();
227
228 for (int i = 0; i < allSceneItems.size(); i++) {
229 SelectionSceneItem* item = static_cast<SelectionSceneItem*>(allSceneItems.at(i));
230 if (channelList.contains(item->m_sChannelName))
231 item->m_bHighlightItem = true;
232 else
233 item->m_bHighlightItem = false;
234 }
235
236 m_pSelectionScene->update();
237}
238
239//=============================================================================================================
240
241void ChannelSelectionView::selectChannels(QStringList channelList)
242{
243 QList<QGraphicsItem*> allSceneItems = m_pSelectionScene->items();
244
245 for (int i = 0; i < allSceneItems.size(); i++) {
246 SelectionSceneItem* item = static_cast<SelectionSceneItem*>(allSceneItems.at(i));
247 if (channelList.contains(item->m_sChannelName))
248 item->setSelected(true);
249 else
250 item->setSelected(false);
251 }
252
253 m_pSelectionScene->update();
254}
255
256//=============================================================================================================
257
259{
260 //if no channels have been selected by the user -> show selected group channels
261 QListWidget* targetListWidget;
262 if (m_pUi->m_listWidget_userDefined->count() > 0)
263 targetListWidget = m_pUi->m_listWidget_userDefined;
264 else
265 targetListWidget = m_pUi->m_listWidget_visibleChannels;
266
267 //Create list of channels which are to be visible in the view
268 QStringList selectedChannels;
269
270 for (int i = 0; i < targetListWidget->count(); i++) {
271 QListWidgetItem* item = targetListWidget->item(i);
272 selectedChannels << item->text();
273 }
274
275 return selectedChannels;
276}
277
278//=============================================================================================================
279
280QListWidgetItem* ChannelSelectionView::getItemForChName(QListWidget* listWidget,
281 const QString& channelName)
282{
283 for (int i = 0; i < listWidget->count(); i++)
284 if (listWidget->item(i)->text() == channelName)
285 return listWidget->item(i);
286
287 return new QListWidgetItem();
288}
289
290//=============================================================================================================
291
292const QMap<QString, QPointF>& ChannelSelectionView::getLayoutMap()
293{
294 return m_layoutMap;
295}
296
297//=============================================================================================================
298
299void ChannelSelectionView::newFiffFileLoaded(QSharedPointer<FiffInfo>& pFiffInfo)
300{
301 Q_UNUSED(pFiffInfo);
302
303 loadLayout(resolveLayoutPath(m_pUi->m_comboBox_layoutFile->currentText()));
304}
305
306//=============================================================================================================
307
309{
310 return m_pUi->m_comboBox_layoutFile->currentText();
311}
312
313//=============================================================================================================
314
316{
317 return m_pUi->m_lineEdit_loadedFile->text();
318}
319
320//=============================================================================================================
321
322void ChannelSelectionView::setCurrentLayoutFile(QString currentLayoutFile)
323{
324 qDebug() << "setCurrentLayoutFile:" << currentLayoutFile;
325 const QSignalBlocker blocker(m_pUi->m_comboBox_layoutFile);
326 m_pUi->m_comboBox_layoutFile->setCurrentText(currentLayoutFile);
327
328 loadLayout(resolveLayoutPath(currentLayoutFile));
330}
331
332//=============================================================================================================
333
335{
336 QStringList badChannelMappedNames;
337 QStringList badChannelList = m_pChannelInfoModel->getBadChannelList();
338
339 if (m_pUi->m_checkBox_showBadChannelsAsRed->isChecked()) {
340 for (int i = 0; i < m_pChannelInfoModel->rowCount(); i++) {
341 QModelIndex digIndex = m_pChannelInfoModel->index(i, 3);
342 QString mappedChName = m_pChannelInfoModel->data(digIndex, ChannelInfoModelRoles::GetMappedLayoutChName).toString();
343
344 digIndex = m_pChannelInfoModel->index(i, 1);
345 QString origChName = m_pChannelInfoModel->data(digIndex, ChannelInfoModelRoles::GetOrigChName).toString();
346
347 if (badChannelList.contains(origChName)) {
348 badChannelMappedNames << mappedChName;
349 }
350 }
351 }
352
353 m_pSelectionScene->repaintItems(m_layoutMap, badChannelMappedNames);
354 m_pSelectionScene->update();
355
356 updateSceneItems();
358}
359
360//=============================================================================================================
361
363{
364 //if no channels have been selected by the user -> show selected group channels
365 QListWidget* targetListWidget;
366 if (m_pUi->m_listWidget_userDefined->count() > 0)
367 targetListWidget = m_pUi->m_listWidget_userDefined;
368 else
369 targetListWidget = m_pUi->m_listWidget_visibleChannels;
370
371 //Create list of channels which are to be visible in the view
372 QStringList selectedChannels;
373
374 for (int i = 0; i < targetListWidget->count(); i++) {
375 QListWidgetItem* item = targetListWidget->item(i);
376 int indexTemp = m_pChannelInfoModel->getIndexFromMappedChName(item->text());
377
378 if (indexTemp != -1) {
379 QModelIndex mappedNameIndex = m_pChannelInfoModel->index(indexTemp, 1);
380 QString origChName = m_pChannelInfoModel->data(mappedNameIndex, ChannelInfoModelRoles::GetOrigChName).toString();
381
382 selectedChannels << origChName;
383 } else
384 selectedChannels << item->text();
385 }
386
387 emit showSelectedChannelsOnly(selectedChannels);
388
389 //emit signal that selection was changed
390 if (!m_pSelectionScene->selectedItems().empty()) {
391 emit selectionChanged(m_pSelectionScene->selectedItems());
392 } else {
393 //only return visible items (EEG or MEG channels)
394 QList<QGraphicsItem*> visibleItemList = m_pSelectionScene->items();
395 QMutableListIterator<QGraphicsItem*> i(visibleItemList);
396 while (i.hasNext()) {
397 if (!i.next()->isVisible()) {
398 i.remove();
399 }
400 }
401 emit selectionChanged(visibleItemList);
402 }
403}
404
405//=============================================================================================================
406
408{
409 if (m_sSettingsPath.isEmpty()) {
410 return;
411 }
412
413 QSettings settings("MNECPP");
414
415 std::cout << "saveSettings: " << getCurrentLayoutFile().toStdString();
416
417 settings.setValue(m_sSettingsPath + QString("/ChannelSelectionView/selectedLayoutFile"), getCurrentLayoutFile());
418 settings.setValue(m_sSettingsPath + QString("/ChannelSelectionView/channelSelectionViewPos"), this->pos());
419 settings.setValue(m_sSettingsPath + QString("/ChannelSelectionView/selectedGroupFile"), getCurrentGroupFile());
420}
421
422//=============================================================================================================
423
425{
426 if (m_sSettingsPath.isEmpty()) {
427 return;
428 }
429
430 QSettings settings("MNECPP");
431
432 setCurrentLayoutFile(settings.value(m_sSettingsPath + QString("/ChannelSelectionView/selectedLayoutFile"), "Vectorview-all.lout").toString());
433 loadSelectionGroups(QCoreApplication::applicationDirPath() + settings.value(m_sSettingsPath + QString("/ChannelSelectionView/selectedGroupFile"), "mne_browse_raw_vv.sel").toString().prepend("/../resources/general/selectionGroups/"));
434
435 qDebug() << "loadSettings: " << getCurrentLayoutFile();
436
437 QPoint pos = settings.value(m_sSettingsPath + QString("/ChannelSelectionView/channelSelectionViewPos"), QPoint(100, 100)).toPoint();
438
439 QList<QScreen*> screensList = QGuiApplication::screens();
440 if (screensList.isEmpty()) {
441 move(QPoint(100, 100));
442 } else {
443 move(pos);
444 }
445}
446
447//=============================================================================================================
448
450{
451 switch (mode) {
453 break;
454 default: // default is research mode
455 break;
456 }
457}
458
459//=============================================================================================================
460
462{
463 switch (mode) {
465 break;
466 default: // default is realtime mode
467 break;
468 }
469}
470
471//=============================================================================================================
472
473bool ChannelSelectionView::loadLayout(QString path)
474{
475 qDebug() << "loadLayout:" << path;
476 const std::optional<MNELIB::MNELayout> layout = MNELIB::MNELayout::read(path);
477 const bool state = layout.has_value();
478 m_layoutMap = state ? layout->channelPositions() : QMap<QString, QPointF>();
479
480 //if no layout for EEG is specified generate from digitizer points
481 QList<QVector<float>> inputPoints;
482 QList<QVector<float>> outputPoints;
483 QStringList names;
484 QFile out("manualLayout.lout");
485
486 for (int i = 0; i < m_pChannelInfoModel->rowCount(); i++) {
487 QModelIndex digIndex = m_pChannelInfoModel->index(i, 1);
488 QString chName = m_pChannelInfoModel->data(digIndex, ChannelInfoModelRoles::GetOrigChName).toString();
489
490 digIndex = m_pChannelInfoModel->index(i, 8);
491 QVector3D channelDig = m_pChannelInfoModel->data(digIndex, ChannelInfoModelRoles::GetChDigitizer).value<QVector3D>();
492
493 digIndex = m_pChannelInfoModel->index(i, 4);
494 int kind = m_pChannelInfoModel->data(digIndex, ChannelInfoModelRoles::GetChKind).toInt();
495
496 if (kind == FIFFV_EEG_CH) { //FIFFV_MEG_CH
497 QVector<float> temp;
498 temp.append(channelDig.x());
499 temp.append(channelDig.y());
500 temp.append(channelDig.z());
501 inputPoints.append(temp);
502
503 names << chName;
504 }
505 }
506
507 float prad = 60.0;
508 float width = 5.0;
509 float height = 4.0;
510 int numberTries = 0;
511
512 if (inputPoints.size() > 0) {
513 while (numberTries < 10) {
514 if (!LayoutMaker::makeLayout(inputPoints,
515 outputPoints,
516 names,
517 out,
518 true,
519 prad,
520 width,
521 height,
522 false,
523 false,
524 true)) {
525 numberTries++;
526 } else {
527 numberTries = 11;
528 }
529 }
530 }
531
532 //Add new EEG points to Layout Map
533 for (int i = 0; i < outputPoints.size(); i++) {
534 if (!m_layoutMap.contains(names.at(i))) {
535 m_layoutMap[names.at(i)] = QPointF(outputPoints.at(i)[0], outputPoints.at(i)[1]);
536 }
537 }
538
539 QStringList bad;
540 m_pSelectionScene->repaintItems(m_layoutMap, bad);
541 m_pSelectionScene->update();
542 updateSceneItems();
543
544 //Fit to view
545 m_pUi->m_graphicsView_layoutPlot->fitInView(m_pSelectionScene->itemsBoundingRect(), Qt::KeepAspectRatio);
546
547 if (state)
548 emit loadedLayoutMap(m_layoutMap);
549
550 if (m_bSetup) {
551 saveSettings();
552 }
553
554 return state;
555}
556
557//=============================================================================================================
558
559QString ChannelSelectionView::resolveLayoutPath(const QString& layoutFile) const
560{
561 if (layoutFile.isEmpty()) {
562 return QString();
563 }
564
565 if (QFileInfo(layoutFile).isAbsolute()) {
566 return layoutFile;
567 }
568
569 return QCoreApplication::applicationDirPath() + QStringLiteral("/../resources/general/2DLayouts/") + layoutFile;
570}
571
572//=============================================================================================================
573
574bool ChannelSelectionView::loadSelectionGroups(QString path)
575{
576 //Clear the visible channel list
577 m_pUi->m_listWidget_visibleChannels->clear();
578
579 //Keep the entry All in the selection list and m_selectionGroupsMap -> delete the rest
580 m_pUi->m_listWidget_selectionGroups->clear();
581
582 //Read selection from file and store to map
583 QString newPath = path; //QCoreApplication::applicationDirPath() + path.prepend("/../resources/general/selectionGroups/");
584
585 m_selectionGroupsMap.clear();
586
587 // An empty path, or one with neither recognised extension, reads nothing
588 // and must report failure rather than an indeterminate value.
589 bool state = false;
590 if (!path.isEmpty()) {
591 if (path.contains(".sel"))
592 state = SelectionIO::readMNESelFile(newPath, m_selectionGroupsMap);
593 if (path.contains(".mon"))
594 state = SelectionIO::readBrainstormMonFile(newPath, m_selectionGroupsMap);
595 }
596
597 //Create group 'All' and 'All EEG' manually (bcause this group depends on the loaded channels from the Info data file, not on the loaded selection file)
598 auto it = m_selectionGroupsMap.find("All");
599 if (it != m_selectionGroupsMap.end()) {
600 m_selectionGroupsMap.erase(it);
601 }
602 m_selectionGroupsMap.insert("All", m_currentlyLoadedFiffChannels);
603
604 QStringList names;
605 for (int i = 0; i < m_pChannelInfoModel->rowCount(); i++) {
606 QModelIndex digIndex = m_pChannelInfoModel->index(i, 1);
607 QString chName = m_pChannelInfoModel->data(digIndex, ChannelInfoModelRoles::GetOrigChName).toString();
608
609 digIndex = m_pChannelInfoModel->index(i, 4);
610 int kind = m_pChannelInfoModel->data(digIndex, ChannelInfoModelRoles::GetChKind).toInt();
611
612 if (kind == FIFFV_EEG_CH) //FIFFV_MEG_CH
613 names << chName;
614 }
615
616 //Add 'Add EEG' group to selection groups
617 it = m_selectionGroupsMap.find("All EEG");
618 if (it != m_selectionGroupsMap.end()) {
619 m_selectionGroupsMap.erase(it);
620 }
621 m_selectionGroupsMap.insert("All EEG", names);
622
623 //Add selection groups to list widget
624
625 for (auto i = m_selectionGroupsMap.constBegin(); i != m_selectionGroupsMap.constEnd(); i++) {
626 m_pUi->m_listWidget_selectionGroups->insertItem(m_pUi->m_listWidget_selectionGroups->count(), i.key());
627 }
628
629 //Update selection
630 updateSelectionGroupsList(getItemForChName(m_pUi->m_listWidget_selectionGroups, "All"), new QListWidgetItem());
631
632 //Set group all as slected item
633 m_pUi->m_listWidget_selectionGroups->setCurrentItem(getItemForChName(m_pUi->m_listWidget_selectionGroups, "All"), QItemSelectionModel::Select);
634
635 m_pUi->m_lineEdit_loadedFile->setText(QFileInfo(path).fileName());
636
637 if (m_bSetup) {
638 saveSettings();
639 }
640
641 return state;
642}
643
644//=============================================================================================================
645
646void ChannelSelectionView::cleanUpMEGChannels()
647{
648 //Iterate through all loaded selection groups
649 for (auto i = m_selectionGroupsMap.constBegin(); i != m_selectionGroupsMap.constEnd(); i++) {
650 QStringList channelList = i.value();
651
652 //Search the current selection group for MEG channels which are not in the currently loaded layout file and delete them
653 QMutableStringListIterator stringListIndex(channelList);
654 while (stringListIndex.hasNext()) {
655 stringListIndex.next();
656
657 if (!m_layoutMap.contains(stringListIndex.value()) && stringListIndex.value().contains("MEG"))
658 stringListIndex.remove();
659 }
660
661 //Overwrite old selection groups channels
662 m_selectionGroupsMap.insert(i.key(), channelList);
663 }
664}
665
666//=============================================================================================================
667
668void ChannelSelectionView::updateSelectionGroupsList(QListWidgetItem* current, QListWidgetItem* previous)
669{
670 Q_UNUSED(previous);
671
672 if (current == 0) {
673 return;
674 }
675 if (current->text().contains("EEG"))
676 m_pSelectionScene->m_iChannelTypeMode = FIFFV_EEG_CH;
677 else
678 m_pSelectionScene->m_iChannelTypeMode = FIFFV_MEG_CH;
679
680 //update visible channel list widget
681 m_pUi->m_listWidget_visibleChannels->clear();
682 auto items = m_selectionGroupsMap.find(current->text());
683 m_pUi->m_listWidget_visibleChannels->addItems(*items);
684
685 //update scene items based o nthe new selection group
686 updateSceneItems();
687
688 //update the channels plotted in the data view
690
692}
693
694//=============================================================================================================
695
696void ChannelSelectionView::updateSceneItems()
697{
698 QStringList visibleItems;
699
700 for (int i = 0; i < m_pUi->m_listWidget_visibleChannels->count(); i++)
701 visibleItems << m_pUi->m_listWidget_visibleChannels->item(i)->text();
702
703 m_pSelectionScene->hideItems(visibleItems);
704}
705
706//=============================================================================================================
707
708void ChannelSelectionView::updateUserDefinedChannelsList()
709{
710 QList<QGraphicsItem*> itemList = m_pSelectionScene->selectedItems();
711 QStringList userDefinedChannels;
712
713 for (int i = 0; i < itemList.size(); i++) {
714 SelectionSceneItem* item = static_cast<SelectionSceneItem*>(itemList.at(i));
715 userDefinedChannels << item->m_sChannelName;
716 }
717
718 m_pUi->m_listWidget_userDefined->clear();
719 m_pUi->m_listWidget_userDefined->addItems(userDefinedChannels);
720
722}
723
724//=============================================================================================================
725
726void ChannelSelectionView::onBtnLoadUserSelection()
727{
728 QString path = QFileDialog::getOpenFileName(this,
729 QString("Open selection file"),
730 QString("../resources/general/selectionGroups/"),
731 tr("Selection files (*.sel *.mon)"));
732
733 if (path.isEmpty())
734 return;
735
736 loadSelectionGroups(path);
737 m_pUi->m_lineEdit_loadedFile->setText(QFileInfo(path).fileName());
738}
739
740//=============================================================================================================
741
742void ChannelSelectionView::onBtnSaveUserSelection()
743{
744 QDate date;
745 QString path = QFileDialog::getSaveFileName(this,
746 "Save user channel selection",
747 QString("../resources/general/selectionGroups/%1_%2_%3_UserSelection").arg(date.currentDate().year()).arg(date.currentDate().month()).arg(date.currentDate().day()),
748 tr("MNE selection file(*.sel);; Brainstorm montage file(*.mon)"));
749
750 QMultiMap<QString, QStringList> tempMap = m_selectionGroupsMap;
751 tempMap.remove("All");
752 tempMap.remove("All EEG");
753
754 if (!path.isEmpty()) {
755 if (path.contains(".sel"))
756 SelectionIO::writeMNESelFile(path, tempMap);
757 if (path.contains(".mon"))
759 }
760}
761
762//=============================================================================================================
763
764void ChannelSelectionView::onBtnAddToSelectionGroups()
765{
766 QStringList temp;
767 for (int i = 0; i < m_pUi->m_listWidget_userDefined->count(); i++)
768 temp << m_pUi->m_listWidget_userDefined->item(i)->text();
769
770 m_selectionGroupsMap.insert(m_pUi->m_lineEdit_selectionGroupName->text(), temp);
771 m_pUi->m_listWidget_selectionGroups->insertItem(m_pUi->m_listWidget_selectionGroups->count(), m_pUi->m_lineEdit_selectionGroupName->text());
772}
773
774//=============================================================================================================
775
776void ChannelSelectionView::onComboBoxLayoutChanged()
777{
778 QString selectionName(m_pUi->m_comboBox_layoutFile->currentText());
779 loadLayout(resolveLayoutPath(selectionName));
781}
782
783//=============================================================================================================
784
785void ChannelSelectionView::resizeEvent(QResizeEvent* event)
786{
787 Q_UNUSED(event);
788
789 //Fit scene in view
790 //m_pUi->m_graphicsView_layoutPlot->fitInView(m_pSelectionScene->itemsBoundingRect(), Qt::KeepAspectRatio);
791}
792
793//=============================================================================================================
794
795bool ChannelSelectionView::eventFilter(QObject* obj, QEvent* event)
796{
797 //Setup delete key on user defined channel list
798 if (obj == m_pUi->m_listWidget_userDefined && event->type() == QEvent::KeyRelease) {
799 QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
800
801 if (keyEvent->key() == Qt::Key_Delete) {
802 qDeleteAll(m_pUi->m_listWidget_userDefined->selectedItems());
804 return true;
805 } else
806 return false;
807 }
808
809 if (obj == m_pUi->m_listWidget_selectionGroups && event->type() == QEvent::KeyRelease) {
810 QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
811
812 if (keyEvent->key() == Qt::Key_Delete) {
813 QList<QListWidgetItem*> tempSelectedList;
814
815 for (int i = 0; i < m_pUi->m_listWidget_selectionGroups->selectedItems().size(); i++) {
816 if (m_pUi->m_listWidget_selectionGroups->selectedItems().at(i)->text() != "All" &&
817 m_pUi->m_listWidget_selectionGroups->selectedItems().at(i)->text() != "All EEG") {
818 tempSelectedList.append(m_pUi->m_listWidget_selectionGroups->selectedItems().at(i));
819 m_selectionGroupsMap.remove(m_pUi->m_listWidget_selectionGroups->selectedItems().at(i)->text());
820 }
821 }
822
823 qDeleteAll(tempSelectedList);
825
826 return true;
827 } else
828 return false;
829 }
830
831 // pass the event on to the parent class
832 return QWidget::eventFilter(obj, event);
833}
834
835//=============================================================================================================
836
838{
839 return m_pUi->viewWidget;
840}
841
842//=============================================================================================================
843
845{
846 return m_pUi->controlWidget;
847}
848
849//=============================================================================================================
850
852{
853 return ((m_pUi->m_listWidget_selectionGroups->currentItem()->text() == "All") && (m_pUi->m_listWidget_userDefined->count() == 0));
854}
855
856//=============================================================================================================
857
859{
860 m_pSelectionScene->clear();
861}
Static MATLAB-style FIFF facade: thin wrapper functions kept for parity with the historical mne-matla...
#define FIFFV_EEG_CH
#define FIFFV_MEG_CH
Generator that projects 3-D electrode positions onto a 2-D .lout topographic layout via least-squares...
Reader / writer for MNE .sel channel-selection files and Brainstorm .mon montage files.
Interactive 2-D sensor-layout picker for building and saving channel groups.
QAbstractTableModel exposing per-channel FIFF metadata (name, type, unit, position,...
QGraphicsScene of the sensor-layout dots used by DISPLIB::ChannelSelectionView for interactive channe...
Channel-selection group descriptor (DISPLIB::SelectionItem) and the matching QGraphicsItem (DISPLIB::...
2-D plotter layout read from an MNE-C .lout file: viewports, channel matching and zoom.
FIFF file I/O, in-memory data structures and high-level readers/writers.
2-D display widgets and visualisation helpers (charts, topography, colour maps).
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
AbstractView(QWidget *parent=0, Qt::WindowFlags f=Qt::Widget)
void selectionChanged(const QList< QGraphicsItem * > &selectedChannelItems)
QListWidgetItem * getItemForChName(QListWidget *listWidget, const QString &channelName)
const QMap< QString, QPointF > & getLayoutMap()
void showSelectedChannelsOnly(QStringList selectedChannels)
void updateProcessingMode(ProcessingMode mode)
ChannelSelectionView(const QString &sSettingsPath="", QWidget *parent=0, QSharedPointer< ChannelInfoModel > pChannelInfoModel=QSharedPointer< ChannelInfoModel >(0), Qt::WindowType f=Qt::Widget)
void highlightChannels(QModelIndexList channelIndexList)
void newFiffFileLoaded(QSharedPointer< FIFFLIB::FiffInfo > &pFiffInfo)
void selectChannels(QStringList channelList)
void setCurrentlyMappedFiffChannels(const QStringList &mappedLayoutChNames)
void loadedLayoutMap(const QMap< QString, QPointF > &layoutMap)
void setCurrentLayoutFile(QString currentLayoutFile)
QSharedPointer< ChannelInfoModel > SPtr
QGraphicsScene of sensor-layout dots used by ChannelSelectionView for interactive channel picking.
Graphics item representing a selectable electrode or channel in a 2-D layout scene.
static std::optional< MNELayout > read(const QString &path)
static bool makeLayout(const QList< QVector< float > > &inputPoints, QList< QVector< float > > &outputPoints, const QStringList &names, QFile &outFile, bool do_fit, float prad, float w, float h, bool writeFile=false, bool mirrorXAxis=false, bool mirrorYAxis=false)
static bool readBrainstormMonFile(QString path, QMultiMap< QString, QStringList > &selectionMap)
static bool writeBrainstormMonFiles(QString path, const QMultiMap< QString, QStringList > &selectionMap)
static bool readMNESelFile(QString path, QMultiMap< QString, QStringList > &selectionMap)
static bool writeMNESelFile(QString path, const QMultiMap< QString, QStringList > &selectionMap)