1 /*
2     SPDX-FileCopyrightText: 2007-2009 Sergio Pistone <sergio_pistone@yahoo.com.ar>
3     SPDX-FileCopyrightText: 2010-2020 Mladen Milinkovic <max@smoothware.net>
4 
5     SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "linesselectionmodel.h"
9 #include "core/subtitle.h"
10 #include "core/subtitleline.h"
11 #include "gui/treeview/linesmodel.h"
12 
13 #include <QDebug>
14 #include <QSignalBlocker>
15 
16 using namespace SubtitleComposer;
17 
18 /**
19  * @brief QItemSelectionModel that doesn't lose selection during model reset
20  */
LinesSelectionModel(LinesModel * model)21 LinesSelectionModel::LinesSelectionModel(LinesModel *model)
22 	: QItemSelectionModel(model),
23 	  m_resetInProgress(false),
24 	  m_currentLine(nullptr)
25 {
26 }
27 
28 void
setCurrentIndex(const QModelIndex & index,QItemSelectionModel::SelectionFlags command)29 LinesSelectionModel::setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
30 {
31 	m_currentLine = static_cast<LinesModel *>(model())->subtitle()->line(index.row());
32 	QItemSelectionModel::setCurrentIndex(index, command);
33 }
34 
35 void
select(const QModelIndex & index,QItemSelectionModel::SelectionFlags command)36 LinesSelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
37 {
38 	select(QItemSelection(index, index), command);
39 }
40 
41 void
select(const QItemSelection & selection,QItemSelectionModel::SelectionFlags command)42 LinesSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
43 {
44 	QItemSelectionModel::select(selection, command);
45 
46 	if(command == NoUpdate)
47 		return;
48 
49 	if(!m_resetInProgress && (command & Clear))
50 		m_selection.clear();
51 
52 	const Subtitle *subtitle = static_cast<LinesModel *>(model())->subtitle();
53 	QModelIndexList sel = selection.indexes();
54 	while(!sel.empty()) {
55 		const SubtitleLine *line = subtitle->line(sel.takeFirst().row());
56 		if(command & Select) {
57 			m_selection.insert(line);
58 		} else if(command & Deselect) {
59 			m_selection.remove(line);
60 		} else if(command & Toggle) {
61 			if(m_selection.contains(line))
62 				m_selection.remove(line);
63 			else
64 				m_selection.insert(line);
65 		}
66 	}
67 }
68 
69 void
clear()70 LinesSelectionModel::clear()
71 {
72 	QItemSelectionModel::clear();
73 	if(!m_resetInProgress) {
74 		m_currentLine = nullptr;
75 		m_selection.clear();
76 	}
77 }
78 
79 void
reset()80 LinesSelectionModel::reset()
81 {
82 	m_resetInProgress = true;
83 	QItemSelectionModel::reset();
84 	m_resetInProgress = false;
85 
86 	if(m_currentLine)
87 		QItemSelectionModel::setCurrentIndex(model()->index(m_currentLine->index(), 0), QItemSelectionModel::Current);
88 
89 	const LinesModel *model = static_cast<LinesModel *>(this->model());
90 	Subtitle *subtitle = model->subtitle();
91 	const int lastCol = model->columnCount() - 1;
92 	for(auto it = m_selection.cbegin(); it != m_selection.cend(); ++it) {
93 		const SubtitleLine *line = *it;
94 		if(line && line->subtitle() == subtitle) {
95 			const int i = line->index();
96 			QItemSelectionModel::select(QItemSelection(model->index(i), model->index(i, lastCol)), QItemSelectionModel::Select);
97 		}
98 	}
99 }
100