summaryrefslogtreecommitdiffstats
path: root/subtitleparser.cpp
blob: 2c91f06daec4df1abd048076c1e6210a5192412e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "subtitleparser.h"
#include <QTextStream>
#include <QString>
#include <QStringList>
#include <QDebug>

Subtitle::Subtitle(const QString &text, quint64 start, quint64 stop)
{
	m_text = text;
	m_start = start;
	m_stop = stop;
	m_offset = 0;
}
void Subtitle::offsetTime(qint64 time)
{
	if (time < 0 && static_cast<qint64>(m_start) < -time)
		m_offset = -m_start;
	else
		m_offset = time;
}
bool Subtitle::isContainedIn(quint64 time) const
{
	return time >= (m_start + m_offset) && time <= (m_stop + m_offset);
}
QString Subtitle::text() const
{
	return m_text;
}
bool Subtitle::isAfter(quint64 time) const
{
	return (m_stop + m_offset) > time;
}
QString Subtitle::formatTime(quint64 time) const
{
	quint64 hours = time / (1000 * 60 * 60);
	quint64 leftover = time % (1000 * 60 * 60);
	quint64 minutes = leftover / (1000 * 60);
	leftover = leftover % (1000 * 60);
	quint64 seconds = leftover / 1000;
	quint64 milliseconds = leftover % 1000;
	QChar zero = QLatin1Char('0');
	return QString("%1:%2:%3,%4").
			arg(hours, 2, 10, zero).
			arg(minutes, 2, 10, zero).
			arg(seconds, 2, 10, zero).
			arg(QString(QString::number(milliseconds) + QLatin1String("00")).left(3));
}
QString Subtitle::toString() const
{
	return QString("%1 --> %2\n%3\n").arg(formatTime(m_start + m_offset)).arg(formatTime(m_stop + m_offset)).arg(m_text);
}

SubtitleParser::SubtitleParser(QIODevice *toRead, const QString &fileName)
{
	m_fileName = fileName;
	QTextStream reader(toRead);
	QString nextLine;
	while (!(nextLine = reader.readLine()).isNull()) {
		QString timeStamp = reader.readLine();
		QString text;
		bool notFirst = false;
		while (!(nextLine = reader.readLine()).isEmpty()) {
			if (notFirst) {
				text.append("\n");
			}
			notFirst = true;
			text.append(nextLine);
		}
		QStringList times = timeStamp.split(" --> ");
		if (times.length() != 2) break;
		m_subtitles.append(Subtitle(text, parseTime(times[0]), parseTime(times[1])));
	}
	m_searchPosition = m_subtitles.constBegin();
}
quint64 SubtitleParser::parseTime(const QString &time)
{
	QStringList split = time.split(':');
	if (split.length() != 3)
		return 0;
	QStringList secs = split[2].split(',');
	if (secs.length() != 2)
		return 0;
	return
			split[0].toULongLong() * 60 * 60 * 1000 +
			split[1].toULongLong() * 60 * 1000 +
			secs[0].toULongLong() * 1000 +
			secs[1].toULongLong();
}
QString SubtitleParser::fileName() const
{
	return m_fileName;
}
QString SubtitleParser::subtitleAtTime(quint64 time)
{
	QLinkedList<Subtitle>::const_iterator i;
	bool forward = true;
	for (i = m_searchPosition; i != m_subtitles.constEnd(); ) {
		if (i->isContainedIn(time)) {
			m_searchPosition = i;
			return i->text();
		}
		if (i->isAfter(time)) {
			if (i == m_subtitles.constBegin())
				break;
			--i;
			forward = false;
		} else {
			if (!forward)
				break;
			++i;
		}
	}
	return QString(' ');
}
void SubtitleParser::offsetTime(qint64 time)
{
	for (QLinkedList<Subtitle>::iterator i = m_subtitles.begin(); i != m_subtitles.end(); ++i)
		i->offsetTime(time);
}
void SubtitleParser::writeOut(QIODevice *toWrite)
{
	QTextStream writer(toWrite);
	int number = 0;
	for (QLinkedList<Subtitle>::const_iterator i = m_subtitles.constBegin(); i != m_subtitles.constEnd(); i++) {
		writer << ++number << QChar('\n') << i->toString();
		if (i + 1 != m_subtitles.constEnd())
			writer << QChar('\n');
	}

}