summaryrefslogtreecommitdiffstats
path: root/subtitleparser.cpp
blob: 0942eda773d95172adc6851dba230f7d09208dfa (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
#include "subtitleparser.h"
#include <QTextStream>
#include <QString>
#include <QStringList>

Subtitle::Subtitle(QString text, quint64 start, quint64 stop)
{
	m_text = text;
	m_start = start;
	m_stop = stop;
	m_offset = 0;
}
void Subtitle::offsetTime(qint64 time)
{
	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;
}
const 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;
	QString hoursStr = (hours < 10 ? QString('0') : QString()) + QString::number(hours);
	QString minutesStr = (minutes < 10 ? QString('0') : QString()) + QString::number(minutes);
	QString secondsStr = (seconds < 10 ? QString('0') : QString()) + QString::number(seconds);
	QString millisecondsStr = QString::number(milliseconds) + (milliseconds < 100 ? (milliseconds < 10 ? QString("00") : QString('0')) : QString());
	return QString("%1:%2:%3,%4").arg(hoursStr).arg(minutesStr).arg(secondsStr).arg(millisecondsStr);
}
const 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, 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(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');
	}

}