diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt index 30399a5868..38528d35b1 100644 --- a/qt/CMakeLists.txt +++ b/qt/CMakeLists.txt @@ -26,6 +26,8 @@ set( build_style/build_common.h build_style/build_drules.cpp build_style/build_drules.h + build_style/build_phone_pack.cpp + build_style/build_phone_pack.h build_style/build_skins.cpp build_style/build_skins.h build_style/build_statistics.cpp diff --git a/qt/build_style/build_common.cpp b/qt/build_style/build_common.cpp index aa90703927..9c563ca25f 100644 --- a/qt/build_style/build_common.cpp +++ b/qt/build_style/build_common.cpp @@ -34,3 +34,15 @@ bool CopyFile(QString const & oldFile, QString const & newFile) return false; return QFile::copy(oldFile, newFile); } + +QString JoinFoldersToPath(std::initializer_list const & folders) +{ + QString result; + for (auto it = folders.begin(); it != folders.end(); ++it) + { + if (it != folders.begin()) + result.append(QDir::separator()); + result.append(*it); + } + return QDir::cleanPath(result); +} diff --git a/qt/build_style/build_common.h b/qt/build_style/build_common.h index 3ee19b1967..55500c9af1 100644 --- a/qt/build_style/build_common.h +++ b/qt/build_style/build_common.h @@ -6,8 +6,12 @@ #include #include +#include + inline string to_string(const QString & qs) { return qs.toUtf8().constData(); } pair ExecProcess(QString const & cmd, QProcessEnvironment const * env = nullptr); bool CopyFile(QString const & oldFile, QString const & newFile); + +QString JoinFoldersToPath(std::initializer_list const & folders); diff --git a/qt/build_style/build_phone_pack.cpp b/qt/build_style/build_phone_pack.cpp new file mode 100644 index 0000000000..822ea80390 --- /dev/null +++ b/qt/build_style/build_phone_pack.cpp @@ -0,0 +1,50 @@ +#include "build_statistics.h" + +#include "build_common.h" + +#include "platform/platform.hpp" + +#include +#include + +#include + +namespace +{ +QString GetScriptPath() +{ + QString const kScriptName = "generate_styles_override.py"; + QString const resourceDir = GetPlatform().ResourcesDir().c_str(); + if (resourceDir.isEmpty()) + return kScriptName; + return JoinFoldersToPath({resourceDir, kScriptName}); +} +} // namespace + +namespace build_style +{ +QString RunBuildingPhonePack(QString const & stylesFolder, QString const & targetFolder) +{ + if (!QDir(stylesFolder).exists()) + throw std::runtime_error("styles folder does not exist"); + + if (!QDir(targetFolder).exists()) + throw std::runtime_error("target folder does not exist"); + + QStringList params; + params << "python" << + '"' + GetScriptPath() + '"' << + '"' + stylesFolder + '"' << + '"' + targetFolder + '"'; + QString const cmd = params.join(' '); + auto const res = ExecProcess(cmd); + if (res.first != 0) + { + QString msg = QString("System error ") + to_string(res.first).c_str(); + if (!res.second.isEmpty()) + msg = msg + "\n" + res.second; + throw std::runtime_error(to_string(msg)); + } + return res.second; +} +} // namespace build_style diff --git a/qt/build_style/build_phone_pack.h b/qt/build_style/build_phone_pack.h new file mode 100644 index 0000000000..fcc055819f --- /dev/null +++ b/qt/build_style/build_phone_pack.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace build_style +{ + +QString RunBuildingPhonePack(QString const & stylesFolder, QString const & targetFolder); + +} // namespace build_style diff --git a/qt/mainwindow.cpp b/qt/mainwindow.cpp index ae8dd98583..3a66c20d36 100644 --- a/qt/mainwindow.cpp +++ b/qt/mainwindow.cpp @@ -21,9 +21,13 @@ #include "std/target_os.hpp" +#ifdef BUILD_DESIGNER +#include "build_style/build_common.h" +#include "build_style/build_phone_pack.h" #include "build_style/build_style.h" #include "build_style/build_statistics.h" #include "build_style/run_tests.h" +#endif // BUILD_DESIGNER #include #include @@ -124,6 +128,7 @@ MainWindow::MainWindow(Framework & framework, bool apiOpenGLES3, QString const & , m_pDrawDebugRectAction(nullptr) , m_pGetStatisticsAction(nullptr) , m_pRunTestsAction(nullptr) + , m_pBuildPhonePackAction(nullptr) #endif { // Always runs on the first desktop @@ -463,15 +468,14 @@ void MainWindow::CreateNavigationBar() m_pRunTestsAction->setCheckable(false); m_pRunTestsAction->setToolTip(tr("Run tests")); + // Add "Build phone package" button + m_pBuildPhonePackAction = pToolBar->addAction(QIcon(":/navig64/phonepack.png"), + tr("Build phone package"), + this, + SLOT(OnBuildPhonePackage())); + m_pBuildPhonePackAction->setCheckable(false); + m_pBuildPhonePackAction->setToolTip(tr("Build phone package")); #endif // BUILD_DESIGNER - - // add view actions 1 - button_t arr[] = { - { QString(), 0, 0 }, - //{ tr("Show all"), ":/navig64/world.png", SLOT(ShowAll()) }, - { tr("Scale +"), ":/navig64/plus.png", SLOT(ScalePlus()) } - }; - add_buttons(pToolBar, arr, ARRAY_SIZE(arr), m_pDrawWidget); } qt::common::ScaleSlider::Embed(Qt::Vertical, *pToolBar, *m_pDrawWidget); @@ -766,6 +770,51 @@ void MainWindow::OnRunTests() msgBox.exec(); } } + +void MainWindow::OnBuildPhonePackage() +{ + try + { + char const * const kStylesFolder = "styles"; + char const * const kClearStyleFolder = "clear"; + + QString const targetDir = QFileDialog::getExistingDirectory(nullptr, "Choose output directory"); + if (targetDir.isEmpty()) + return; + auto outDir = QDir(JoinFoldersToPath({targetDir, kStylesFolder})); + if (outDir.exists()) + { + QMessageBox msgBox; + msgBox.setWindowTitle("Warning"); + msgBox.setText(QString("Folder ") + outDir.absolutePath() + " will be deleted?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::No); + auto result = msgBox.exec(); + if (result == QMessageBox::No) + throw std::runtime_error(std::string("Target directory exists: ") + outDir.absolutePath().toStdString()); + } + + QString const stylesDir = JoinFoldersToPath({m_mapcssFilePath, "..", "..", ".."}); + if (!QDir(JoinFoldersToPath({stylesDir, kClearStyleFolder})).exists()) + throw std::runtime_error(std::string("Styles folder is not found in ") + stylesDir.toStdString()); + + QString text = build_style::RunBuildingPhonePack(stylesDir, targetDir); + text.append("\nMobile device style package is in the directory: "); + text.append(JoinFoldersToPath({targetDir, kStylesFolder})); + text.append(". Copy it to your mobile device.\n"); + InfoDialog dlg(QString("Building phone pack"), text, nullptr); + dlg.exec(); + } + catch (std::exception & e) + { + QMessageBox msgBox; + msgBox.setWindowTitle("Error"); + msgBox.setText(e.what()); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.exec(); + } +} #endif // BUILD_DESIGNER #ifndef NO_DOWNLOADER diff --git a/qt/mainwindow.hpp b/qt/mainwindow.hpp index f9a30eec70..f4ae03d9c8 100644 --- a/qt/mainwindow.hpp +++ b/qt/mainwindow.hpp @@ -45,6 +45,7 @@ class MainWindow : public QMainWindow, location::LocationObserver QAction * m_pDrawDebugRectAction; QAction * m_pGetStatisticsAction; QAction * m_pRunTestsAction; + QAction * m_pBuildPhonePackAction; #endif // BUILD_DESIGNER DrawWidget * m_pDrawWidget; @@ -130,6 +131,7 @@ protected Q_SLOTS: void OnDebugStyle(); void OnGetStatistics(); void OnRunTests(); + void OnBuildPhonePackage(); #endif // BUILD_DESIGNER }; } diff --git a/qt/qt.pro b/qt/qt.pro index 1e02d5fed3..a6fd1b59ea 100644 --- a/qt/qt.pro +++ b/qt/qt.pro @@ -122,6 +122,7 @@ map_designer { SOURCES += \ build_style/build_common.cpp \ build_style/build_drules.cpp \ + build_style/build_phone_pack.cpp \ build_style/build_skins.cpp \ build_style/build_style.cpp \ build_style/build_statistics.cpp \ @@ -130,6 +131,7 @@ SOURCES += \ HEADERS += \ build_style/build_common.h \ build_style/build_drules.h \ + build_style/build_phone_pack.h \ build_style/build_skins.h \ build_style/build_style.h \ build_style/build_statistics.h \ diff --git a/qt/res/phonepack.png b/qt/res/phonepack.png new file mode 100644 index 0000000000..3465d05525 Binary files /dev/null and b/qt/res/phonepack.png differ diff --git a/qt/res/resources.qrc b/qt/res/resources.qrc index 0bc39f9c81..10401a8944 100644 --- a/qt/res/resources.qrc +++ b/qt/res/resources.qrc @@ -23,6 +23,7 @@ chart.png test.png geom.png + phonepack.png logo.png diff --git a/tools/unix/build_designer.sh b/tools/unix/build_designer.sh index 164269d43b..adc80be595 100755 --- a/tools/unix/build_designer.sh +++ b/tools/unix/build_designer.sh @@ -40,6 +40,7 @@ cp -r "$OMIM_PATH/tools/kothic" "$MAC_RESOURCES/kothic" cp "$OMIM_PATH/tools/python/stylesheet/drules_info.py" "$MAC_RESOURCES/kothic/src/drules_info.py" cp "$OMIM_PATH/protobuf/protobuf-2.6.1-py2.7.egg" "$MAC_RESOURCES/kothic" cp "$OMIM_PATH/tools/python/recalculate_geom_index.py" "$MAC_RESOURCES/recalculate_geom_index.py" +cp "$OMIM_PATH/tools/python/generate_styles_override.py" "$MAC_RESOURCES/generate_styles_override.py" # Copy all drules and resources (required for test environment) rm -rf $MAC_RESOURCES/drules_proto*