Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
118
qt/build_style/build_common.cpp
Normal file
118
qt/build_style/build_common.cpp
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
#include "build_common.h"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "base/file_name_utils.hpp"
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QProcessEnvironment>
|
||||
|
||||
#include <exception>
|
||||
#include <iomanip> // std::quoted
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
QString ExecProcess(QString const & program, std::initializer_list<QString> args, QProcessEnvironment const * env)
|
||||
{
|
||||
// Quote all arguments.
|
||||
QStringList qargs(args);
|
||||
for (auto i = qargs.begin(); i != qargs.end(); ++i)
|
||||
*i = "\"" + *i + "\"";
|
||||
|
||||
QProcess p;
|
||||
if (nullptr != env)
|
||||
p.setProcessEnvironment(*env);
|
||||
|
||||
p.start(program, qargs, QIODevice::ReadOnly);
|
||||
p.waitForFinished(-1);
|
||||
|
||||
int const exitCode = p.exitCode();
|
||||
QString output = p.readAllStandardOutput();
|
||||
QString const error = p.readAllStandardError();
|
||||
if (exitCode != 0)
|
||||
{
|
||||
QString msg = "Error: " + program + " " + qargs.join(" ") + "\nReturned " + QString::number(exitCode);
|
||||
if (!output.isEmpty())
|
||||
msg += "\n" + output;
|
||||
if (!error.isEmpty())
|
||||
msg += "\nSTDERR:\n" + error;
|
||||
throw std::runtime_error(msg.toStdString());
|
||||
}
|
||||
if (!error.isEmpty())
|
||||
{
|
||||
QString const msg = "STDERR with a zero exit code:\n" + program + " " + qargs.join(" ");
|
||||
throw std::runtime_error(msg.toStdString());
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
bool CopyFile(QString const & oldFile, QString const & newFile)
|
||||
{
|
||||
if (oldFile == newFile)
|
||||
return true;
|
||||
if (!QFile::exists(oldFile))
|
||||
return false;
|
||||
if (QFile::exists(newFile) && !QFile::remove(newFile))
|
||||
return false;
|
||||
return QFile::copy(oldFile, newFile);
|
||||
}
|
||||
|
||||
void CopyFromResources(QString const & name, QString const & output)
|
||||
{
|
||||
QString const resourceDir = GetPlatform().ResourcesDir().c_str();
|
||||
if (!CopyFile(JoinPathQt({resourceDir, name}), JoinPathQt({output, name})))
|
||||
throw std::runtime_error(std::string("Cannot copy file ") + name.toStdString() + " to " + output.toStdString());
|
||||
}
|
||||
|
||||
void CopyToResources(QString const & name, QString const & input, QString const & newName)
|
||||
{
|
||||
QString const resourceDir = GetPlatform().ResourcesDir().c_str();
|
||||
if (!CopyFile(JoinPathQt({input, name}), JoinPathQt({resourceDir, newName.isEmpty() ? name : newName})))
|
||||
throw std::runtime_error(std::string("Cannot copy file ") + name.toStdString() + " from " + input.toStdString());
|
||||
}
|
||||
|
||||
QString JoinPathQt(std::initializer_list<QString> folders)
|
||||
{
|
||||
QString result;
|
||||
bool firstInserted = false;
|
||||
for (auto it = folders.begin(); it != folders.end(); ++it)
|
||||
{
|
||||
if (it->isEmpty() || *it == QDir::separator())
|
||||
continue;
|
||||
|
||||
if (firstInserted)
|
||||
result.append(QDir::separator());
|
||||
|
||||
result.append(*it);
|
||||
firstInserted = true;
|
||||
}
|
||||
return QDir::cleanPath(result);
|
||||
}
|
||||
|
||||
QString GetExternalPath(QString const & name, QString const & primaryPath, QString const & secondaryPath)
|
||||
{
|
||||
QString const resourceDir = GetPlatform().ResourcesDir().c_str();
|
||||
QString path = JoinPathQt({resourceDir, primaryPath, name});
|
||||
if (!QFileInfo::exists(path))
|
||||
path = JoinPathQt({resourceDir, secondaryPath, name});
|
||||
|
||||
// Special case for looking for in application folder.
|
||||
if (!QFileInfo::exists(path) && secondaryPath.isEmpty())
|
||||
{
|
||||
std::string const appPath = QCoreApplication::applicationDirPath().toStdString();
|
||||
|
||||
std::regex re("(/[^/]*\\.app)");
|
||||
std::smatch m;
|
||||
if (std::regex_search(appPath, m, re) && m.size() > 0)
|
||||
path.fromStdString(base::JoinPath(m[0], name.toStdString()));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
QString GetProtobufEggPath()
|
||||
{
|
||||
return GetExternalPath("protobuf-3.3.0-py2.7.egg", "kothic", "../3party/protobuf");
|
||||
}
|
||||
24
qt/build_style/build_common.h
Normal file
24
qt/build_style/build_common.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
class QProcessEnvironment;
|
||||
|
||||
// Returns stdout output of the program, throws std::runtime_error in case of non-zero exit code.
|
||||
// Quotes all arguments to avoid issues with space-containing paths.
|
||||
QString ExecProcess(QString const & program, std::initializer_list<QString> args, QProcessEnvironment const * env = nullptr);
|
||||
|
||||
bool CopyFile(QString const & oldFile, QString const & newFile);
|
||||
|
||||
void CopyFromResources(QString const & name, QString const & output);
|
||||
void CopyToResources(QString const & name, QString const & input, QString const & newName = "");
|
||||
|
||||
QString JoinPathQt(std::initializer_list<QString> folders);
|
||||
|
||||
QString GetExternalPath(QString const & name, QString const & primaryPath,
|
||||
QString const & secondaryPath);
|
||||
QString GetProtobufEggPath();
|
||||
64
qt/build_style/build_drules.cpp
Normal file
64
qt/build_style/build_drules.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include "build_drules.h"
|
||||
#include "build_common.h"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QProcessEnvironment>
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
void BuildDrawingRulesImpl(QString const & mapcssFile, QString const & outputDir)
|
||||
{
|
||||
QString const outputTemplate = JoinPathQt({outputDir, "drules_proto_design"});
|
||||
QString const outputFile = outputTemplate + ".bin";
|
||||
|
||||
// Caller ensures that output directory is clear
|
||||
if (QFile(outputFile).exists())
|
||||
throw std::runtime_error("Output directory is not clear");
|
||||
|
||||
// Add path to the protobuf EGG in the PROTOBUF_EGG_PATH environment variable
|
||||
QProcessEnvironment env{QProcessEnvironment::systemEnvironment()};
|
||||
env.insert("PROTOBUF_EGG_PATH", GetProtobufEggPath());
|
||||
|
||||
// Run the script
|
||||
(void)ExecProcess("python",
|
||||
{
|
||||
GetExternalPath("libkomwm.py", "kothic/src", "../tools/kothic/src"),
|
||||
"-s",
|
||||
mapcssFile,
|
||||
"-o",
|
||||
outputTemplate,
|
||||
"-x",
|
||||
"True",
|
||||
},
|
||||
&env);
|
||||
|
||||
// Ensure that generated file is not empty.
|
||||
if (QFile(outputFile).size() == 0)
|
||||
throw std::runtime_error("Drawing rules file has zero size");
|
||||
}
|
||||
|
||||
void BuildDrawingRules(QString const & mapcssFile, QString const & outputDir)
|
||||
{
|
||||
CopyFromResources("mapcss-mapping.csv", outputDir);
|
||||
CopyFromResources("mapcss-dynamic.txt", outputDir);
|
||||
BuildDrawingRulesImpl(mapcssFile, outputDir);
|
||||
}
|
||||
|
||||
void ApplyDrawingRules(QString const & outputDir)
|
||||
{
|
||||
CopyToResources("drules_proto_design.bin", outputDir);
|
||||
CopyToResources("classificator.txt", outputDir);
|
||||
CopyToResources("types.txt", outputDir);
|
||||
CopyToResources("patterns.txt", outputDir, "patterns_design.txt");
|
||||
CopyToResources("colors.txt", outputDir, "colors_design.txt");
|
||||
}
|
||||
} // namespace build_style
|
||||
9
qt/build_style/build_drules.h
Normal file
9
qt/build_style/build_drules.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
void BuildDrawingRules(QString const & mapcssFile, QString const & outputDir);
|
||||
void ApplyDrawingRules(QString const & outputDir);
|
||||
} // build_style
|
||||
27
qt/build_style/build_phone_pack.cpp
Normal file
27
qt/build_style/build_phone_pack.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include "build_statistics.h"
|
||||
|
||||
#include "build_common.h"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
QString RunBuildingPhonePack(QString const & stylesDir, QString const & targetDir)
|
||||
{
|
||||
using std::to_string, std::runtime_error;
|
||||
|
||||
if (!QDir(stylesDir).exists())
|
||||
throw runtime_error("Styles directory does not exist " + stylesDir.toStdString());
|
||||
|
||||
if (!QDir(targetDir).exists())
|
||||
throw runtime_error("target directory does not exist" + targetDir.toStdString());
|
||||
|
||||
return ExecProcess("python",
|
||||
{GetExternalPath("generate_styles_override.py", "", "../tools/python"), stylesDir, targetDir});
|
||||
}
|
||||
} // namespace build_style
|
||||
8
qt/build_style/build_phone_pack.h
Normal file
8
qt/build_style/build_phone_pack.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
QString RunBuildingPhonePack(QString const & stylesFolder, QString const & targetFolder);
|
||||
} // namespace build_style
|
||||
216
qt/build_style/build_skins.cpp
Normal file
216
qt/build_style/build_skins.cpp
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
#include "qt/build_style/build_skins.h"
|
||||
|
||||
#include "qt/build_style/build_common.h"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
|
||||
namespace
|
||||
{
|
||||
enum SkinType
|
||||
{
|
||||
SkinMDPI,
|
||||
SkinHDPI,
|
||||
SkinXHDPI,
|
||||
Skin6Plus,
|
||||
SkinXXHDPI,
|
||||
SkinXXXHDPI,
|
||||
|
||||
// SkinCount MUST BE last
|
||||
SkinCount
|
||||
};
|
||||
|
||||
using SkinInfo = std::tuple<char const *, int, bool>;
|
||||
SkinInfo const g_skinInfo[SkinCount] = {
|
||||
std::make_tuple("mdpi", 18, false), std::make_tuple("hdpi", 27, false), std::make_tuple("xhdpi", 36, false),
|
||||
std::make_tuple("6plus", 43, false), std::make_tuple("xxhdpi", 54, false), std::make_tuple("xxxhdpi", 64, false),
|
||||
};
|
||||
|
||||
std::array<SkinType, SkinCount> const g_skinTypes = {{
|
||||
SkinMDPI,
|
||||
SkinHDPI,
|
||||
SkinXHDPI,
|
||||
Skin6Plus,
|
||||
SkinXXHDPI,
|
||||
SkinXXXHDPI,
|
||||
}};
|
||||
|
||||
inline char const * SkinSuffix(SkinType s)
|
||||
{
|
||||
return std::get<0>(g_skinInfo[s]);
|
||||
}
|
||||
inline int SkinSize(SkinType s)
|
||||
{
|
||||
return std::get<1>(g_skinInfo[s]);
|
||||
}
|
||||
inline bool SkinCoorrectColor(SkinType s)
|
||||
{
|
||||
return std::get<2>(g_skinInfo[s]);
|
||||
}
|
||||
|
||||
QString GetSkinGeneratorPath()
|
||||
{
|
||||
QString const path = GetExternalPath("skin_generator_tool", "skin_generator_tool.app/Contents/MacOS", "");
|
||||
if (path.isEmpty())
|
||||
throw std::runtime_error("Can't find skin_generator_tool");
|
||||
ASSERT(QFileInfo::exists(path), (path.toStdString()));
|
||||
return path;
|
||||
}
|
||||
|
||||
class RAII
|
||||
{
|
||||
public:
|
||||
RAII(std::function<void()> && f) : m_f(std::move(f)) {}
|
||||
~RAII() { m_f(); }
|
||||
|
||||
private:
|
||||
std::function<void()> const m_f;
|
||||
};
|
||||
|
||||
std::string trim(std::string && s)
|
||||
{
|
||||
s.erase(std::remove_if(s.begin(), s.end(), &isspace), s.end());
|
||||
return std::move(s);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
std::unordered_map<std::string, int> GetSkinSizes(QString const & file)
|
||||
{
|
||||
std::unordered_map<std::string, int> skinSizes;
|
||||
|
||||
for (SkinType s : g_skinTypes)
|
||||
skinSizes.insert(std::make_pair(SkinSuffix(s), SkinSize(s)));
|
||||
|
||||
try
|
||||
{
|
||||
std::ifstream ifs(file.toStdString());
|
||||
|
||||
std::string line;
|
||||
while (std::getline(ifs, line))
|
||||
{
|
||||
size_t const pos = line.find('=');
|
||||
if (pos == std::string::npos)
|
||||
continue;
|
||||
|
||||
std::string name(line.begin(), line.begin() + pos);
|
||||
std::string valueTxt(line.begin() + pos + 1, line.end());
|
||||
|
||||
name = trim(std::move(name));
|
||||
int value = std::stoi(trim(std::move(valueTxt)));
|
||||
|
||||
if (value <= 0)
|
||||
continue;
|
||||
|
||||
skinSizes[name] = value;
|
||||
}
|
||||
}
|
||||
catch (std::exception const & e)
|
||||
{
|
||||
// reset
|
||||
for (SkinType s : g_skinTypes)
|
||||
skinSizes[SkinSuffix(s)] = SkinSize(s);
|
||||
}
|
||||
|
||||
return skinSizes;
|
||||
}
|
||||
|
||||
void BuildSkinImpl(QString const & styleDir, QString const & suffix, int size, bool colorCorrection,
|
||||
QString const & outputDir)
|
||||
{
|
||||
QString const symbolsDir = JoinPathQt({styleDir, "symbols"});
|
||||
|
||||
// Check symbols directory exists
|
||||
if (!QDir(symbolsDir).exists())
|
||||
throw std::runtime_error("Symbols directory does not exist");
|
||||
|
||||
// Caller ensures that output directory is clear
|
||||
if (QDir(outputDir).exists())
|
||||
throw std::runtime_error("Output directory is not clear");
|
||||
|
||||
// Create output skin directory
|
||||
if (!QDir().mkdir(outputDir))
|
||||
throw std::runtime_error("Cannot create output skin directory");
|
||||
|
||||
// Create symbolic link for symbols/png
|
||||
QString const pngOriginDir = styleDir + suffix;
|
||||
QString const pngDir = JoinPathQt({styleDir, "symbols", "png"});
|
||||
QFile::remove(pngDir);
|
||||
if (!QFile::link(pngOriginDir, pngDir))
|
||||
throw std::runtime_error("Unable to create symbols/png link");
|
||||
RAII const cleaner([=]() { QFile::remove(pngDir); });
|
||||
|
||||
QString const strSize = QString::number(size);
|
||||
// Run the script.
|
||||
(void)ExecProcess(GetSkinGeneratorPath(), {
|
||||
"--symbolWidth",
|
||||
strSize,
|
||||
"--symbolHeight",
|
||||
strSize,
|
||||
"--symbolsDir",
|
||||
symbolsDir,
|
||||
"--skinName",
|
||||
JoinPathQt({outputDir, "basic"}),
|
||||
"--skinSuffix=",
|
||||
"--colorCorrection",
|
||||
(colorCorrection ? "true" : "false"),
|
||||
});
|
||||
|
||||
// Check if files were created.
|
||||
if (QFile(JoinPathQt({outputDir, "symbols.png"})).size() == 0 ||
|
||||
QFile(JoinPathQt({outputDir, "symbols.sdf"})).size() == 0)
|
||||
{
|
||||
throw std::runtime_error("Skin files have not been created");
|
||||
}
|
||||
}
|
||||
|
||||
void BuildSkins(QString const & styleDir, QString const & outputDir)
|
||||
{
|
||||
QString const resolutionFilePath = JoinPathQt({styleDir, "resolutions.txt"});
|
||||
|
||||
auto const resolution2size = GetSkinSizes(resolutionFilePath);
|
||||
|
||||
for (SkinType s : g_skinTypes)
|
||||
{
|
||||
QString const suffix = SkinSuffix(s);
|
||||
QString const outputSkinDir = JoinPathQt({outputDir, "symbols", suffix, "design"});
|
||||
int const size = resolution2size.at(suffix.toStdString()); // SkinSize(s);
|
||||
bool const colorCorrection = SkinCoorrectColor(s);
|
||||
|
||||
BuildSkinImpl(styleDir, suffix, size, colorCorrection, outputSkinDir);
|
||||
}
|
||||
}
|
||||
|
||||
void ApplySkins(QString const & outputDir)
|
||||
{
|
||||
QString const resourceDir = GetPlatform().ResourcesDir().c_str();
|
||||
|
||||
for (SkinType s : g_skinTypes)
|
||||
{
|
||||
QString const suffix = SkinSuffix(s);
|
||||
QString const outputSkinDir = JoinPathQt({outputDir, "symbols", suffix, "design"});
|
||||
QString const resourceSkinDir = JoinPathQt({resourceDir, "symbols", suffix, "design"});
|
||||
|
||||
if (!QFileInfo::exists(resourceSkinDir) && !QDir().mkdir(resourceSkinDir))
|
||||
throw std::runtime_error("Cannot create resource skin directory: " + resourceSkinDir.toStdString());
|
||||
|
||||
if (!CopyFile(JoinPathQt({outputSkinDir, "symbols.png"}), JoinPathQt({resourceSkinDir, "symbols.png"})) ||
|
||||
!CopyFile(JoinPathQt({outputSkinDir, "symbols.sdf"}), JoinPathQt({resourceSkinDir, "symbols.sdf"})))
|
||||
{
|
||||
throw std::runtime_error("Cannot copy skins files");
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace build_style
|
||||
9
qt/build_style/build_skins.h
Normal file
9
qt/build_style/build_skins.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
void BuildSkins(QString const & styleDir, QString const & outputDir);
|
||||
void ApplySkins(QString const & outputDir);
|
||||
} // namespace build_style
|
||||
46
qt/build_style/build_statistics.cpp
Normal file
46
qt/build_style/build_statistics.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include "build_statistics.h"
|
||||
|
||||
#include "build_common.h"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QProcessEnvironment>
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
QString GetStyleStatistics(QString const & mapcssMappingFile, QString const & drulesFile)
|
||||
{
|
||||
if (!QFile(mapcssMappingFile).exists())
|
||||
throw std::runtime_error("mapcss-mapping file does not exist at " + mapcssMappingFile.toStdString());
|
||||
|
||||
if (!QFile(drulesFile).exists())
|
||||
throw std::runtime_error("drawing-rules file does not exist at " + drulesFile.toStdString());
|
||||
|
||||
// Add path to the protobuf EGG in the PROTOBUF_EGG_PATH environment variable.
|
||||
QProcessEnvironment env{QProcessEnvironment::systemEnvironment()};
|
||||
env.insert("PROTOBUF_EGG_PATH", GetProtobufEggPath());
|
||||
|
||||
// Run the script.
|
||||
return ExecProcess("python",
|
||||
{
|
||||
GetExternalPath("drules_info.py", "kothic/src", "../tools/python/stylesheet"),
|
||||
mapcssMappingFile,
|
||||
drulesFile,
|
||||
},
|
||||
&env);
|
||||
}
|
||||
|
||||
QString GetCurrentStyleStatistics()
|
||||
{
|
||||
QString const resourceDir = GetPlatform().ResourcesDir().c_str();
|
||||
QString const mappingPath = JoinPathQt({resourceDir, "mapcss-mapping.csv"});
|
||||
QString const drulesPath = JoinPathQt({resourceDir, "drules_proto_design.bin"});
|
||||
return GetStyleStatistics(mappingPath, drulesPath);
|
||||
}
|
||||
} // namespace build_style
|
||||
9
qt/build_style/build_statistics.h
Normal file
9
qt/build_style/build_statistics.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
QString GetStyleStatistics(QString const & mapcssMappingFile, QString const & drulesFile);
|
||||
QString GetCurrentStyleStatistics();
|
||||
} // namespace build_style
|
||||
121
qt/build_style/build_style.cpp
Normal file
121
qt/build_style/build_style.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
#include "build_style.h"
|
||||
#include "build_common.h"
|
||||
#include "build_drules.h"
|
||||
#include "build_skins.h"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include <exception>
|
||||
#include <future>
|
||||
#include <string>
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFile>
|
||||
|
||||
namespace
|
||||
{
|
||||
QString GetRecalculateGeometryScriptPath()
|
||||
{
|
||||
return GetExternalPath("recalculate_geom_index.py", "", "../tools/python");
|
||||
}
|
||||
|
||||
QString GetGeometryToolPath()
|
||||
{
|
||||
return GetExternalPath("generator_tool", "generator_tool.app/Contents/MacOS", "");
|
||||
}
|
||||
|
||||
QString GetGeometryToolResourceDir()
|
||||
{
|
||||
return GetExternalPath("", "generator_tool.app/Contents/Resources", "");
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
void BuildAndApply(QString const & mapcssFile)
|
||||
{
|
||||
// Ensure mapcss exists
|
||||
if (!QFile(mapcssFile).exists())
|
||||
throw std::runtime_error("mapcss files does not exist");
|
||||
|
||||
QDir const projectDir = QFileInfo(mapcssFile).absoluteDir();
|
||||
QString const styleDir = projectDir.absolutePath() + QDir::separator();
|
||||
QString const outputDir = styleDir + "out" + QDir::separator();
|
||||
|
||||
// Ensure output directory is clear
|
||||
if (QDir(outputDir).exists() && !QDir(outputDir).removeRecursively())
|
||||
throw std::runtime_error("Unable to remove the output directory");
|
||||
if (!QDir().mkdir(outputDir))
|
||||
throw std::runtime_error("Unable to make the output directory");
|
||||
|
||||
bool const hasSymbols = QDir(styleDir + "symbols/").exists();
|
||||
if (hasSymbols)
|
||||
{
|
||||
auto future = std::async(std::launch::async, BuildSkins, styleDir, outputDir);
|
||||
BuildDrawingRules(mapcssFile, outputDir);
|
||||
future.get(); // may rethrow exception from the BuildSkin
|
||||
|
||||
ApplyDrawingRules(outputDir);
|
||||
ApplySkins(outputDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildDrawingRules(mapcssFile, outputDir);
|
||||
ApplyDrawingRules(outputDir);
|
||||
}
|
||||
}
|
||||
|
||||
void BuildIfNecessaryAndApply(QString const & mapcssFile)
|
||||
{
|
||||
if (!QFile(mapcssFile).exists())
|
||||
throw std::runtime_error("mapcss files does not exist");
|
||||
|
||||
QDir const projectDir = QFileInfo(mapcssFile).absoluteDir();
|
||||
QString const styleDir = projectDir.absolutePath() + QDir::separator();
|
||||
QString const outputDir = styleDir + "out" + QDir::separator();
|
||||
|
||||
if (QDir(outputDir).exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
ApplyDrawingRules(outputDir);
|
||||
ApplySkins(outputDir);
|
||||
}
|
||||
catch (std::exception const & ex)
|
||||
{
|
||||
BuildAndApply(mapcssFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildAndApply(mapcssFile);
|
||||
}
|
||||
}
|
||||
|
||||
void RunRecalculationGeometryScript(QString const & mapcssFile)
|
||||
{
|
||||
QString const resourceDir = GetPlatform().ResourcesDir().c_str();
|
||||
QString const writableDir = GetPlatform().WritableDir().c_str();
|
||||
|
||||
QString const generatorToolPath = GetGeometryToolPath();
|
||||
QString const appPath = QCoreApplication::applicationFilePath();
|
||||
|
||||
QString const geometryToolResourceDir = GetGeometryToolResourceDir();
|
||||
|
||||
CopyFromResources("drules_proto_design.bin", geometryToolResourceDir);
|
||||
CopyFromResources("classificator.txt", geometryToolResourceDir);
|
||||
CopyFromResources("types.txt", geometryToolResourceDir);
|
||||
|
||||
(void)ExecProcess("python", {
|
||||
GetRecalculateGeometryScriptPath(),
|
||||
resourceDir,
|
||||
writableDir,
|
||||
generatorToolPath,
|
||||
appPath,
|
||||
mapcssFile,
|
||||
});
|
||||
}
|
||||
|
||||
bool NeedRecalculate = false;
|
||||
} // namespace build_style
|
||||
12
qt/build_style/build_style.h
Normal file
12
qt/build_style/build_style.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
void BuildAndApply(QString const & mapcssFile);
|
||||
void BuildIfNecessaryAndApply(QString const & mapcssFile);
|
||||
void RunRecalculationGeometryScript(QString const & mapcssFile);
|
||||
|
||||
extern bool NeedRecalculate;
|
||||
} // namespace build_style
|
||||
22
qt/build_style/run_tests.cpp
Normal file
22
qt/build_style/run_tests.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "run_tests.h"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "build_common.h"
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
std::pair<bool, QString> RunCurrentStyleTests()
|
||||
{
|
||||
QString const program = GetExternalPath("style_tests", "style_tests.app/Contents/MacOS", "");
|
||||
QString const resourcesDir = QString::fromStdString(GetPlatform().ResourcesDir());
|
||||
QString const output = ExecProcess(program, {
|
||||
"--user_resource_path=" + resourcesDir,
|
||||
"--data_path=" + resourcesDir,
|
||||
});
|
||||
|
||||
// Unfortunately test process returns 0 even if some test failed,
|
||||
// therefore phrase 'All tests passed.' is looked to be sure that everything is OK.
|
||||
return std::make_pair(output.contains("All tests passed."), output);
|
||||
}
|
||||
} // namespace build_style
|
||||
10
qt/build_style/run_tests.h
Normal file
10
qt/build_style/run_tests.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace build_style
|
||||
{
|
||||
std::pair<bool, QString> RunCurrentStyleTests();
|
||||
} // namespace build_style
|
||||
Loading…
Add table
Add a link
Reference in a new issue