33 #include <QStringBuilder>
40 #include <kdatetime.h>
42 #include <kio/netaccess.h>
43 #include <ktemporaryfile.h>
49 #define NUM_LANG_WITH_INFO 41
96 "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;",
97 "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;",
98 "nplurals=2; plural=(n != 1);",
99 "nplurals=2; plural=(n != 1);",
100 "nplurals=2; plural=(n != 1);",
101 "nplurals=2; plural=(n != 1);",
102 "nplurals=2; plural=(n != 1);",
103 "nplurals=2; plural=(n != 1);",
104 "nplurals=2; plural=(n != 1);",
105 "nplurals=2; plural=(n != 1);",
106 "nplurals=2; plural=(n != 1);",
107 "nplurals=2; plural=(n != 1);",
108 "nplurals=2; plural=(n != 1);",
109 "nplurals=2; plural=(n > 1);",
110 "nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;",
111 "nplurals=2; plural=(n != 1);",
112 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
113 "nplurals=2; plural=(n != 1);",
114 "nplurals=2; plural=(n != 1);",
115 "nplurals=1; plural=0;",
116 "nplurals=1; plural=0;",
117 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);",
118 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);",
119 "nplurals=2; plural=(n != 1);",
120 "nplurals=2; plural=(n != 1);",
121 "nplurals=2; plural=(n != 1);",
122 "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
123 "nplurals=2; plural=(n != 1);",
124 "nplurals=2; plural=(n > 1);",
125 "nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;",
126 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
127 "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;",
128 "nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0);",
129 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
130 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
131 "nplurals=2; plural=(n != 1);",
132 "nplurals=1; plural=0;",
133 "nplurals=2; plural=(n > 1);",
134 "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
135 "nplurals=1; plural=0;",
136 "nplurals=1; plural=0;"
142 QRegExp rxplural(
"Plural-Forms:\\s*nplurals=(.);");
143 if (rxplural.
indexIn(header) == -1)
155 QRegExp rxplural(
"nplurals=(.);");
156 if (rxplural.
indexIn(expr) == -1)
171 if (KDE_ISLIKELY( i>=0 ))
177 qWarning()<<
"gonna call msginit";
178 QString def=
"nplurals=2; plural=n != 1;";
181 arguments <<
"-l" << lang
187 msginit.
start(
"msginit", arguments);
190 if (KDE_ISUNLIKELY( msginit.
state()!=QProcess::Running ))
197 "# SOME DESCRIPTIVE TITLE.\n"
198 "# Copyright (C) YEAR Free Software Foundation, Inc.\n"
199 "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n"
204 "\"Project-Id-Version: PACKAGE VERSION\\n\"\n"
205 "\"POT-Creation-Date: 2002-06-25 03:23+0200\\n\"\n"
206 "\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n"
207 "\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n"
208 "\"Language-Team: LANGUAGE <LL@li.org>\\n\"\n"
209 "\"Language: LL\\n\"\n"
210 "\"MIME-Version: 1.0\\n\"\n"
211 "\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
212 "\"Content-Transfer-Encoding: ENCODING\\n\"\n"
219 kWarning()<<
"msginit error";
225 int pos = result.
indexOf(
"Plural-Forms: ");
226 if (KDE_ISUNLIKELY( pos==-1 ))
233 int end = result.
indexOf(
'"',pos);
234 if (KDE_ISUNLIKELY( pos==-1 ))
248 int& numberOfPluralForms,
249 const QString& CatalogProjectId,
250 bool generatedFromDocbook,
251 bool belongsToProject,
267 temp=
"Last-Translator: "%authorNameEmail%
"\\n";
269 QRegExp lt(
"^ *Last-Translator:.*");
270 for ( it = headerList.begin(),found=
false; it != headerList.end() && !found; ++it )
272 if (it->contains(lt))
274 if (forSaving) *it = temp;
278 if (KDE_ISUNLIKELY( !found ))
281 QString dateTimeString = KDateTime::currentLocalDateTime().toString(
"%Y-%m-%d %H:%M%z");
282 temp=
"PO-Revision-Date: "%dateTimeString%
"\\n";
283 QRegExp poRevDate(
"^ *PO-Revision-Date:.*");
284 for ( it = headerList.begin(),found=
false; it != headerList.end() && !found; ++it )
286 found=it->contains(poRevDate);
287 if (found && forSaving) *it = temp;
289 if (KDE_ISUNLIKELY( !found ))
292 temp=
"Project-Id-Version: "%CatalogProjectId%
"\\n";
294 QRegExp projectIdVer(
"^ *Project-Id-Version:.*");
295 for ( it = headerList.begin(),found=
false; it != headerList.end() && !found; ++it )
297 found=it->contains(projectIdVer);
298 if (found && it->contains(
"PACKAGE VERSION"))
301 if (KDE_ISUNLIKELY( !found ))
311 static KConfig* allLanguagesConfig=0;
312 if (!allLanguagesConfig)
314 allLanguagesConfig =
new KConfig(
"all_languages", KConfig::NoGlobals,
"locale");
315 allLanguagesConfig->setLocale(
QString());
317 QRegExp langTeamRegExp(
"^ *Language-Team:.*");
318 for ( it = headerList.begin(),found=
false; it != headerList.end() && !found; ++it )
320 found=it->contains(langTeamRegExp);
325 foreach (
const QString &runningLangCode, KGlobal::locale()->allLanguagesList())
327 KConfigGroup cg(allLanguagesConfig, runningLangCode);
328 map[cg.readEntry(
"Name")]=runningLangCode;
331 kWarning()<<
"seems that all_languages file is missing (usually located under /usr/share/locale)";
333 QRegExp re(
"^ *Language-Team: *(.*) *<([^>]*)>");
340 langCode=map.
value(language);
351 KConfigGroup cg(allLanguagesConfig, langCode);
352 language=cg.readEntry(
"Name");
357 if (mailingList.
isEmpty() || belongsToProject)
367 temp=
"Language-Team: "%language%
" <"%mailingList%
'>';
369 if (KDE_ISLIKELY( found ))
374 QRegExp langCodeRegExp(
"^ *Language: *([^ \\\\]*)");
375 temp=
"Language: "%langCode%
"\\n";
376 for ( it = headerList.begin(),found=
false; it != headerList.end() && !found; ++it )
378 found=(langCodeRegExp.
indexIn(*it)!=-1);
383 if (KDE_ISUNLIKELY( !found ))
386 temp=
"Content-Type: text/plain; charset="%codec->
name()%
"\\n";
387 for ( it = headerList.begin(),found=
false; it != headerList.end() && !found; ++it )
392 if (KDE_ISUNLIKELY( !found ))
397 temp=
"Content-Transfer-Encoding: 8bit\\n";
399 for ( it = headerList.begin(),found=
false; it != headerList.end() && !found; ++it )
402 headerList.append(temp);
405 temp=
"MIME-Version: 1.0\\n";
406 for ( it = headerList.begin(),found=
false; it != headerList.end()&& !found; ++it )
409 if (found) *it = temp;
411 if (KDE_ISUNLIKELY( !found ))
417 for ( it = headerList.begin(),found=
false; it != headerList.end()&& !found; ++it )
427 if (generatedFromDocbook)
431 kWarning()<<
"No plural form info in header, using project-defined one"<<langCode;
436 QRegExp pf(
"^ *Plural-Forms:\\s*nplurals.*\\\\n");
444 kWarning()<<
"no... smth went wrong :(\ncheck your gettext install";
449 numberOfPluralForms=num;
452 else if ( !generatedFromDocbook)
459 headerList.
append(pluralFormLine);
464 temp=
"X-Generator: Lokalize %1\\n";
467 for ( it = headerList.begin(),found=
false; it != headerList.end()&& !found; ++it )
470 if (found) *it = temp;
472 if (KDE_ISUNLIKELY( !found ))
476 header=headerList.join(
"\n");
481 QRegExp fsfc(
"^# *Copyright (\\(C\\)|\\x00a9).*Free Software Foundation, Inc");
482 for ( it = commentList.begin(),found=
false; it != commentList.end()&&!found; ++it )
484 found=it->contains( fsfc ) ;
506 if ( ( !usePrefs || saveOptions.updateDescription )
507 && ( !saveOptions.descriptionString.isEmpty() ) )
509 temp =
"# "+saveOptions.descriptionString;
510 temp.
replace(
"@PACKAGE@", packageName());
511 temp.
replace(
"@LANGUAGE@", identityOptions.languageName);
516 regexpstr.
replace(
"@PACKAGE@",
".*" );
517 regexpstr.
replace(
"@LANGUAGE@",
".*" );
522 QRegExp regexpUntranslated (
"^#\\s+translation of .* to .*\\s*$" );
525 kDebug () <<
"Temp is '" << temp <<
"'";
528 bool foundTemplate=
false;
530 it = commentList.
begin();
531 while ( it != commentList.end() )
533 kDebug () <<
"testing '" << (*it) <<
"'";
534 bool deleteItem =
false;
538 kDebug () <<
"Match ";
544 else if ( regexp.
indexIn( *it ) >= 0 )
549 else if ( regexpUntranslated.
indexIn( *it ) >= 0 )
554 else if ( (*it) ==
"# SOME DESCRIPTIVE TITLE." )
561 it = commentList.erase( it );
565 if (!found) commentList.prepend(temp);
580 QRegExp regexpAuthorYear(
"^#.*(<.+@.+>)?,\\s*([\\d]+[\\d\\-, ]*|YEAR)" );
581 QRegExp regexpYearAlone(
"^# , \\d{4}.?\\s*$" );
582 if (commentList.isEmpty())
584 commentList.append(temp);
589 it = commentList.begin();
590 while ( it != commentList.end() )
592 bool deleteItem =
false;
593 if ( it->indexOf(
"copyright", 0, Qt::CaseInsensitive ) != -1 )
597 else if ( it->contains(
QRegExp(
"#, *fuzzy") ) )
599 else if ( it->contains( regexpYearAlone ) )
606 else if ( it->contains(
"# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.") )
608 else if ( it->contains(
"# SOME DESCRIPTIVE TITLE"))
610 else if ( it->contains( regexpAuthorYear ) )
612 if ( !foundAuthors.
contains( (*it) ) )
615 foundAuthors.
append( (*it) );
622 it = commentList.erase( it );
630 bool foundAuthor =
false;
634 ait = foundAuthors.
end();
635 for ( it = foundAuthors.
begin() ; it!=foundAuthors.
end(); ++it )
640 if ( it->contains( cy ) )
649 foundAuthors.
append(temp);
650 else if ( ait != foundAuthors.
end() )
653 const int index = (*ait).lastIndexOf(
QRegExp(
"[\\d]+[\\d\\-, ]*") );
657 ait->
insert(index+1,
", "%cy);
660 kDebug() <<
"INTERNAL ERROR: author found but iterator dangling!";
665 foundAuthors.
append(temp);
668 foreach (
QString author, foundAuthors)
671 if ( !author.
endsWith(
'.') ) author +=
'.';
672 commentList.
append(author);
677 comment=commentList.join(
"\n");
QString cap(int nth) const
QString & append(QChar ch)
short toShort(bool *ok, int base) const
bool contains(const Key &key) const
virtual QByteArray name() const =0
QString toString(Qt::DateFormat format) const
void setMinimal(bool minimal)
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QString escape(const QString &str)
static Project * instance()
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QString langCode() const
Get LangCode.
static QString defaultLangCode()
Get DefaultLangCode.
static QString authorEmail()
Get authorEmail.
int indexIn(const QString &str, int offset, CaretMode caretMode) const
static QString authorName()
Get authorName.
int indexOf(char ch, int from) const
void append(const T &value)
QString & insert(int position, QChar ch)
static QString defaultMailingList()
Get DefaultMailingList.
QString mailingList() const
Get MailingList.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QByteArray mid(int pos, int len) const
bool contains(QChar ch, Qt::CaseSensitivity cs) const
bool waitForStarted(int msecs)
QString & replace(int position, int n, QChar after)
bool contains(char ch) const
qint64 write(const char *data, qint64 maxSize)
QString fromLatin1(const char *str, int size)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
void start(const QString &program, const QStringList &arguments, QFlags< QIODevice::OpenModeFlag > mode)
QProcess::ProcessState state() const
const T value(const Key &key) const
bool waitForFinished(int msecs)
QByteArray toUtf8() const