diff -r 56cd8111b7f7 -r 41300fa6a67c qmake/generators/symbian/symmake.cpp --- a/qmake/generators/symbian/symmake.cpp Tue Jan 26 12:42:25 2010 +0200 +++ b/qmake/generators/symbian/symmake.cpp Tue Feb 02 00:43:10 2010 +0200 @@ -49,6 +49,8 @@ #include #include #include +#include +#include #define RESOURCE_DIRECTORY_MMP "/resource/apps" #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" @@ -74,6 +76,18 @@ #define MMP_OPTION_CW "OPTION CW" #define MMP_OPTION_ARMCC "OPTION ARMCC" #define MMP_OPTION_GCCE "OPTION GCCE" +#define MMP_LINKEROPTION_CW "LINKEROPTION CW" +#define MMP_LINKEROPTION_ARMCC "LINKEROPTION ARMCC" +#define MMP_LINKEROPTION_GCCE "LINKEROPTION GCCE" +#define MMP_CAPABILITY "CAPABILITY" +#define MMP_EPOCALLOWDLLDATA "EPOCALLOWDLLDATA" +#define MMP_EPOCHEAPSIZE "EPOCHEAPSIZE" +#define MMP_EPOCSTACKSIZE "EPOCSTACKSIZE" +#define MMP_UID "UID" +#define MMP_VENDORID "VENDORID" +#define MMP_VERSION "VERSION" +#define MMP_START_RESOURCE "START RESOURCE" +#define MMP_END_RESOURCE "END" #define SIS_TARGET "sis" #define OK_SIS_TARGET "ok_sis" @@ -172,7 +186,7 @@ { t << "// ============================================================================" << endl; t << "// * Makefile for building: " << escapeFilePath(var("TARGET")) << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// * This file is generated by qmake and should not be modified by the" << endl; t << "// * user." << endl; @@ -226,7 +240,7 @@ generatePkgFile(iconFile); } - writeBldInfContent(t, generatePkg); + writeBldInfContent(t, generatePkg, iconFile); // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile, // but all required data is not yet available. @@ -276,6 +290,8 @@ writeRegRssFile(userRssRules); writeRssFile(numberOfIcons, iconFile); writeLocFile(symbianLangCodes); + if (!project->values("SYMBIANTRANSLATIONS").isEmpty()) + writeSymbianLocFile(symbianLangCodes); } } @@ -401,14 +417,11 @@ .arg(installPathRegResource) .arg(fixedTarget + "_reg.rsc") << endl; - QString myIconFile = iconFile; - myIconFile = myIconFile.replace("\\\\", "\\"); - if (!iconFile.isEmpty()) { t << QString("\"%1epoc32/data/z%2\" - \"!:%3\"") .arg(epocRoot()) - .arg(QString(myIconFile).replace('\\','/')) - .arg(myIconFile) << endl << endl; + .arg(iconFile) + .arg(QDir::toNativeSeparators(iconFile)) << endl << endl; } } } @@ -473,7 +486,7 @@ QTextStream t(&ft); t << "; ==============================================================================" << endl; - t << "; Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "; Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "; This file is generated by qmake and should not be modified by the" << endl; t << "; user." << endl; @@ -636,19 +649,10 @@ incpaths << project->values("UI_HEADERS_DIR"); incpaths << project->values("UI_DIR"); - QString epocPath("epoc32"); for (int j = 0; j < incpaths.size(); ++j) { QString includepath = canonizePath(incpaths.at(j)); appendIfnotExist(sysincspaths, includepath); - // As a workaround for Symbian toolchain insistence to treat include - // statements as relative to source file rather than the file they appear in, - // we generate extra temporary include directories to make - // relative include paths used in various headers to work properly. - // Note that this is not a fix-all solution; it's just a stop-gap measure - // to make Qt itself build until toolchain can support relative includes in - // a way that Qt expects. - if (!includepath.contains(epocPath)) // No temp dirs for epoc includes - appendIfnotExist(sysincspaths, includepath + QString("/" QT_EXTRA_INCLUDE_DIR)); + appendAbldTempDirs(sysincspaths, includepath); } // Remove duplicate include path entries @@ -684,30 +688,75 @@ // Check MMP_RULES for singleton keywords that are overridden QStringList overridableMmpKeywords; - overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE) << QLatin1String(MMP_OPTION_CW) - << QLatin1String(MMP_OPTION_ARMCC) << QLatin1String(MMP_OPTION_GCCE); + QStringList restrictableMmpKeywords; + QStringList restrictedMmpKeywords; + bool inResourceBlock = false; + + overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE); + restrictableMmpKeywords << QLatin1String(MMP_TARGET) << QLatin1String(MMP_SECUREID) + << QLatin1String(MMP_OPTION_CW) << QLatin1String(MMP_OPTION_ARMCC) + << QLatin1String(MMP_OPTION_GCCE) << QLatin1String(MMP_LINKEROPTION_CW) + << QLatin1String(MMP_LINKEROPTION_ARMCC) << QLatin1String(MMP_LINKEROPTION_GCCE) + << QLatin1String(MMP_CAPABILITY) << QLatin1String(MMP_EPOCALLOWDLLDATA) + << QLatin1String(MMP_EPOCHEAPSIZE) << QLatin1String(MMP_EPOCSTACKSIZE) + << QLatin1String(MMP_UID) << QLatin1String(MMP_VENDORID) + << QLatin1String(MMP_VERSION); foreach (QString item, project->values("MMP_RULES")) { if (project->values(item).isEmpty()) { - checkOverridability(overridableMmpKeywords, item); + handleMmpRulesOverrides(item, inResourceBlock, restrictedMmpKeywords, + restrictableMmpKeywords, overridableMmpKeywords); } else { foreach (QString itemRow, project->values(item)) { - checkOverridability(overridableMmpKeywords, itemRow); + handleMmpRulesOverrides(itemRow, inResourceBlock, restrictedMmpKeywords, + restrictableMmpKeywords, overridableMmpKeywords); } } } + + if (restrictedMmpKeywords.size()) { + fprintf(stderr, "Warning: Restricted statements detected in MMP_RULES:\n" + " (%s)\n" + " Use corresponding qmake variable(s) instead.\n", + qPrintable(restrictedMmpKeywords.join(", "))); + } +} + +void SymbianMakefileGenerator::handleMmpRulesOverrides(QString &checkString, + bool &inResourceBlock, + QStringList &restrictedMmpKeywords, + const QStringList &restrictableMmpKeywords, + const QStringList &overridableMmpKeywords) +{ + QString simplifiedString = checkString.simplified(); + + if (!inResourceBlock && simplifiedString.startsWith(MMP_START_RESOURCE, Qt::CaseInsensitive)) + inResourceBlock = true; + else if (inResourceBlock && simplifiedString.startsWith(MMP_END_RESOURCE, Qt::CaseInsensitive)) + inResourceBlock = false; + + // Allow restricted and overridable items in RESOURCE blocks as those do not actually + // override anything. + if (!inResourceBlock) { + appendKeywordIfMatchFound(overriddenMmpKeywords, overridableMmpKeywords, simplifiedString); + appendKeywordIfMatchFound(restrictedMmpKeywords, restrictableMmpKeywords, simplifiedString); + } +} + +void SymbianMakefileGenerator::appendKeywordIfMatchFound(QStringList &list, + const QStringList &keywordList, + QString &checkString) +{ + // Check if checkString starts with any supplied keyword and + // add the found keyword to list if it does. + foreach (QString item, keywordList) { + if (checkString.startsWith(QString(item).append(" "), Qt::CaseInsensitive) + || checkString.compare(item, Qt::CaseInsensitive) == 0) { + appendIfnotExist(list, item); + } + } } -void SymbianMakefileGenerator::checkOverridability(QStringList &overridableKeywords, QString &checkString) -{ - // Check if checkString contains overridable keyword and - // add the keyword to overridden keywords list if so. - QString simplifiedString = checkString.simplified(); - foreach (QString item, overridableKeywords) { - if (simplifiedString.startsWith(item)) - appendIfnotExist(overriddenMmpKeywords, item); - } -} bool SymbianMakefileGenerator::removeDuplicatedStrings(QStringList &stringList) { @@ -729,7 +778,7 @@ void SymbianMakefileGenerator::writeMmpFileHeader(QTextStream &t) { t << "// ==============================================================================" << endl; - t << "// Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// This file is generated by qmake and should not be modified by the" << endl; t << "// user." << endl; @@ -818,7 +867,7 @@ void SymbianMakefileGenerator::addMacro(QTextStream& t, const QString& value) { - t << "MACRO" << "\t\t" << value << endl; + t << "MACRO\t\t" << value << endl; } @@ -827,28 +876,28 @@ bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE); if (targetType == TypeExe) { - t << MMP_TARGET << "\t\t" << fixedTarget << ".exe" << endl; + t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl; if (!skipTargetType) { if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) - t << MMP_TARGETTYPE << "\t\t" << "STDEXE" << endl; + t << MMP_TARGETTYPE "\t\tSTDEXE" << endl; else - t << MMP_TARGETTYPE << "\t\t" << "EXE" << endl; + t << MMP_TARGETTYPE "\t\tEXE" << endl; } } else if (targetType == TypeDll || targetType == TypePlugin) { - t << MMP_TARGET << "\t\t" << fixedTarget << ".dll" << endl; + t << MMP_TARGET "\t\t" << fixedTarget << ".dll" << endl; if (!skipTargetType) { if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) - t << MMP_TARGETTYPE << "\t\t" << "STDDLL" << endl; + t << MMP_TARGETTYPE "\t\tSTDDLL" << endl; else - t << MMP_TARGETTYPE << "\t\t" << "DLL" << endl; + t << MMP_TARGETTYPE "\t\tDLL" << endl; } } else if (targetType == TypeLib) { - t << MMP_TARGET << "\t\t" << fixedTarget << ".lib" << endl; + t << MMP_TARGET "\t\t" << fixedTarget << ".lib" << endl; if (!skipTargetType) { if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) - t << MMP_TARGETTYPE << "\t\t" << "STDLIB" << endl; + t << MMP_TARGETTYPE "\t\tSTDLIB" << endl; else - t << MMP_TARGETTYPE << "\t\t" << "LIB" << endl; + t << MMP_TARGETTYPE "\t\tLIB" << endl; } } else { fprintf(stderr, "Error: Unexpected targettype (%d) in SymbianMakefileGenerator::writeMmpFileTargetPart\n", targetType); @@ -856,30 +905,30 @@ t << endl; - t << "UID" << "\t\t" << uid2 << " " << uid3 << endl; + t << MMP_UID "\t\t" << uid2 << " " << uid3 << endl; if (0 != project->values("TARGET.SID").size()) { - t << MMP_SECUREID << "\t\t" << project->values("TARGET.SID").join(" ") << endl; + t << MMP_SECUREID "\t\t" << project->values("TARGET.SID").join(" ") << endl; } else { if (0 == uid3.size()) - t << MMP_SECUREID << "\t\t" << "0" << endl; + t << MMP_SECUREID "\t\t0" << endl; else - t << MMP_SECUREID << "\t\t" << uid3 << endl; + t << MMP_SECUREID "\t\t" << uid3 << endl; } // default value used from mkspecs is 0 if (0 != project->values("TARGET.VID").size()) { - t << "VENDORID" << "\t\t" << project->values("TARGET.VID").join(" ") << endl; + t << MMP_VENDORID "\t\t" << project->values("TARGET.VID").join(" ") << endl; } t << endl; if (0 != project->first("TARGET.EPOCSTACKSIZE").size()) - t << "EPOCSTACKSIZE" << "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl; + t << MMP_EPOCSTACKSIZE "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl; if (0 != project->values("TARGET.EPOCHEAPSIZE").size()) - t << "EPOCHEAPSIZE" << "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl; + t << MMP_EPOCHEAPSIZE "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl; if (0 != project->values("TARGET.EPOCALLOWDLLDATA").size()) - t << "EPOCALLOWDLLDATA" << endl; + t << MMP_EPOCALLOWDLLDATA << endl; if (targetType == TypePlugin && !project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) { // Use custom def file for Qt plugins @@ -903,25 +952,34 @@ locTarget.append(".rss"); t << "SOURCEPATH\t\t\t. " << endl; - t << "LANG SC "; // no endl - foreach(QString lang, symbianLangCodes) { - t << lang << " "; // no endl + + if (!project->values("SYMBIANTRANSLATIONS").isEmpty()) { + t << MMP_START_RESOURCE "\t\t" << locTarget << endl; + t << "LANGUAGE_IDS" << endl; + t << "HEADER" << endl; + t << "TARGETPATH\t\t\t" RESOURCE_DIRECTORY_MMP << endl; + t << MMP_END_RESOURCE << endl << endl; + } else { + t << "LANG SC "; // no endl + foreach(QString lang, symbianLangCodes) { + t << lang << " "; // no endl + } + t << endl; + t << MMP_START_RESOURCE "\t\t" << locTarget << endl; + t << "HEADER" << endl; + t << "TARGETPATH\t\t\t" RESOURCE_DIRECTORY_MMP << endl; + t << MMP_END_RESOURCE << endl << endl; } - t << endl; - t << "START RESOURCE\t\t" << locTarget << endl; - t << "HEADER" << endl; - t << "TARGETPATH\t\t\t" RESOURCE_DIRECTORY_MMP << endl; - t << "END" << endl << endl; QString regTarget = fixedTarget; regTarget.append("_reg.rss"); t << "SOURCEPATH\t\t\t." << endl; - t << "START RESOURCE\t\t" << regTarget << endl; + t << MMP_START_RESOURCE "\t\t" << regTarget << endl; if (isForSymbianSbsv2()) t << "DEPENDS " << fixedTarget << ".rsg" << endl; t << "TARGETPATH\t\t" REGISTRATION_RESOURCE_DIRECTORY_HW << endl; - t << "END" << endl << endl; + t << MMP_END_RESOURCE << endl << endl; } } @@ -933,7 +991,7 @@ QStringList values = it.value(); for (int i = 0; i < values.size(); ++i) { QString handledPath = values.at(i); - t << "SYSTEMINCLUDE" << "\t\t" << fixPathForMmp(handledPath, current) << endl; + t << "SYSTEMINCLUDE\t\t" << fixPathForMmp(handledPath, current) << endl; } } @@ -989,14 +1047,14 @@ { if (0 != project->first("TARGET.CAPABILITY").size()) { QStringList &capabilities = project->values("TARGET.CAPABILITY"); - t << "CAPABILITY" << "\t\t"; + t << MMP_CAPABILITY "\t\t"; for (int i = 0; i < capabilities.size(); ++i) { QString cap = capabilities.at(i); t << cap << " "; } } else { - t << "CAPABILITY" << "\t\t" << "None"; + t << MMP_CAPABILITY "\t\tNone"; } t << endl << endl; } @@ -1004,6 +1062,7 @@ void SymbianMakefileGenerator::writeMmpFileCompilerOptionPart(QTextStream& t) { QString cw, armcc, gcce; + QString cwlink, armlink, gccelink; if (0 != project->values("QMAKE_CXXFLAGS.CW").size()) { cw.append(project->values("QMAKE_CXXFLAGS.CW").join(" ")); @@ -1053,21 +1112,58 @@ gcce.append(" "); } + if (0 != project->values("QMAKE_LFLAGS.CW").size()) { + cwlink.append(project->values("QMAKE_LFLAGS.CW").join(" ")); + cwlink.append(" "); + } + + if (0 != project->values("QMAKE_LFLAGS.ARMCC").size()) { + armlink.append(project->values("QMAKE_LFLAGS.ARMCC").join(" ")); + armlink.append(" "); + } + + if (0 != project->values("QMAKE_LFLAGS.GCCE").size()) { + gccelink.append(project->values("QMAKE_LFLAGS.GCCE").join(" ")); + gccelink.append(" "); + } + + if (0 != project->values("QMAKE_LFLAGS").size()) { + cwlink.append(project->values("QMAKE_LFLAGS").join(" ")); + cwlink.append(" "); + armlink.append(project->values("QMAKE_LFLAGS").join(" ")); + armlink.append(" "); + gccelink.append(project->values("QMAKE_LFLAGS").join(" ")); + gccelink.append(" "); + } + if (!cw.isEmpty() && cw[cw.size()-1] == ' ') cw.chop(1); if (!armcc.isEmpty() && armcc[armcc.size()-1] == ' ') armcc.chop(1); if (!gcce.isEmpty() && gcce[gcce.size()-1] == ' ') gcce.chop(1); + if (!cwlink.isEmpty() && cwlink[cwlink.size()-1] == ' ') + cwlink.chop(1); + if (!armlink.isEmpty() && armlink[armlink.size()-1] == ' ') + armlink.chop(1); + if (!gccelink.isEmpty() && gccelink[gccelink.size()-1] == ' ') + gccelink.chop(1); - if (!cw.isEmpty() && !overriddenMmpKeywords.contains(MMP_OPTION_CW)) + if (!cw.isEmpty()) t << MMP_OPTION_CW " " << cw << endl; - if (!armcc.isEmpty() && !overriddenMmpKeywords.contains(MMP_OPTION_ARMCC)) + if (!armcc.isEmpty()) t << MMP_OPTION_ARMCC " " << armcc << endl; - if (!gcce.isEmpty() && !overriddenMmpKeywords.contains(MMP_OPTION_GCCE)) + if (!gcce.isEmpty()) t << MMP_OPTION_GCCE " " << gcce << endl; - t << endl; + if (!cwlink.isEmpty()) + t << MMP_LINKEROPTION_CW " " << cwlink << endl; + if (!armlink.isEmpty()) + t << MMP_LINKEROPTION_ARMCC " " << armlink << endl; + if (!gccelink.isEmpty()) + t << MMP_LINKEROPTION_GCCE " " << gccelink << endl; + + t << endl; } void SymbianMakefileGenerator::writeMmpFileBinaryVersionPart(QTextStream& t) @@ -1103,7 +1199,7 @@ mmpVersion = "10.0"; // Default binary version for symbian is 10.0 } - t << "VERSION " << mmpVersion << endl; + t << MMP_VERSION " " << mmpVersion << endl; } void SymbianMakefileGenerator::writeMmpFileRulesPart(QTextStream& t) @@ -1122,7 +1218,7 @@ } } -void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension) +void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile) { // Read user defined bld inf rules @@ -1244,7 +1340,7 @@ // Generate extension rules - writeBldInfExtensionRulesPart(t); + writeBldInfExtensionRulesPart(t, iconFile); userItems = userBldInfRules.value(BLD_INF_TAG_EXTENSIONS); foreach(QString item, userItems) @@ -1344,7 +1440,7 @@ generatedFiles << ft.fileName(); QTextStream t(&ft); t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// * This file is generated by qmake and should not be modified by the" << endl; t << "// * user." << endl; @@ -1353,8 +1449,7 @@ t << "#include <" << fixedTarget << ".rsg>" << endl; t << "#include " << endl; t << endl; - //t << "#include " << "\n" << endl; - t << "UID2 " << "KUidAppRegistrationResourceFile" << endl; + t << "UID2 KUidAppRegistrationResourceFile" << endl; t << "UID3 " << uid3 << endl << endl; t << "RESOURCE APP_REGISTRATION_INFO" << endl; t << "\t{" << endl; @@ -1382,14 +1477,17 @@ generatedFiles << ft.fileName(); QTextStream t(&ft); t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// * This file is generated by qmake and should not be modified by the" << endl; t << "// * user." << endl; t << "// ============================================================================" << endl; t << endl; t << "#include " << endl; - t << "#include \"" << fixedTarget << ".loc\"" << endl; + if (!project->values("SYMBIANTRANSLATIONS").isEmpty()) + t << "#include <" << fixedTarget << ".loc>" << endl; + else + t << "#include \"" << fixedTarget << ".loc\"" << endl; t << endl; t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl; t << "\t{" << endl; @@ -1399,14 +1497,17 @@ t << "\t\t{" << endl; t << "\t\tcaption = STRING_r_caption;" << endl; - if (numberOfIcons.isEmpty() || iconFile.isEmpty()) { + QString rssIconFile = iconFile; + rssIconFile = rssIconFile.replace("/", "\\\\"); + + if (numberOfIcons.isEmpty() || rssIconFile.isEmpty()) { // There can be maximum one item in this tag, validated when parsed t << "\t\tnumber_of_icons = 0;" << endl; t << "\t\ticon_file = \"\";" << endl; } else { // There can be maximum one item in this tag, validated when parsed t << "\t\tnumber_of_icons = " << numberOfIcons << ";" << endl; - t << "\t\ticon_file = \"" << iconFile << "\";" << endl; + t << "\t\ticon_file = \"" << rssIconFile << "\";" << endl; } t << "\t\t};" << endl; t << "\t}" << endl; @@ -1419,7 +1520,17 @@ void SymbianMakefileGenerator::writeLocFile(QStringList &symbianLangCodes) { QString filename(fixedTarget); - filename.append(".loc"); + if (project->values("SYMBIANTRANSLATIONS").isEmpty()) { + filename.append(".loc"); + } else { + if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) { + filename.insert(0,project->first("SYMBIANLOCFILESDIR")); + } else { + filename.insert(0,"/epoc32/include/platform/app/loc/"); + } + filename.append(".loc"); + } + QFile ft(filename); if (ft.open(QIODevice::WriteOnly)) { if (Option::mkfile::listgen) { @@ -1428,12 +1539,13 @@ generatedFiles << ft.fileName(); QTextStream t(&ft); t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// * This file is generated by qmake and should not be modified by the" << endl; t << "// * user." << endl; t << "// ============================================================================" << endl; t << endl; + if (project->values("SYMBIANTRANSLATIONS").isEmpty()) { t << "#ifdef LANGUAGE_SC" << endl; t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; @@ -1447,10 +1559,122 @@ t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; t << "#endif" << endl; } else { + t << "#if LANGUAGE_01" << endl; + t << "#include <" << "01/" << fixedTarget << "_01.loc>" << endl; + foreach(QString lang, symbianLangCodes) { + if (lang.localeAwareCompare("01") != 0) { + t << "#elif LANGUAGE_" << lang << endl; + t << "#include <" << lang << "/" << fixedTarget << "_" << lang << ".loc>" << ">" << endl; + } + } + t << "#endif" << endl; + } + } else { PRINT_FILE_CREATE_ERROR(filename); } } +void SymbianMakefileGenerator::writeSymbianLocFile(QStringList &symbianLangCodes) +{ + QString filename(fixedTarget); + foreach(QString lang, symbianLangCodes) { + + QString tsFilename(filename); + QString language = qt2S60LangMapTable.key(lang, QString("en")); + tsFilename.append("_"+language+".ts"); + tsFilename.insert(0,project->first("SYMBIANTRANSLATIONDIR")); + + QString locFilename(filename); + locFilename.append("_"+lang+".loc"); + if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) { + locFilename.insert(0,lang+"/"); + locFilename.insert(0,project->first("SYMBIANLOCFILESDIR")); + } else { + locFilename.insert(0,"/epoc32/include/platform/app/loc/"+lang+"/"); + } + + QString shortCaption; + QString longCaption; + + // get captions from ts file + QFile tsFile(tsFilename); + if (tsFile.exists()) { + if (tsFile.open(QIODevice::ReadOnly)) { + QString shortCaptionId = QLatin1String("txt_short_caption_"); + shortCaptionId.append(filename); + QString longCaptionId = QLatin1String("txt_long_caption_"); + longCaptionId.append(filename); + QXmlStreamReader xml(&tsFile); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "context") { + while (!(xml.isEndElement() && xml.name() == "context") && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "message" && + xml.attributes().value("numerus") == "no" && + xml.attributes().value("id") == shortCaptionId) { + while (!(xml.isEndElement() && xml.name() == "message") && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "translation") { + shortCaption = xml.readElementText(); + } + } + } + if (xml.isStartElement() && xml.name() == "message" && + xml.attributes().value("numerus") == "no" && + xml.attributes().value("id") == longCaptionId) { + while (!(xml.isEndElement() && xml.name() == "message") && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "translation") { + longCaption = xml.readElementText(); + } + } + } + } + } + } + if (shortCaption.isEmpty()) + fprintf(stderr, "Warning: STRING_r_short_caption not generated from file '%s'.\n", qPrintable(tsFilename)); + if (longCaption.isEmpty()) + fprintf(stderr, "Warning: STRING_r_caption not generated from file '%s'.\n", qPrintable(tsFilename)); + if (xml.hasError()) + fprintf(stderr, "ERROR: \"%s\" when parsing ts file\n", qPrintable(xml.errorString())); + } else { + fprintf(stderr, "Could not open ts file (%s)\n", qPrintable(tsFilename)); + } + } else { + fprintf(stderr, "ts file does not exist: (%s)\n", qPrintable(tsFilename)); + } + + // generate language specific caption loc file + QFile ft(locFilename); + if (ft.open(QIODevice::WriteOnly)) { + generatedFiles << ft.fileName(); + QTextStream t(&ft); + t << "// ============================================================================" << endl; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; + t << "// * This file is generated by qmake and should not be modified by the" << endl; + t << "// * user." << endl; + t << "// ============================================================================" << endl; + t << endl; + if (!shortCaption.isEmpty()) { + t << "#define STRING_r_short_caption \"" << shortCaption << "\"" << endl; + } else { + t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; + } + if (!longCaption.isEmpty()) { + t << "#define STRING_r_caption \"" << longCaption << "\"" << endl; + } else { + t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + } + ft.close(); + } else { + PRINT_FILE_CREATE_ERROR(locFilename); + } + } +} + void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons, QString &iconFile, QStringList &userRssRules) { for (QMap::iterator it = project->variables().begin(); it != project->variables().end(); ++it) { @@ -1541,17 +1765,26 @@ fillQt2S60LangMapTable(); - foreach(QString file, tsfiles) { - int extIndex = file.lastIndexOf("."); - int langIndex = file.lastIndexOf("_", (extIndex - file.length())); - langIndex += 1; - QString qtlang = file.mid(langIndex, extIndex - langIndex); - QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC")); + if (project->values("SYMBIANTRANSLATIONS").isEmpty()) { + foreach(QString file, tsfiles) { + int extIndex = file.lastIndexOf("."); + int langIndex = file.lastIndexOf("_", (extIndex - file.length())); + langIndex += 1; + QString qtlang = file.mid(langIndex, extIndex - langIndex); + QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC")); + if (!symbianLangCodes.contains(s60lang) && s60lang != "SC") + symbianLangCodes += s60lang; + } + } else { + modifyQt2S60LangMapTable(); // Modify the table according to the system_languages.ini file + foreach(QString symbianTranslation, project->values("SYMBIANTRANSLATIONS")) { + QString s60lang = qt2S60LangMapTable.value(symbianTranslation, QString("SC")); - if (!symbianLangCodes.contains(s60lang) && s60lang != "SC") - symbianLangCodes += s60lang; + if (!symbianLangCodes.contains(s60lang) && s60lang != "SC") + symbianLangCodes += s60lang; + } } - + return symbianLangCodes; } @@ -1724,6 +1957,24 @@ qt2S60LangMapTable.insert("ny", "SC"); //Chewa // } +void SymbianMakefileGenerator::modifyQt2S60LangMapTable() +{ + QString systemLanguagesIniFile = project->first("SYMBIANTRANSLATIONDIR"). + append(QLatin1String("system_languages.ini")); + QFileInfo systemLangFileInfo(systemLanguagesIniFile); + if (systemLangFileInfo.exists()) { + QSettings systemLanguages(systemLanguagesIniFile, QSettings::IniFormat); + QStringList keys = systemLanguages.allKeys(); + foreach (const QString &qtlang, keys){ + QString s60lang = systemLanguages.value(qtlang).toString(); + if (s60lang.localeAwareCompare(qt2S60LangMapTable.value(qtlang, QString("SC"))) != 0) { + qt2S60LangMapTable.insert(qtlang, s60lang); + fprintf(stderr, "Inserted: s60lang '%s' for qtlang '%s'.\n", qPrintable(s60lang), qPrintable(qtlang)); + } + } + } +} + void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QString value) { if (!list.contains(value)) @@ -1779,6 +2030,7 @@ void SymbianMakefileGenerator::removeSpecialCharacters(QString& str) { + // When modifying this method check also application_icon.prf str.replace(QString("/"), QString("_")); str.replace(QString("\\"), QString("_")); str.replace(QString("-"), QString("_"));