/src/lib/standardactions.cpp

https://github.com/ManuelSchneid3r/albert · C++ · 125 lines · 83 code · 31 blank · 11 comment · 14 complexity · 728497d7c550481921f096c246bf8ba7 MD5 · raw file

  1. // Copyright (C) 2014-2019 Manuel Schneider
  2. #include <QGuiApplication>
  3. #include <QClipboard>
  4. #include <QDesktopServices>
  5. #include <QProcess>
  6. #include <QStringList>
  7. #include <pwd.h>
  8. #include <unistd.h>
  9. #include "albert/util/shutil.h"
  10. #include "standardactions.h"
  11. // Place it somewhere for now. TODO: move it to potential core plugin
  12. EXPORT_CORE QString terminalCommand;
  13. /** **************************************************************************/
  14. Core::StandardActionBase::StandardActionBase(const QString &text)
  15. : text_(std::move(text))
  16. {
  17. }
  18. QString Core::StandardActionBase::text() const
  19. {
  20. return text_;
  21. }
  22. /** **************************************************************************/
  23. Core::FuncAction::FuncAction(const QString &text, std::function<void ()> action)
  24. : StandardActionBase(text), action_(std::move(action))
  25. {
  26. }
  27. void Core::FuncAction::activate()
  28. {
  29. action_();
  30. }
  31. /** **************************************************************************/
  32. Core::ClipAction::ClipAction(const QString &text, QString clipBoardText)
  33. : StandardActionBase(text), clipBoardText_(std::move(clipBoardText))
  34. {
  35. }
  36. void Core::ClipAction::activate()
  37. {
  38. QGuiApplication::clipboard()->setText(clipBoardText_);
  39. }
  40. /** **************************************************************************/
  41. Core::UrlAction::UrlAction(const QString &text, QUrl url)
  42. : StandardActionBase(text), url_(std::move(url))
  43. {
  44. }
  45. void Core::UrlAction::activate()
  46. {
  47. QDesktopServices::openUrl(url_);
  48. }
  49. /** **************************************************************************/
  50. Core::ProcAction::ProcAction(const QString &text, const QStringList &commandline, const QString &workingDirectory)
  51. : StandardActionBase(text), commandline_(commandline), workingDir_(workingDirectory)
  52. {
  53. }
  54. void Core::ProcAction::activate()
  55. {
  56. if (commandline_.isEmpty())
  57. return;
  58. QStringList commandline = commandline_;
  59. if (workingDir_.isEmpty())
  60. QProcess::startDetached(commandline.takeFirst(), commandline);
  61. else
  62. QProcess::startDetached(commandline.takeFirst(), commandline, workingDir_);
  63. }
  64. /** **************************************************************************/
  65. Core::TermAction::TermAction(const QString &text, const QStringList &commandline, const QString &workingDirectory, bool shell, Core::TermAction::CloseBehavior behavior)
  66. : ProcAction (text, commandline, workingDirectory), shell_(shell), behavior_(behavior)
  67. {
  68. }
  69. void Core::TermAction::activate()
  70. {
  71. if (commandline_.isEmpty())
  72. return;
  73. if (shell_){
  74. // Quote the input commandline since it's nested
  75. QStringList quotedCommandLine;
  76. for (const QString &strRef : commandline_)
  77. quotedCommandLine << ShUtil::quote(strRef);
  78. // Get the user shell (passwd must not be freed)
  79. passwd *pwd = getpwuid(geteuid());
  80. if (pwd == nullptr)
  81. throw "Could not retrieve user shell";
  82. // Let standard shell handle flow control (syntax differs in shells, e.g. fish)
  83. commandline_ = Core::ShUtil::split(terminalCommand);
  84. if (behavior_ == CloseBehavior::DoNotClose)
  85. commandline_ << "sh" << "-ic" << QString("%1 -ic '%2'; exec %1").arg(pwd->pw_shell, quotedCommandLine.join(' '));
  86. else if (behavior_ == CloseBehavior::CloseOnSuccess)
  87. commandline_ << "sh" << "-ic" << QString("%1 -ic '%2' && sleep 1 || exec %1").arg(pwd->pw_shell, quotedCommandLine.join(' '));
  88. else // behavior_ == CloseBehavior::CloseOnExit
  89. commandline_ << "sh" << "-ic" << QString("%1 -ic '%2'; sleep 1 ").arg(pwd->pw_shell, quotedCommandLine.join(' '));
  90. } else {
  91. commandline_ = Core::ShUtil::split(terminalCommand) + commandline_;
  92. }
  93. ProcAction::activate();
  94. }