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