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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
/**
* Tries to find hadifix and mbrola by looking onto the hard disk. This is
* neccessary because both hadifix and mbrola do not have standard
* installation directories.
*/
void findInitialConfig() {
QString hadifixDataPath = findHadifixDataPath();
defaultHadifixExec = findExecutable("txt2pho", hadifixDataPath+"/../");
QStringList list; list += "mbrola"; list += "mbrola-linux-i386";
defaultMbrolaExec = findExecutable(list, hadifixDataPath+"/../../mbrola/");
defaultVoices = findVoices (defaultMbrolaExec, hadifixDataPath);
}
/** Tries to find the hadifix data path by looking into a number of files. */
QString findHadifixDataPath () {
QStringList files;
files += "/etc/txt2pho";
files += QDir::homeDirPath()+"/.txt2phorc";
QStringList::iterator it;
for (it = files.begin(); it != files.end(); ++it) {
QFile file(*it);
if ( file.open(IO_ReadOnly) ) {
QTextStream stream(&file);
while (!stream.atEnd()) {
QString s = stream.readLine().stripWhiteSpace();
// look for a line "DATAPATH=..."
if (s.startsWith("DATAPATH")) {
s = s.mid(8, s.length()-8).stripWhiteSpace();
if (s.startsWith("=")) {
s = s.mid(1, s.length()-1).stripWhiteSpace();
if (s.startsWith("/"))
return s;
else {
QFileInfo info (QFileInfo(*it).dirPath() + "/" + s);
return info.absFilePath();
}
}
}
}
file.close();
}
}
return "/usr/local/txt2pho/";
}
/** Tries to find the an executable by looking onto the hard disk. */
QString findExecutable (const QStringList &names, const QString &possiblePath) {
// a) Try to find it directly
QStringList::ConstIterator it;
QStringList::ConstIterator itEnd = names.constEnd();
for (it = names.constBegin(); it != itEnd; ++it) {
QString executable = KStandardDirs::findExe (*it);
if (!executable.isNull() && !executable.isEmpty())
return executable;
}
// b) Try to find it in the path specified by the second parameter
for (it = names.constBegin(); it != itEnd; ++it) {
QFileInfo info (possiblePath+*it);
if (info.exists() && info.isExecutable() && info.isFile()) {
return info.absFilePath();
}
}
// Both tries failed, so the user has to locate the executable.
return QString::null;
}
/** Tries to find the voice files by looking onto the hard disk. */
QStringList findVoices(QString mbrolaExec, const QString &hadifixDataPath) {
// First of all:
// dereference links to the mbrola executable (if mbrolaExec is a link).
for (int i = 0; i < 10; ++i) {
// If we have a chain of more than ten links something is surely wrong.
QFileInfo info (mbrolaExec);
if (info.exists() && info.isSymLink())
mbrolaExec = info.readLink();
}
// Second:
// create a list of directories that possibly contain voice files
QStringList list;
// 2a) search near the mbrola executable
QFileInfo info (mbrolaExec);
if (info.exists() && info.isFile() && info.isExecutable()) {
QString mbrolaPath = info.dirPath (true);
list += mbrolaPath;
}
// 2b) search near the hadifix data path
info.setFile(hadifixDataPath + "../../mbrola");
QString mbrolaPath = info.dirPath (true) + "/mbrola";
if (!list.contains(mbrolaPath))
list += mbrolaPath;
// 2c) broaden the search by adding subdirs (with a depth of 2)
QStringList subDirs = findSubdirs (list);
QStringList subSubDirs = findSubdirs (subDirs);
list += subDirs;
list += subSubDirs;
// Third:
// look into each of these directories and search for voice files.
QStringList result;
QStringList::iterator it;
for (it = list.begin(); it != list.end(); ++it) {
QDir baseDir (*it, QString::null,
QDir::Name|QDir::IgnoreCase, QDir::Files);
QStringList files = baseDir.entryList();
QStringList::iterator iter;
for (iter = files.begin(); iter != files.end(); ++iter) {
// Voice files start with "MBROLA", but are afterwards binary files
QString filename = *it + "/" + *iter;
QFile file (filename);
if (file.open(IO_ReadOnly)) {
QTextStream stream(&file);
if (!stream.atEnd()) {
QString s = stream.readLine();
if (s.startsWith("MBROLA"))
if (HadifixProc::determineGender(mbrolaExec, filename)
!= HadifixProc::NoVoice
)
result += filename;
file.close();
}
}
}
}
return result;
}
/** Returns a list of subdirs (with absolute paths) */
QStringList findSubdirs (const QStringList &baseDirs) {
QStringList result;
QStringList::ConstIterator it;
QStringList::ConstIterator itEnd = baseDirs.constEnd();
for (it = baseDirs.constBegin(); it != itEnd; ++it) {
// a) get a list of directory names
QDir baseDir (*it, QString::null,
QDir::Name|QDir::IgnoreCase, QDir::Dirs);
QStringList list = baseDir.entryList();
// b) produce absolute paths
QStringList::ConstIterator iter;
QStringList::ConstIterator iterEnd = list.constEnd();
for (iter = list.constBegin(); iter != iterEnd; ++iter) {
if ((*iter != ".") && (*iter != ".."))
result += *it + "/" + *iter;
}
}
return result;
}
|