コード例 #1
0
QString GwtCallback::chooseRVersion()
{
#ifdef Q_OS_WIN32
   RVersion rVersion = desktop::detectRVersion(true, pOwner_->asWidget());
   if (rVersion.isValid())
      return getRVersion();
   else
      return QString();
#else
   return QString();
#endif
}
コード例 #2
0
void ChooseRHome::setValue(const RVersion& value, bool preferR64)
{
   if (value.isEmpty())
   {
      if (preferR64)
         ui->radioDefault64->setChecked(true);
      else
         ui->radioDefault->setChecked(true);
   }
   else
   {
      ui->radioCustom->setChecked(true);
      QList<QListWidgetItem*> matches =
            ui->listHomeDir->findItems(value.description(), Qt::MatchExactly);
      if (matches.size() > 0)
         matches.first()->setSelected(true);
      ui->listHomeDir->setFocus();
   }
}
コード例 #3
0
bool prepareEnvironment(Options &options)
{
   bool forceUi = ::GetAsyncKeyState(VK_CONTROL) & ~1;

   RVersion rVersion = detectRVersion(forceUi);
   if (!rVersion.isValid())
      return false;


   // get the short path version of the home dir
   std::string homePath =
         QDir::toNativeSeparators(rVersion.homeDir()).toStdString();
   DWORD len = ::GetShortPathName(homePath.c_str(), NULL, 0);
   std::vector<TCHAR> buffer(len, 0);
   if (::GetShortPathName(homePath.c_str(), &(buffer[0]), len) != 0)
   {
      // copy path to string and assign it we got one
      std::string shortHomePath(&(buffer[0]));
      if (!shortHomePath.empty())
         homePath = shortHomePath;
   }
   else
   {
      LOG_ERROR(systemError(::GetLastError(), ERROR_LOCATION));
   }


   // set R_HOME
   system::setenv("R_HOME", homePath);

   std::string path =
         QDir::toNativeSeparators(rVersion.binDir()).toStdString() + ";" +
         system::getenv("PATH");
   system::setenv("PATH", path);

   return true;
}
コード例 #4
0
ファイル: DesktopMain.cpp プロジェクト: flashus/rstudio
int main(int argc, char* argv[])
{
   core::system::initHook();

   try
   {
      QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

      // initialize log
      FilePath userHomePath = core::system::userHomePath("R_USER|HOME");
      FilePath logPath = core::system::userSettingsPath(
            userHomePath,
            "RStudio-Desktop").childPath("log");
      core::system::initializeLog("rdesktop",
                                  core::system::kLogLevelWarning,
                                  logPath);


      boost::scoped_ptr<QApplication> pApp;
      boost::scoped_ptr<ApplicationLaunch> pAppLaunch;
      ApplicationLaunch::init(QString::fromAscii("RStudio"),
                              argc,
                              argv,
                              &pApp,
                              &pAppLaunch);

      // determine the filename that was passed to us
      QString filename;
#ifdef __APPLE__
      // get filename from OpenFile apple-event (pump to ensure delivery)
      pApp->processEvents();
      filename = verifyAndNormalizeFilename(
                              pAppLaunch->startupOpenFileRequest());
#endif
      // allow all platforms (including OSX) to check the command line.
      // we include OSX because the way Qt handles apple events is to
      // re-route them to the first instance to register for events. in
      // this case (for projects) we use this to initiate a launch
      // of the application with the project filename on the command line
      if (filename.isEmpty())
      {
         // get filename from command line arguments
         if (pApp->arguments().size() > 1)
            filename = verifyAndNormalizeFilename(pApp->arguments().last());
      }

      // if we have a filename and it is NOT a project file then see
      // if we can open it within an existing instance
      if (isNonProjectFilename(filename))
      {
         if (pAppLaunch->sendMessage(filename))
            return 0;
      }
      else
      {
         // try to register ourselves as a peer for others
         pAppLaunch->attemptToRegisterPeer();
      }

      pApp->setAttribute(Qt::AA_MacDontSwapCtrlAndMeta);

      initializeSharedSecret();
      initializeWorkingDirectory(argc, argv, filename);
      initializeStartupEnvironment(&filename);

      Options& options = desktop::options();
      if (!prepareEnvironment(options))
         return 1;

      // get install path
      FilePath installPath;
      Error error = core::system::installPath("..", argc, argv, &installPath);
      if (error)
      {
         LOG_ERROR(error);
         return EXIT_FAILURE;
      }

#ifdef _WIN32
      RVersion version = detectRVersion(false);
#endif

      // calculate paths to config file and rsession
      FilePath confPath, sessionPath;

      // check for debug configuration
#ifndef NDEBUG
      FilePath currentPath = FilePath::safeCurrentPath(installPath);
      if (currentPath.complete("conf/rdesktop-dev.conf").exists())
      {
         confPath = currentPath.complete("conf/rdesktop-dev.conf");
         sessionPath = currentPath.complete("session/rsession");
#ifdef _WIN32
         if (version.architecture() == ArchX64)
            sessionPath = installPath.complete("x64/rsession");
#endif
      }
#endif

      // if there is no conf path then release mode
      if (confPath.empty())
      {
         // default session path (then tweak)
         sessionPath = installPath.complete("bin/rsession");

         // check for win64 binary on windows
#ifdef _WIN32
         if (version.architecture() == ArchX64)
            sessionPath = installPath.complete("bin/x64/rsession");
#endif

         // check for running in a bundle on OSX
#ifdef __APPLE__
         if (installPath.complete("Info.plist").exists())
            sessionPath = installPath.complete("MacOS/rsession");
#endif
      }
      core::system::fixupExecutablePath(&sessionPath);

      // launch session
      SessionLauncher sessionLauncher(sessionPath, confPath);
      error = sessionLauncher.launchFirstSession(filename, pAppLaunch.get());
      if (!error)
      {
         int result = pApp->exec();

         sessionLauncher.cleanupAtExit();

         options.cleanUpScratchTempDir();

         return result;
      }
      else
      {
         LOG_ERROR(error);

         // These calls to processEvents() seem to be necessary to get
         // readAllStandardError to work.
         pApp->processEvents();
         pApp->processEvents();
         pApp->processEvents();

         QMessageBox errorMsg(safeMessageBoxIcon(QMessageBox::Critical),
                              QString::fromUtf8("RStudio"),
                              sessionLauncher.launchFailedErrorMessage());
         errorMsg.addButton(new QPushButton(QString::fromUtf8("OK")),
                            QMessageBox::AcceptRole);
         errorMsg.show();

         pApp->exec();

         return EXIT_FAILURE;
      }
   }
   CATCH_UNEXPECTED_EXCEPTION
}
コード例 #5
0
void ChooseRHome::chooseOther()
{
   if (lastDir_.isEmpty())
   {
      lastDir_ = QString::fromLocal8Bit(core::system::getenv("ProgramFiles").c_str());
   }

   QString dir = QFileDialog::getExistingDirectory(
         this,
         QString::fromUtf8("Choose R Directory"),
         lastDir_,
         QFileDialog::ShowDirsOnly);

   if (dir.isEmpty())
      return;

   lastDir_ = dir;

   QList<RVersion> versions = detectVersionsInDir(dir);

   RVersion rVer;

   if (versions.size() == 0)
   {
      showWarning(
            this,
            QString::fromUtf8("Invalid R Directory"),
            QString::fromUtf8("This directory does not appear to contain a "
            "valid R installation.\n\nPlease try again."));
      return;
   }
   else if (versions.size() > 1)
   {
      QStringList items;
      for (int i = 0; i < versions.size(); i++)
         items << versions.at(i).description();

      QInputDialog inputDialog(this);
      inputDialog.setOptions(QInputDialog::UseListViewForComboBoxItems);
      inputDialog.setComboBoxItems(items);
      inputDialog.setComboBoxEditable(false);
      inputDialog.setWindowTitle(QString::fromUtf8("Choose Version"));
      inputDialog.setLabelText(QString::fromUtf8("Please choose the version to use:"));

      if (inputDialog.exec() != QDialog::Accepted)
         return;

      int idx = items.indexOf(QRegExp(inputDialog.textValue(),
                                      Qt::CaseSensitive,
                                      QRegExp::FixedString));
      if (idx < 0)
         return;
      rVer = versions.at(idx);
   }
   else // versions.size() == 1
   {
      rVer = versions.at(0);
   }

   switch (rVer.validate())
   {
   case desktop::ValidateSuccess:
      break;
   case desktop::ValidateNotFound:
      showWarning(
            this,
            QString::fromUtf8("Invalid R Directory"),
            QString::fromUtf8("This directory does not appear to contain a "
                              "valid R installation.\n\nPlease try again."));
      return;
   case desktop::ValidateBadArchitecture:
      showWarning(
            this,
            QString::fromUtf8("Incompatible R Build"),
            QString::fromUtf8("The version of R you've selected was built "
                              "for a different CPU architecture and cannot "
                              "be used with this version of RStudio."));
      return;
   case desktop::ValidateVersionTooOld:
   default:
      showWarning(
            this,
            QString::fromUtf8("Incompatible R Build"),
            QString::fromUtf8("The version of R you've selected is not "
                              "compatible with RStudio. Please install a "
                              "newer version of R."));
      return;
   }

   QList<QListWidgetItem*> items = ui->listHomeDir->findItems(
         rVer.description(), Qt::MatchExactly);
   if (!items.isEmpty())
   {
      ui->listHomeDir->setCurrentItem(items[0]);
   }
   else
   {
      QListWidgetItem* pItem = toItem(rVer);
      ui->listHomeDir->addItem(pItem);
      pItem->setSelected(true);
   }
}
コード例 #6
0
ファイル: DesktopMain.cpp プロジェクト: dreammaster38/rstudio
int main(int argc, char* argv[])
{
   core::system::initHook();

   try
   {
      initializeLang();

      // initialize log
      core::system::initializeLog("rdesktop",
                                  core::system::kLogLevelWarning,
                                  desktop::userLogPath());

      // ignore SIGPIPE
      Error error = core::system::ignoreSignal(core::system::SigPipe);
      if (error)
         LOG_ERROR(error);

#ifdef __APPLE__
      // font substituion for OSX Mavericks
      // see: https://bugreports.qt-project.org/browse/QTBUG-32789
      QFont::insertSubstitution(QString::fromUtf8(".Lucida Grande UI"),
                                QString::fromUtf8("Lucida Grande"));
#endif

      boost::scoped_ptr<QApplication> pApp;
      boost::scoped_ptr<ApplicationLaunch> pAppLaunch;
      ApplicationLaunch::init(QString::fromUtf8("RStudio"),
                              argc,
                              argv,
                              &pApp,
                              &pAppLaunch);

      // determine the filename that was passed to us
      QString filename;
#ifdef __APPLE__
      // get filename from OpenFile apple-event (pump to ensure delivery)
      pApp->processEvents();
      filename = verifyAndNormalizeFilename(
                              pAppLaunch->startupOpenFileRequest());
#endif
      // allow all platforms (including OSX) to check the command line.
      // we include OSX because the way Qt handles apple events is to
      // re-route them to the first instance to register for events. in
      // this case (for projects) we use this to initiate a launch
      // of the application with the project filename on the command line
      if (filename.isEmpty())
      {
         // get filename from command line arguments
         if (pApp->arguments().size() > 1)
         {
            QString arg = pApp->arguments().last();
            if (arg != QString::fromUtf8(kRunDiagnosticsOption))
               filename = verifyAndNormalizeFilename(arg);
         }
      }

      // if we have a filename and it is NOT a project file then see
      // if we can open it within an existing instance
      if (isNonProjectFilename(filename))
      {
         if (pAppLaunch->sendMessage(filename))
            return 0;
      }
      else
      {
         // try to register ourselves as a peer for others
         pAppLaunch->attemptToRegisterPeer();
      }

      // init options from command line
      desktop::options().initFromCommandLine(pApp->arguments());

      // reset log if we are in run-diagnostics mode
      if (desktop::options().runDiagnostics())
      {
         desktop::reattachConsoleIfNecessary();
         initializeStderrLog("rdesktop", core::system::kLogLevelWarning);
      }

      pApp->setAttribute(Qt::AA_MacDontSwapCtrlAndMeta);

      initializeSharedSecret();
      initializeWorkingDirectory(argc, argv, filename);
      initializeStartupEnvironment(&filename);

      Options& options = desktop::options();
      if (!prepareEnvironment(options))
         return 1;

      // get install path
      FilePath installPath;
      error = core::system::installPath("..", argv[0], &installPath);
      if (error)
      {
         LOG_ERROR(error);
         return EXIT_FAILURE;
      }

#ifdef _WIN32
      RVersion version = detectRVersion(false);
#endif

      // calculate paths to config file, rsession, and desktop scripts
      FilePath confPath, sessionPath, scriptsPath;

      // check for debug configuration
#ifndef NDEBUG
      FilePath currentPath = FilePath::safeCurrentPath(installPath);
      if (currentPath.complete("conf/rdesktop-dev.conf").exists())
      {
         confPath = currentPath.complete("conf/rdesktop-dev.conf");
         sessionPath = currentPath.complete("session/rsession");
         scriptsPath = currentPath.complete("desktop");
#ifdef _WIN32
         if (version.architecture() == ArchX64)
            sessionPath = installPath.complete("x64/rsession");
#endif
      }
#endif

      // if there is no conf path then release mode
      if (confPath.empty())
      {
         // default paths (then tweak)
         sessionPath = installPath.complete("bin/rsession");
         scriptsPath = installPath.complete("bin");

         // check for win64 binary on windows
#ifdef _WIN32
         if (version.architecture() == ArchX64)
            sessionPath = installPath.complete("bin/x64/rsession");
#endif

         // check for running in a bundle on OSX
#ifdef __APPLE__
         if (installPath.complete("Info.plist").exists())
         {
            sessionPath = installPath.complete("MacOS/rsession");
            scriptsPath = installPath.complete("MacOS");
         }
#endif
      }
      core::system::fixupExecutablePath(&sessionPath);

      // set the scripts path in options
      desktop::options().setScriptsPath(scriptsPath);

      // launch session
      SessionLauncher sessionLauncher(sessionPath, confPath);
      error = sessionLauncher.launchFirstSession(filename, pAppLaunch.get());
      if (!error)
      {
         int result = pApp->exec();

         sessionLauncher.cleanupAtExit();

         options.cleanUpScratchTempDir();

         return result;
      }
      else
      {
         LOG_ERROR(error);

         // These calls to processEvents() seem to be necessary to get
         // readAllStandardError to work.
         pApp->processEvents();
         pApp->processEvents();
         pApp->processEvents();

         QMessageBox errorMsg(safeMessageBoxIcon(QMessageBox::Critical),
                              QString::fromUtf8("RStudio"),
                              sessionLauncher.launchFailedErrorMessage());
         errorMsg.addButton(new QPushButton(QString::fromUtf8("OK")),
                            QMessageBox::AcceptRole);
         errorMsg.show();

         pApp->exec();

         return EXIT_FAILURE;
      }
   }
   CATCH_UNEXPECTED_EXCEPTION
}
コード例 #7
0
ファイル: DesktopMain.cpp プロジェクト: kiwiroy/rstudio
int main(int argc, char* argv[])
{
   core::system::initHook();

   try
   {
      initializeLang();
      
      if (useChromiumDevtools())
      {
         // use QTcpSocket to find an open port. this is unfortunately a bit racey
         // but AFAICS there isn't a better solution for port selection
         QByteArray port;
         QTcpSocket* pSocket = new QTcpSocket();
         if (pSocket->bind())
         {
            quint16 port = pSocket->localPort();
            desktopInfo().setChromiumDevtoolsPort(port);
            core::system::setenv("QTWEBENGINE_REMOTE_DEBUGGING", safe_convert::numberToString(port));
            pSocket->close();
         }
      }

      // initialize log
      core::system::initializeLog("rdesktop",
                                  core::system::kLogLevelWarning,
                                  desktop::userLogPath());

      // ignore SIGPIPE
      Error error = core::system::ignoreSignal(core::system::SigPipe);
      if (error)
         LOG_ERROR(error);

      // attempt to remove stale lockfiles, as they can impede
      // application startup
      error = removeStaleOptionsLockfile();
      if (error)
         LOG_ERROR(error);

      // set application attributes
      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      
      // prepare command line arguments
      static std::vector<char*> arguments(argv, argv + argc);
      
      // enable viewport meta (allows us to control / restrict
      // certain touch gestures)
      static char enableViewport[] = "--enable-viewport";
      arguments.push_back(enableViewport);
      
#ifndef NDEBUG
      // disable web security for development builds (so we can
      // get access to sourcemaps)
      static char disableWebSecurity[] = "--disable-web-security";
      arguments.push_back(disableWebSecurity);
#endif
      
      // disable chromium renderer accessibility by default (it can cause
      // slowdown when used in conjunction with some applications; see e.g.
      // https://github.com/rstudio/rstudio/issues/1990)
      if (core::system::getenv("RSTUDIO_ACCESSIBILITY").empty())
      {
         static char disableRendererAccessibility[] = "--disable-renderer-accessibility";
         arguments.push_back(disableRendererAccessibility);
      }

#ifdef Q_OS_LINUX
      // workaround for Qt 5.10.1 bug "Could not find QtWebEngineProcess"
      // https://bugreports.qt.io/browse/QTBUG-67023
      // https://bugreports.qt.io/browse/QTBUG-66346
      static char noSandbox[] = "--no-sandbox";
      arguments.push_back(noSandbox);
#endif

#ifdef Q_OS_MAC
      // don't prefer compositing to LCD text rendering. when enabled, this causes the compositor to
      // be used too aggressively on Retina displays on macOS, with the side effect that the
      // scrollbar doesn't auto-hide because a compositor layer is present.
      // https://github.com/rstudio/rstudio/issues/1953
      static char disableCompositorPref[] = "--disable-prefer-compositing-to-lcd-text";
      arguments.push_back(disableCompositorPref);
      
      // disable gpu rasterization for certain display configurations.
      // this works around some of the rendering issues seen with RStudio.
      //
      // https://bugs.chromium.org/p/chromium/issues/detail?id=773705
      // https://github.com/rstudio/rstudio/issues/2093
      //
      // because the issue seems to only affect certain video cards on macOS
      // High Sierra, we scope that change to that particular configuration
      // for now (we can expand this list if more users report issues)
      core::Version macVersion(QSysInfo::productVersion().toStdString());
      if (macVersion.versionMajor() == 10 &&
          macVersion.versionMinor() == 13)
      {
         core::system::ProcessResult processResult;
         core::system::runCommand(
                  "/usr/sbin/system_profiler SPDisplaysDataType",
                  core::system::ProcessOptions(),
                  &processResult);

         std::string stdOut = processResult.stdOut;
         if (!stdOut.empty())
         {
            std::vector<std::string> blackList = {
               "NVIDIA GeForce GT 650M",
               "NVIDIA GeForce GT 750M"
            };

            for (const std::string& entry : blackList)
            {
               if (stdOut.find(entry) != std::string::npos)
               {
                  static char disableGpuRasterization[] = "--disable-gpu-rasterization";
                  arguments.push_back(disableGpuRasterization);
                  break;
               }
            }
         }
      }
#endif

      // re-assign command line arguments
      argc = (int) arguments.size();
      argv = &arguments[0];

      // prepare application for launch
      boost::scoped_ptr<QApplication> pApp;
      boost::scoped_ptr<ApplicationLaunch> pAppLaunch;
      ApplicationLaunch::init(QString::fromUtf8("RStudio"),
                              argc,
                              argv,
                              &pApp,
                              &pAppLaunch);

      // determine the filename that was passed to us
      QString filename;
#ifdef __APPLE__
      // get filename from OpenFile apple-event (pump to ensure delivery)
      pApp->processEvents();
      filename = verifyAndNormalizeFilename(
                              pAppLaunch->startupOpenFileRequest());
#endif
      // allow all platforms (including OSX) to check the command line.
      // we include OSX because the way Qt handles apple events is to
      // re-route them to the first instance to register for events. in
      // this case (for projects) we use this to initiate a launch
      // of the application with the project filename on the command line
      if (filename.isEmpty())
      {
         // get filename from command line arguments
         if (pApp->arguments().size() > 1)
         {
            QString arg = pApp->arguments().at(1);
            if (arg != QString::fromUtf8(kRunDiagnosticsOption))
               filename = verifyAndNormalizeFilename(arg);
         }
      }

      // if we have a filename and it is NOT a project file then see
      // if we can open it within an existing instance
      if (isNonProjectFilename(filename))
      {
         if (pAppLaunch->sendMessage(filename))
            return 0;
      }
      else
      {
         // try to register ourselves as a peer for others
         pAppLaunch->attemptToRegisterPeer();
      }

      // init options from command line
      desktop::options().initFromCommandLine(pApp->arguments());

      // reset log if we are in run-diagnostics mode
      if (desktop::options().runDiagnostics())
      {
         desktop::reattachConsoleIfNecessary();
         initializeStderrLog("rdesktop", core::system::kLogLevelWarning);
      }

      initializeSharedSecret();
      initializeWorkingDirectory(argc, argv, filename);
      initializeStartupEnvironment(&filename);

      Options& options = desktop::options();
      if (!prepareEnvironment(options))
         return 1;

      // get install path
      FilePath installPath;
      error = core::system::installPath("..", argv[0], &installPath);
      if (error)
      {
         LOG_ERROR(error);
         return EXIT_FAILURE;
      }

#ifdef _WIN32
      RVersion version = detectRVersion(false);
#endif

      // calculate paths to config file, rsession, and desktop scripts
      FilePath confPath, sessionPath, scriptsPath;
      bool devMode = false;

      // check for debug configuration
      FilePath currentPath = FilePath::safeCurrentPath(installPath);
      if (currentPath.complete("conf/rdesktop-dev.conf").exists())
      {
         confPath = currentPath.complete("conf/rdesktop-dev.conf");
         sessionPath = currentPath.complete("session/rsession");
         scriptsPath = currentPath.complete("desktop");
         devMode = true;
#ifdef _WIN32
         if (version.architecture() == ArchX64 &&
             installPath.complete("session/x64").exists())
         {
            sessionPath = installPath.complete("session/x64/rsession");
         }
#endif
      }

      // if there is no conf path then release mode
      if (confPath.empty())
      {
         // default paths (then tweak)
         sessionPath = installPath.complete("bin/rsession");
         scriptsPath = installPath.complete("bin");

         // check for win64 binary on windows
#ifdef _WIN32
         if (version.architecture() == ArchX64 &&
             installPath.complete("bin/x64").exists())
         {
            sessionPath = installPath.complete("bin/x64/rsession");
         }
#endif

         // check for running in a bundle on OSX
#ifdef __APPLE__
         if (installPath.complete("Info.plist").exists())
         {
            sessionPath = installPath.complete("MacOS/rsession");
            scriptsPath = installPath.complete("MacOS");
         }
#endif
      }
      core::system::fixupExecutablePath(&sessionPath);

      auto* pProxyFactory = new NetworkProxyFactory();
      QNetworkProxyFactory::setApplicationProxyFactory(pProxyFactory);

      // set the scripts path in options
      desktop::options().setScriptsPath(scriptsPath);

      // launch session
      SessionLauncher sessionLauncher(sessionPath, confPath, filename, pAppLaunch.get());
      sessionLauncher.launchFirstSession(installPath, devMode, pApp->arguments());

      ProgressActivator progressActivator;

      int result = pApp->exec();

      desktop::activation().releaseLicense();
      options.cleanUpScratchTempDir();

      return result;
   }
   CATCH_UNEXPECTED_EXCEPTION
}