From d7eb44f0851b17a2ea0e09be09de3067a0fc9420 Mon Sep 17 00:00:00 2001 From: Zira project Date: Tue, 22 Sep 2020 15:46:59 +0500 Subject: [PATCH] android, php, git improvements, fixes --- .gitignore | 2 + bin/themes/Intellij Dark/icons/home.png | Bin 0 -> 326 bytes bin/themes/Intellij Dark/theme.css | 3 +- bin/themes/Studio Light/icons/home.png | Bin 0 -> 365 bytes bin/themes/Studio Light/theme.css | 3 +- include/filebrowser.h | 1 + include/git.h | 5 + include/helper.h | 1 + include/mainwindow.h | 12 + include/parserworker.h | 21 ++ qrc/image.qrc | 1 + qrc/resources/images/icons/home.png | Bin 0 -> 377 bytes qrc/resources/styles/dark/icons/home.png | Bin 0 -> 326 bytes qrc/resources/styles/dark/style | 3 +- qrc/resources/styles/light/icons/home.png | Bin 0 -> 365 bytes qrc/resources/styles/light/style | 3 +- qrc/style.qrc | 2 + src/filebrowser.cpp | 11 + src/git.cpp | 21 ++ src/helper.cpp | 1 + src/mainwindow.cpp | 105 +++++- src/parserworker.cpp | 378 ++++++++++++++++++---- src/settings.cpp | 3 +- ui/mainwindow.ui | 52 +++ 24 files changed, 550 insertions(+), 78 deletions(-) create mode 100644 bin/themes/Intellij Dark/icons/home.png create mode 100644 bin/themes/Studio Light/icons/home.png create mode 100644 qrc/resources/images/icons/home.png create mode 100644 qrc/resources/styles/dark/icons/home.png create mode 100644 qrc/resources/styles/light/icons/home.png diff --git a/.gitignore b/.gitignore index 2c47b8c..4db5df3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ ZiraEditor.pro.user +android/Qt5_12/assets/ +android/Qt5_14/assets/ diff --git a/bin/themes/Intellij Dark/icons/home.png b/bin/themes/Intellij Dark/icons/home.png new file mode 100644 index 0000000000000000000000000000000000000000..ce47184dff6cac3be7c4328d3a364ff612417229 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHi2)7?%L|%O}@4fkKx(T^vIyZoR$X$#+;mfHiPK(FdK{ z*XOiWYseXViTKac7X|Zlc3Kp6oXCG!ZEK!*<>Jpt%UTXdB(tyY`WSfh#uS3l2XI* z(5|2)I5z%%?DrCG1EKjcj*`dJT?3YVJSi}xutta_Rc^m^6VH+NT?)z{cPpL<_@l>R zB(~qOiRV~;m%`$YvlUMi{88gDlG`uk$oD8*@r37}Bo@oA_!foqkDCRb7}SY1%{k`p zHsSFPPmUtF|Kg6UNBWgkO!zUMLrbGh;Ng}Bl5cdc?z>gC<)aLjJkV1>p!$B&?cH;J n?QhnG@R7*m9>Zf1j=vdxPnrDkm +#include #include "settings.h" #include "parsephp.h" #include "parsejs.h" #include "parsecss.h" #include "types.h" +extern const QString PHP_WEBSERVER_URI; + class ParserWorker : public QObject { Q_OBJECT public: explicit ParserWorker(Settings * settings, QObject *parent = nullptr); + ~ParserWorker(); protected: void parseProjectDir(QString dir, QStringList & files); void parseProjectFile(QString file, QVariantMap & map); @@ -26,6 +30,13 @@ protected: void searchInFile(QString file, QString searchText, bool searchOptionCase, bool searchOptionWord, bool searchOptionRegexp); void searchInFilesResultFound(QString file, QString lineText, int line, int symbol); void quickFindInDir(QString startDir, QString dir, QString text); + bool createAndroidDirectory(QDir rootDir, QString path); + bool setAndroidFilePermissions(QFile &f); + bool setAndroidFilePermissions(QString path); + bool installAndroidFile(QString fileName, QString installDir); + bool installAndroidPackFiles(); + bool isAndroidPackInstalled(); + void setAndroidBinPaths(); private: QString phpPath; QString gitPath; @@ -44,9 +55,15 @@ private: int quickResultsCount; bool quickBreaked; bool wantStop; + QString androidHomePath; + QStringList androidBinFiles; + QStringList androidGitFiles; + QStringList androidOtherFiles; + qint64 phpWebServerPid; signals: void lintFinished(int tabIndex, QStringList errorTexts, QStringList errorLines, QString output); void execPHPFinished(int tabIndex, QString output); + void execPHPWebServerFinished(bool success, QString output); void phpcsFinished(int tabIndex, QStringList errorTexts, QStringList errorLines); void parseMixedFinished(int tabIndex, ParsePHP::ParseResult result); void parseJSFinished(int tabIndex, ParseJS::ParseResult result); @@ -65,11 +82,14 @@ signals: void activateProgressInfo(QString text); void deactivateProgressInfo(); void updateProgressInfo(QString text); + void installAndroidPackFinished(QString result); public slots: void disable(); void lint(int tabIndex, QString path); void execPHP(int tabIndex, QString path); void execSelection(int tabIndex, QString text); + void startPHPWebServer(QString path); + void stopPHPWebServer(); void phpcs(int tabIndex, QString path); void parseMixed(int tabIndex, QString text); void parseJS(int tabIndex, QString text); @@ -81,6 +101,7 @@ public slots: void sassCommand(QString src, QString dst); void quickFind(QString dir, QString text, WordsMapList words, QStringList wordPrefixes); void cancelRequested(); + void installAndroidPack(); }; #endif // PARSERWORKER_H diff --git a/qrc/image.qrc b/qrc/image.qrc index 7afb830..264a186 100644 --- a/qrc/image.qrc +++ b/qrc/image.qrc @@ -57,5 +57,6 @@ resources/images/icons/edit-paste.png resources/images/icons/branch-close.png resources/images/icons/branch-open.png + resources/images/icons/home.png diff --git a/qrc/resources/images/icons/home.png b/qrc/resources/images/icons/home.png new file mode 100644 index 0000000000000000000000000000000000000000..6d65cec4ed7c1707f5c730c27a3684ef81a55e89 GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHi2)7#E*fMb(zY3=E8Ho-U3d6}R4A+sk{%K*aSSyLi_b z=hG~2CQg!Eu*CnQg2|Z!Rwf<+ih&L%=F8guzQelav*)zjV-m^6>sQTA4mDqHc`l6W zV_KQP=C@UwSIccby;Y*2|Ht=5${GuQL<&ras3~Dlm5>*8>^$b~9B}Akpum)hngSNf z4*o6$^^XSyo@m%{G|f5c->1<2akA2h%s(j{MKboBO>>U-y9Ka)Tr4of^G^axs)#*@ ziXZcLE;0Co$b|o=YL;2 zwp7#(=w~4Cx~H|Z-16K0W^D)`iA?S>JQm?t%{cMi+MgFS#6dyI;OXk;vd$@?2>@<{ BiO2u| literal 0 HcmV?d00001 diff --git a/qrc/resources/styles/dark/icons/home.png b/qrc/resources/styles/dark/icons/home.png new file mode 100644 index 0000000000000000000000000000000000000000..ce47184dff6cac3be7c4328d3a364ff612417229 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHi2)7?%L|%O}@4fkKx(T^vIyZoR$X$#+;mfHiPK(FdK{ z*XOiWYseXViTKac7X|Zlc3Kp6oXCG!ZEK!*<>Jpt%UTXdB(tyY`WSfh#uS3l2XI* z(5|2)I5z%%?DrCG1EKjcj*`dJT?3YVJSi}xutta_Rc^m^6VH+NT?)z{cPpL<_@l>R zB(~qOiRV~;m%`$YvlUMi{88gDlG`uk$oD8*@r37}Bo@oA_!foqkDCRb7}SY1%{k`p zHsSFPPmUtF|Kg6UNBWgkO!zUMLrbGh;Ng}Bl5cdc?z>gC<)aLjJkV1>p!$B&?cH;J n?QhnG@R7*m9>Zf1j=vdxPnrDkmresources/styles/dark/icons/clear.png resources/styles/dark/icons/separator.png resources/styles/dark/icons/close.png + resources/styles/dark/icons/home.png resources/styles/light/icons/actionOpenFile.png @@ -146,5 +147,6 @@ resources/styles/light/icons/clear.png resources/styles/light/icons/separator.png resources/styles/light/icons/close.png + resources/styles/light/icons/home.png diff --git a/src/filebrowser.cpp b/src/filebrowser.cpp index 8de690c..890d4d4 100644 --- a/src/filebrowser.cpp +++ b/src/filebrowser.cpp @@ -61,6 +61,8 @@ void FileBrowser::initFileBrowser(QString homeDir) if (homeDir.size()==0) homeDir = "."; QAction * upAction = pathLine->addAction(Icon::get("up", QIcon(":icons/levelup.png")), QLineEdit::TrailingPosition); connect(upAction, SIGNAL(triggered(bool)), this, SLOT(upActionTriggered(bool))); + QAction * homeAction = pathLine->addAction(Icon::get("home", QIcon(":icons/home.png")), QLineEdit::LeadingPosition); + connect(homeAction, SIGNAL(triggered(bool)), this, SLOT(homeActionTriggered(bool))); buildFileBrowserTree(homeDir); connect(treeWidget, SIGNAL(itemExpanded(QTreeWidgetItem*)), this, SLOT(fileBrowserExpanded(QTreeWidgetItem*))); connect(treeWidget, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(fileBrowserCollapsed(QTreeWidgetItem*))); @@ -202,6 +204,15 @@ void FileBrowser::upActionTriggered(bool) } } +void FileBrowser::homeActionTriggered(bool) +{ + QStringList stddirs = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); + if (stddirs.size()>0) { + pathLine->setText(stddirs.at(0)); + fileBrowserPathReturnPressed(); + } +} + void FileBrowser::fileBrowserContextMenuRequested(QPoint /*p*/) { //QTreeWidgetItem * item = treeWidget->itemAt(p); diff --git a/src/git.cpp b/src/git.cpp index be05e7c..808d212 100644 --- a/src/git.cpp +++ b/src/git.cpp @@ -16,6 +16,7 @@ const QString GIT_DIFF_COMMAND = "diff"; const QString GIT_COMMIT_COMMAND = "commit"; const QString GIT_PUSH_COMMAND = "push"; const QString GIT_PULL_COMMAND = "pull"; +const QString GIT_CLONE_COMMAND = "clone"; Git::Git(Settings * settings, QObject *parent) : QObject(parent) { @@ -138,6 +139,26 @@ void Git::pullOriginMaster(QString path) emit runGitCommand(path, "pull", QStringList() << "origin" << "master"); } +void Git::initialize(QString path) +{ + emit runGitCommand(path, "init", QStringList()); +} + +void Git::addRemoteURL(QString path, QString url) +{ + emit runGitCommand(path, "remote", QStringList() << "add" << "origin" << url); +} + +void Git::changeRemoteURL(QString path, QString url) +{ + emit runGitCommand(path, "remote", QStringList() << "set-url" << "origin" << url); +} + +void Git::clone(QString path, QString url) +{ + emit runGitCommand(path, "clone", QStringList() << url); +} + void Git::showAnnotation(QString path, QString fileName, bool outputResult, bool silent) { emit runGitCommand(path, "blame", QStringList() << "--line-porcelain" << fileName, outputResult, silent); diff --git a/src/helper.cpp b/src/helper.cpp index fb76e1b..58e9ee5 100644 --- a/src/helper.cpp +++ b/src/helper.cpp @@ -36,6 +36,7 @@ const QString AUTHOR_EMAIL_DOMAIN = "gmail.com"; const QString AUTHOR_CARD_URL = "https://money.yandex.ru/to"; const QString AUTHOR_CARD_ID = "410014796567498"; const QString AUTHOR_CMS_URL = "https://github.com/ziracms/zira"; +const QString AUTHOR_DEVPACK_URL = "https://github.com/ziracms/devpack"; const QString GITHUB_EDITOR_URL = "https://github.com/ziracms/editor"; const QString STYLE_PLUGIN_SUFFIX = "Style"; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4f30d82..4607028 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -328,6 +328,8 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, SIGNAL(parseLint(int,QString)), parserWorker, SLOT(lint(int,QString))); connect(this, SIGNAL(execPHP(int,QString)), parserWorker, SLOT(execPHP(int,QString))); connect(this, SIGNAL(execSelection(int,QString)), parserWorker, SLOT(execSelection(int,QString))); + connect(this, SIGNAL(startPHPWebServer(QString)), parserWorker, SLOT(startPHPWebServer(QString))); + connect(this, SIGNAL(stopPHPWebServer()), parserWorker, SLOT(stopPHPWebServer())); connect(this, SIGNAL(parsePHPCS(int,QString)), parserWorker, SLOT(phpcs(int,QString))); connect(this, SIGNAL(parseMixed(int,QString)), parserWorker, SLOT(parseMixed(int,QString))); connect(this, SIGNAL(parseJS(int,QString)), parserWorker, SLOT(parseJS(int,QString))); @@ -338,9 +340,11 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, SIGNAL(serversCommand(QString, QString)), parserWorker, SLOT(serversCommand(QString,QString))); connect(this, SIGNAL(sassCommand(QString, QString)), parserWorker, SLOT(sassCommand(QString,QString))); connect(this, SIGNAL(quickFind(QString, QString, WordsMapList, QStringList)), parserWorker, SLOT(quickFind(QString, QString, WordsMapList, QStringList))); + connect(this, SIGNAL(installAndroidPack()), parserWorker, SLOT(installAndroidPack())); connect(progressInfo, SIGNAL(cancelTriggered()), parserWorker, SLOT(cancelRequested())); connect(parserWorker, SIGNAL(lintFinished(int,QStringList,QStringList,QString)), this, SLOT(parseLintFinished(int,QStringList,QStringList,QString))); connect(parserWorker, SIGNAL(execPHPFinished(int,QString)), this, SLOT(execPHPFinished(int,QString))); + connect(parserWorker, SIGNAL(execPHPWebServerFinished(bool,QString)), this, SLOT(execPHPWebServerFinished(bool,QString))); connect(parserWorker, SIGNAL(phpcsFinished(int,QStringList,QStringList)), this, SLOT(parsePHPCSFinished(int,QStringList,QStringList))); connect(parserWorker, SIGNAL(parseMixedFinished(int,ParsePHP::ParseResult)), this, SLOT(parseMixedFinished(int,ParsePHP::ParseResult))); connect(parserWorker, SIGNAL(parseJSFinished(int,ParseJS::ParseResult)), this, SLOT(parseJSFinished(int,ParseJS::ParseResult))); @@ -359,6 +363,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(parserWorker, SIGNAL(activateProgressInfo(QString)), this, SLOT(activateProgressInfo(QString))); connect(parserWorker, SIGNAL(deactivateProgressInfo()), this, SLOT(deactivateProgressInfo())); connect(parserWorker, SIGNAL(updateProgressInfo(QString)), this, SLOT(updateProgressInfo(QString))); + connect(parserWorker, SIGNAL(installAndroidPackFinished(QString)), this, SLOT(installAndroidPackFinished(QString))); parserThread.start(); tmpDisableParser = false; @@ -692,6 +697,11 @@ void MainWindow::closeEvent(QCloseEvent *event) emit disableWorker(); // save project project->save(editorTabs->getOpenTabFiles(), editorTabs->getOpenTabLines(), editorTabs->getCurrentTabIndex(), ui->todoEdit->toPlainText()); + if (settings->get("devpack_install_silent") == "no") { + std::unordered_map sMap; + sMap["devpack_install_silent"] = "yes"; + settings->change(sMap); + } settings->save(); // save wnd geometry & state QSettings windowSettings; @@ -754,13 +764,17 @@ void MainWindow::menuToolsOnShow() { bool sassEnabled = false; bool execEnabled = false; + bool execSelectionEnabled = false; Editor * textEditor = getActiveEditor(); - if (textEditor != nullptr && !textEditor->isModified()) { + if (textEditor != nullptr) { QString ext = textEditor->getFileExtension().toLower(); - if (ext == "scss" || ext == "sass") { + if (!textEditor->isModified() && (ext == "scss" || ext == "sass")) { sassEnabled = true; } else if (ext == "php") { - execEnabled = true; + if (!textEditor->isModified()) execEnabled = true; + if (textEditor->textCursor().selectedText().size() > 0) { + execSelectionEnabled = true; + } } } QList toolsActions = ui->menuTools->actions(); @@ -770,10 +784,7 @@ void MainWindow::menuToolsOnShow() } else if (action->objectName() == "actionExecuteFile") { action->setEnabled(execEnabled); } else if (action->objectName() == "actionExecuteSelection") { - if (execEnabled && textEditor->textCursor().selectedText().size() == 0) { - execEnabled = false; - } - action->setEnabled(execEnabled); + action->setEnabled(execSelectionEnabled); } } } @@ -946,6 +957,9 @@ void MainWindow::enableActionsForOpenProject() void MainWindow::projectLoadOnStart() { showWelcomeScreen(); + #if defined(Q_OS_ANDROID) + emit installAndroidPack(); + #endif QSettings windowSettings; QString projectPath = windowSettings.value("project_path").toString(); if (projectPath.size() > 0 && Helper::folderExists(projectPath) && project->exists(projectPath)) { @@ -954,6 +968,9 @@ void MainWindow::projectLoadOnStart() } void MainWindow::openFromArgs() { + #if defined(Q_OS_ANDROID) + emit installAndroidPack(); + #endif if (args.length() <= 1) return; QStringList files; for (int i=1; ioutputDockWidget->isVisible()) ui->outputDockWidget->show(); ui->outputTabWidget->setCurrentIndex(OUTPUT_TAB_RESULTS_INDEX); ui->outputEdit->clear(); - QString cmdStr = "php -n -d max_execution_time=30 -f "+fileName; + QString cmdStr = "php -d max_execution_time=30 -f "+fileName; ui->outputEdit->setHtml(Servers::highlightServersCommand(cmdStr, settings)); emit execPHP(textEditor->getTabIndex(), fileName); @@ -1434,12 +1451,34 @@ void MainWindow::on_actionExecuteSelection_triggered() if (!ui->outputDockWidget->isVisible()) ui->outputDockWidget->show(); ui->outputTabWidget->setCurrentIndex(OUTPUT_TAB_RESULTS_INDEX); ui->outputEdit->clear(); - QString cmdStr = "php -n -d max_execution_time=30 -r '"+text+"'"; + QString cmdStr = "php -d max_execution_time=30 -r '"+text+"'"; ui->outputEdit->setHtml(Servers::highlightServersCommand(cmdStr, settings)); emit execSelection(textEditor->getTabIndex(), code); } +void MainWindow::on_actionStartPHPWebServer_triggered() +{ + emit startPHPWebServer(filebrowser->getRootPath()); +} + +void MainWindow::on_actionStopPHPWebServer_triggered() +{ + emit stopPHPWebServer(); +} + +void MainWindow::execPHPWebServerFinished(bool success, QString output) +{ + hideQAPanel(); + if (!ui->outputDockWidget->isVisible()) ui->outputDockWidget->show(); + ui->outputTabWidget->setCurrentIndex(OUTPUT_TAB_RESULTS_INDEX); + ui->outputEdit->clear(); + ui->outputEdit->setHtml(Servers::highlightServersCommand(output, settings)); + if (success) { + QDesktopServices::openUrl(QUrl("http://" + PHP_WEBSERVER_URI)); + } +} + void MainWindow::execPHPFinished(int tabIndex, QString output) { Editor * textEditor = getActiveEditor(); @@ -1569,6 +1608,35 @@ void MainWindow::on_actionGitPull_triggered() git->pullOriginMaster(getGitWorkingDir()); } +void MainWindow::on_actionGitInitializeRepository_triggered() +{ + git->initialize(getGitWorkingDir()); +} + +void MainWindow::on_actionGitAddRemoteURL_triggered() +{ + bool ok; + QString url = QInputDialog::getText(this, tr("Enter URL"), tr("Enter remote URL.\nNote: you might want to add a username and password to repository URI\n(https://username:password@github.com/username/repository.git)"), QLineEdit::Normal, "", &ok); + if (!ok || url.size() == 0) return; + git->addRemoteURL(getGitWorkingDir(), url); +} + +void MainWindow::on_actionGitChangeRemoteURL_triggered() +{ + bool ok; + QString url = QInputDialog::getText(this, tr("Enter URL"), tr("Enter remote URL.\nNote: you might want to add a username and password to repository URI\n(https://username:password@github.com/username/repository.git)"), QLineEdit::Normal, "", &ok); + if (!ok || url.size() == 0) return; + git->changeRemoteURL(getGitWorkingDir(), url); +} + +void MainWindow::on_actionGitCloneRepository_triggered() +{ + bool ok; + QString url = QInputDialog::getText(this, tr("Enter URL"), tr("Enter repository URL.\nNote: you might want to add a username and password to repository URI\n(https://username:password@github.com/username/repository.git)"), QLineEdit::Normal, "", &ok); + if (!ok || url.size() == 0) return; + git->clone(getGitWorkingDir(), url); +} + void MainWindow::runGitCommand(QString path, QString command, QStringList attrs, bool outputResult, bool silent) { if (!gitCommandsEnabled) return; @@ -1638,6 +1706,8 @@ void MainWindow::gitCommandFinished(QString command, QString output, bool output gitAnnotationRequested(textEditor->getFileName()); gitDiffUnifiedRequested(textEditor->getFileName()); } + } else if (command == GIT_PULL_COMMAND || command == GIT_CLONE_COMMAND) { + filebrowser->refreshFileBrowserDirectory(filebrowser->getRootPath()); } } @@ -1684,6 +1754,18 @@ void MainWindow::gitDiffUnifiedRequested(QString path) git->showUncommittedDiffCurrentUnified(getGitWorkingDir(), path, false, true); } +void MainWindow::installAndroidPackFinished(QString result) +{ + if (settings->get("devpack_install_silent") == "yes") return; + hideQAPanel(); + if (result.size() > 0) { + if (!ui->outputDockWidget->isVisible()) ui->outputDockWidget->show(); + ui->outputTabWidget->setCurrentIndex(OUTPUT_TAB_RESULTS_INDEX); + ui->outputEdit->clear(); + ui->outputEdit->setHtml(result); + } +} + void MainWindow::on_actionSettings_triggered() { SettingsDialog dialog(settings, this); @@ -1729,6 +1811,11 @@ void MainWindow::on_actionHelpZiraCMS_triggered() QDesktopServices::openUrl(QUrl(AUTHOR_CMS_URL)); } +void MainWindow::on_actionHelpZiraDevPack_triggered() +{ + QDesktopServices::openUrl(QUrl(AUTHOR_DEVPACK_URL)); +} + void MainWindow::resetLastSearchParams() { lastSearchText = ""; diff --git a/src/parserworker.cpp b/src/parserworker.cpp index 841df9a..f79e2b7 100644 --- a/src/parserworker.cpp +++ b/src/parserworker.cpp @@ -10,78 +10,27 @@ #include #include #include +#include #include "helper.h" #include "project.h" #include "servers.h" #include "git.h" +const QString ANDROID_PACK_SUBDIR = "packages"; +const QString ANDROID_BIN_DIR = "bin"; +const QString ANDROID_GIT_CORE_DIR = "git-core"; +const QString ANDROID_GIT_TEMPLATES_DIR = "templates"; +const QString ANDROID_PHP_TMP_DIR = "tmp"; +const QString ANDROID_INSTALL_RESULT_LINE_TEMPLATE = "

%1

"; +const QString PHP_WEBSERVER_URI = "127.0.0.1:8000"; + ParserWorker::ParserWorker(Settings * settings, QObject *parent) : QObject(parent) -{ - // php path +{ phpPath = ""; - QString phpPathStr = QString::fromStdString(settings->get("parser_php_path")); - if (phpPathStr.size() == 0) { - QProcess process(this); - process.start("which", QStringList() << "php"); - if (!process.waitForFinished()) return; - QByteArray result = process.readAllStandardOutput(); - phpPathStr = QString(result).trimmed(); - } - if (phpPathStr.size() > 0 && Helper::fileOrFolderExists(phpPathStr)) { - phpPath = phpPathStr; - } - // git path gitPath = ""; - QString gitPathStr = QString::fromStdString(settings->get("parser_git_path")); - if (gitPathStr.size() == 0) { - QProcess process(this); - process.start("which", QStringList() << "git"); - if (!process.waitForFinished()) return; - QByteArray result = process.readAllStandardOutput(); - gitPathStr = QString(result).trimmed(); - } - if (gitPathStr.size() > 0 && Helper::fileOrFolderExists(gitPathStr)) { - gitPath = gitPathStr; - } - // bash path bashPath = ""; - QString bashPathStr = QString::fromStdString(settings->get("parser_bash_path")); - if (bashPathStr.size() == 0) { - QProcess process(this); - process.start("which", QStringList() << "bash"); - if (!process.waitForFinished()) return; - QByteArray result = process.readAllStandardOutput(); - bashPathStr = QString(result).trimmed(); - } - if (bashPathStr.size() > 0 && Helper::fileOrFolderExists(bashPathStr)) { - bashPath = bashPathStr; - } - // sassc path sasscPath = ""; - QString sasscPathStr = QString::fromStdString(settings->get("parser_sassc_path")); - if (sasscPathStr.size() == 0) { - QProcess process(this); - process.start("which", QStringList() << "sassc"); - if (!process.waitForFinished()) return; - QByteArray result = process.readAllStandardOutput(); - sasscPathStr = QString(result).trimmed(); - } - if (sasscPathStr.size() > 0 && Helper::fileOrFolderExists(sasscPathStr)) { - sasscPath = sasscPathStr; - } - // phpcs path phpcsPath = ""; - QString phpcsPathStr = QString::fromStdString(settings->get("parser_phpcs_path")); - if (phpcsPathStr.size() == 0) { - QProcess process(this); - process.start("which", QStringList() << "phpcs"); - if (!process.waitForFinished()) return; - QByteArray result = process.readAllStandardOutput(); - phpcsPathStr = QString(result).trimmed(); - } - if (phpcsPathStr.size() > 0 && Helper::fileOrFolderExists(phpcsPathStr)) { - phpcsPath = phpcsPathStr; - } phpcsStandard = QString::fromStdString(settings->get("parser_phpcs_standard")); if (phpcsStandard.size() == 0) phpcsStandard = "PEAR"; phpcsErrorSeverity = std::stoi(settings->get("parser_phpcs_error_severity")); @@ -97,6 +46,95 @@ ParserWorker::ParserWorker(Settings * settings, QObject *parent) : QObject(paren quickResultsCount = 0; quickBreaked = false; wantStop = false; + phpWebServerPid = 0; + + // android pack + androidHomePath=""; + androidBinFiles << "php" << "git" << "git-receive-pack" << "git-upload-archive" << "git-upload-pack" << "sassc" << "termux-elf-cleaner"; + androidGitFiles << "git" << "git-remote" << "git-remote-http" << "git-remote-https" << "git-receive-pack" << "git-upload-archive" << "git-upload-pack"; + androidOtherFiles << "php.ini" << "gitconfig" << "cacert.pem"; + #if defined(Q_OS_ANDROID) + QStringList stddirs = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); + if (stddirs.size()>0) androidHomePath = stddirs.at(0); + #endif + + // php path + QString phpPathStr = QString::fromStdString(settings->get("parser_php_path")); + if (phpPathStr.size() == 0) { + QProcess process(this); + process.start("which", QStringList() << "php"); + if (process.waitForFinished()) { + QByteArray result = process.readAllStandardOutput(); + phpPathStr = QString(result).trimmed(); + } + } + if (phpPathStr.size() > 0 && Helper::fileOrFolderExists(phpPathStr)) { + phpPath = phpPathStr; + } + + // git path + QString gitPathStr = QString::fromStdString(settings->get("parser_git_path")); + if (gitPathStr.size() == 0) { + QProcess process(this); + process.start("which", QStringList() << "git"); + if (process.waitForFinished()) { + QByteArray result = process.readAllStandardOutput(); + gitPathStr = QString(result).trimmed(); + } + } + if (gitPathStr.size() > 0 && Helper::fileOrFolderExists(gitPathStr)) { + gitPath = gitPathStr; + } + + // bash path + QString bashPathStr = QString::fromStdString(settings->get("parser_bash_path")); + if (bashPathStr.size() == 0) { + QProcess process(this); + process.start("which", QStringList() << "bash"); + if (process.waitForFinished()) { + QByteArray result = process.readAllStandardOutput(); + bashPathStr = QString(result).trimmed(); + } + } + if (bashPathStr.size() > 0 && Helper::fileOrFolderExists(bashPathStr)) { + bashPath = bashPathStr; + } + + // sassc path + QString sasscPathStr = QString::fromStdString(settings->get("parser_sassc_path")); + if (sasscPathStr.size() == 0) { + QProcess process(this); + process.start("which", QStringList() << "sassc"); + if (process.waitForFinished()) { + QByteArray result = process.readAllStandardOutput(); + sasscPathStr = QString(result).trimmed(); + } + } + if (sasscPathStr.size() > 0 && Helper::fileOrFolderExists(sasscPathStr)) { + sasscPath = sasscPathStr; + } + + // phpcs path + QString phpcsPathStr = QString::fromStdString(settings->get("parser_phpcs_path")); + if (phpcsPathStr.size() == 0) { + QProcess process(this); + process.start("which", QStringList() << "phpcs"); + if (process.waitForFinished()) { + QByteArray result = process.readAllStandardOutput(); + phpcsPathStr = QString(result).trimmed(); + } + } + if (phpcsPathStr.size() > 0 && Helper::fileOrFolderExists(phpcsPathStr)) { + phpcsPath = phpcsPathStr; + } +} + +ParserWorker::~ParserWorker() +{ + disable(); + if (phpWebServerPid != 0) { + stopPHPWebServer(); + } } void ParserWorker::disable() @@ -137,7 +175,7 @@ void ParserWorker::execPHP(int tabIndex, QString path) return; } QProcess process(this); - process.start(phpPath, QStringList() << "-n" << "-d" << "max_execution_time=30" << "-f" << path); + process.start(phpPath, QStringList() << "-d" << "max_execution_time=30" << "-f" << path); if (!process.waitForFinished(60000)) return; QString result = QString(process.readAllStandardOutput()); if (result.size() == 0) result = QString(process.readAllStandardError()); @@ -152,7 +190,7 @@ void ParserWorker::execSelection(int tabIndex, QString text) return; } QProcess process(this); - process.start(phpPath, QStringList() << "-n" << "-d" << "max_execution_time=30" << "-r" << text); + process.start(phpPath, QStringList() << "-d" << "max_execution_time=30" << "-r" << text); if (!process.waitForFinished(60000)) return; QString result = QString(process.readAllStandardOutput()); if (result.size() == 0) result = QString(process.readAllStandardError()); @@ -160,6 +198,39 @@ void ParserWorker::execSelection(int tabIndex, QString text) emit execPHPFinished(tabIndex, output); } +void ParserWorker::startPHPWebServer(QString path) +{ + if (phpPath.size() == 0) { + emit message(tr("PHP executable not found.")); + return; + } + if (path.size() == 0 || !Helper::folderExists(path)) return; + if (phpWebServerPid != 0) return; + QProcess process(this); + process.setWorkingDirectory(path); + process.setProgram(phpPath); + process.setArguments(QStringList() << "-S" << PHP_WEBSERVER_URI); + process.setStandardOutputFile(QProcess::nullDevice()); + process.setStandardErrorFile(QProcess::nullDevice()); + if (process.startDetached(&phpWebServerPid)) { + emit execPHPWebServerFinished(true, tr("PHP web-server started.")); + } else { + emit execPHPWebServerFinished(false, tr("Could not start PHP web-server.")); + } +} + +void ParserWorker::stopPHPWebServer() +{ + if (phpWebServerPid == 0) return; + if (QProcess::startDetached("kill", {QString::number(phpWebServerPid)})) { + phpWebServerPid = 0; + // success = false (do not want browser to be opened) + emit execPHPWebServerFinished(false, tr("PHP web-server stopped.")); + } else { + emit execPHPWebServerFinished(false, tr("Could not stop PHP web-server.")); + } +} + void ParserWorker::phpcs(int tabIndex, QString path) { if (phpcsPath.size() == 0) return; //silence @@ -433,7 +504,7 @@ void ParserWorker::gitCommand(QString path, QString command, QStringList attrs, } if (path.size() == 0 || !Helper::folderExists(path)) return; bool useProgress = false; - if (command == GIT_PUSH_COMMAND || command == GIT_PULL_COMMAND) useProgress = true; + if (command == GIT_PUSH_COMMAND || command == GIT_PULL_COMMAND || command == GIT_CLONE_COMMAND) useProgress = true; if (useProgress && !isBusy) emit activateProgress(); QProcess process(this); process.setWorkingDirectory(path); @@ -610,3 +681,182 @@ void ParserWorker::cancelRequested() { wantStop = true; } + +bool ParserWorker::createAndroidDirectory(QDir rootDir, QString path) +{ + if (!rootDir.mkpath(path)) return false; + if (!setAndroidFilePermissions(path)) return false; + return true; +} + +bool ParserWorker::setAndroidFilePermissions(QFile &f) +{ + return f.setPermissions( + QFileDevice::ReadOwner | + QFileDevice::ReadGroup | + QFileDevice::ReadOther | + QFileDevice::WriteOwner | + QFileDevice::WriteGroup | + QFileDevice::WriteOther | + QFileDevice::ExeOwner | + QFileDevice::ExeGroup | + QFileDevice::ExeOther + ); +} + +bool ParserWorker::setAndroidFilePermissions(QString path) +{ + QFile f(path); + return setAndroidFilePermissions(f); +} + +bool ParserWorker::installAndroidFile(QString fileName, QString installDir) +{ + QFile f("assets:/"+fileName); + if (!f.exists()) return false; + + QFile fi(installDir+"/"+fileName); + if (fi.exists()) fi.remove(); + + if (!f.copy(installDir+"/"+fileName)) return false; + + QFile pf(installDir+"/"+fileName); + if (!setAndroidFilePermissions(pf)) return false; + + return true; +} + +void ParserWorker::installAndroidPack() +{ + if (androidHomePath.size() == 0) return; + if (isAndroidPackInstalled()) { + setAndroidBinPaths(); + return; + } + + emit installAndroidPackFinished(ANDROID_INSTALL_RESULT_LINE_TEMPLATE.arg(tr("Installing development pack..."))); + + if (installAndroidPackFiles()) { + QString androidPackInstallPath = androidHomePath + "/" + ANDROID_PACK_SUBDIR; + QString result = ""; + QProcess phpProcess(this); + phpProcess.start(androidPackInstallPath+"/"+ANDROID_BIN_DIR+"/php", QStringList() << "-v"); + if (phpProcess.waitForFinished()) { + QByteArray phpResult = phpProcess.readAllStandardError(); + phpResult += phpProcess.readAllStandardOutput(); + result += ANDROID_INSTALL_RESULT_LINE_TEMPLATE.arg(QString(phpResult).trimmed().split("\n").at(0)); + } + QProcess gitProcess(this); + gitProcess.start(androidPackInstallPath+"/"+ANDROID_BIN_DIR+"/git", QStringList() << "--version"); + if (gitProcess.waitForFinished()) { + QByteArray gitResult = gitProcess.readAllStandardError(); + gitResult += gitProcess.readAllStandardOutput(); + result += ANDROID_INSTALL_RESULT_LINE_TEMPLATE.arg(QString(gitResult).trimmed().split("\n").at(0)); + } + QProcess sasscProcess(this); + sasscProcess.start(androidPackInstallPath+"/"+ANDROID_BIN_DIR+"/sassc", QStringList() << "--version"); + if (sasscProcess.waitForFinished()) { + QByteArray sasscResult = sasscProcess.readAllStandardError(); + sasscResult += sasscProcess.readAllStandardOutput(); + result += ANDROID_INSTALL_RESULT_LINE_TEMPLATE.arg(QString(sasscResult).trimmed().split("\n").at(0)); + } + setAndroidBinPaths(); + emit installAndroidPackFinished(ANDROID_INSTALL_RESULT_LINE_TEMPLATE.arg(tr("Development pack successfully installed."))+result); + } else { + emit installAndroidPackFinished(ANDROID_INSTALL_RESULT_LINE_TEMPLATE.arg(tr("Installation failed :("))); + } +} + +bool ParserWorker::installAndroidPackFiles() +{ + // creating directories + QDir androidHomeDir(androidHomePath); + QFileInfo androidHomeDirInfo(androidHomePath); + if (!androidHomeDirInfo.isWritable() || !androidHomeDirInfo.isExecutable()) return false; + + if (!createAndroidDirectory(androidHomeDir, androidHomePath + "/" + ANDROID_PACK_SUBDIR)) return false; + QString androidPackInstallPath = androidHomePath + "/" + ANDROID_PACK_SUBDIR; + + QDir d(androidPackInstallPath); + if (!createAndroidDirectory(d, androidPackInstallPath+"/"+ANDROID_BIN_DIR)) return false; + if (!createAndroidDirectory(d, androidPackInstallPath+"/"+ANDROID_BIN_DIR+"/"+ANDROID_GIT_CORE_DIR)) return false; + if (!createAndroidDirectory(d, androidPackInstallPath+"/"+ANDROID_GIT_TEMPLATES_DIR)) return false; + if (!createAndroidDirectory(d, androidPackInstallPath+"/"+ANDROID_PHP_TMP_DIR)) return false; + + // copying files + for (QString fileName : androidBinFiles) { + if (!installAndroidFile(fileName, androidPackInstallPath+"/"+ANDROID_BIN_DIR)) return false; + } + + for (QString fileName : androidGitFiles) { + if (!installAndroidFile(fileName, androidPackInstallPath+"/"+ANDROID_BIN_DIR+"/"+ANDROID_GIT_CORE_DIR)) return false; + } + + for (QString fileName : androidOtherFiles) { + if (!installAndroidFile(fileName, androidPackInstallPath)) return false; + } + + // .gitconfig + QFile gitConfigHidden(androidPackInstallPath+"/.gitconfig"); + if (gitConfigHidden.exists()) gitConfigHidden.remove(); + + QFile gitConfig(androidPackInstallPath+"/gitconfig"); + if (gitConfig.exists()) gitConfig.rename(androidPackInstallPath+"/.gitconfig"); + + // run termux-elf-cleaner + QStringList cleanFiles; + for (QString fileName : androidBinFiles) { + if (fileName == "termux-elf-cleaner") continue; + cleanFiles << androidPackInstallPath+"/"+ANDROID_BIN_DIR+"/"+fileName; + } + + for (QString fileName : androidGitFiles) { + cleanFiles << androidPackInstallPath+"/"+ANDROID_BIN_DIR+"/"+ANDROID_GIT_CORE_DIR+"/"+fileName; + } + + QProcess cleanProcess(this); + cleanProcess.start(androidPackInstallPath+"/"+ANDROID_BIN_DIR+"/termux-elf-cleaner", cleanFiles); + if (!cleanProcess.waitForFinished()) return false; + + return true; +} + +bool ParserWorker::isAndroidPackInstalled() +{ + if (androidHomePath.size() == 0) return false; + + for (QString fileName : androidBinFiles) { + QFileInfo fileInfo(androidHomePath+"/"+ANDROID_PACK_SUBDIR+"/"+ANDROID_BIN_DIR+"/"+fileName); + if (!fileInfo.exists() || !fileInfo.isExecutable()) return false; + } + + for (QString fileName : androidGitFiles) { + QFileInfo fileInfo(androidHomePath+"/"+ANDROID_PACK_SUBDIR+"/"+ANDROID_BIN_DIR+"/"+ANDROID_GIT_CORE_DIR+"/"+fileName); + if (!fileInfo.exists() || !fileInfo.isExecutable()) return false; + } + + for (QString fileName : androidOtherFiles) { + if (fileName == "gitconfig") fileName = ".gitconfig"; + QFileInfo fileInfo(androidHomePath+"/"+ANDROID_PACK_SUBDIR+"/"+fileName); + if (!fileInfo.exists() || !fileInfo.isReadable()) return false; + } + + return true; +} + +void ParserWorker::setAndroidBinPaths() +{ + if (androidHomePath.size() == 0) return; + if (phpPath.size() == 0) { + QString phpPathStr = androidHomePath+"/"+ANDROID_PACK_SUBDIR+"/"+ANDROID_BIN_DIR+"/php"; + if (Helper::fileOrFolderExists(phpPathStr)) phpPath = phpPathStr; + } + if (gitPath.size() == 0) { + QString gitPathStr = androidHomePath+"/"+ANDROID_PACK_SUBDIR+"/"+ANDROID_BIN_DIR+"/git"; + if (Helper::fileOrFolderExists(gitPathStr)) gitPath = gitPathStr; + } + if (sasscPath.size() == 0) { + QString sasscPathStr = androidHomePath+"/"+ANDROID_PACK_SUBDIR+"/"+ANDROID_BIN_DIR+"/sassc"; + if (Helper::fileOrFolderExists(sasscPathStr)) sasscPath = sasscPathStr; + } +} diff --git a/src/settings.cpp b/src/settings.cpp index 9c22ac7..6289e54 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -118,7 +118,8 @@ Settings::Settings(QObject * parent) : QObject(parent) {"custom_snippets_file", ""}, {"scale_auto", "yes"}, {"scale_factor", "100"}, - {"scale_factor_unchecked", "no"} + {"scale_factor_unchecked", "no"}, + {"devpack_install_silent", "no"} }; } diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 35d97b4..51953b4 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -139,6 +139,19 @@ &Git + + + Repository + + + + + + + + + + @@ -175,6 +188,9 @@ + + + @@ -206,6 +222,7 @@ + @@ -1176,6 +1193,41 @@ Context menu + + + Initialize + + + + + Add remote URL + + + + + Change remote URL + + + + + Clone + + + + + Start PHP web-server + + + + + Stop PHP web-server + + + + + Zira DevPack + +