Ejemplo n.º 1
0
// determines the icon data; this could be either a path on disk (if we have
// a suitable icon locally), base64-encoded icon data (if the icon is embedded
// in an R package), or nothing (if we cannot determine an icon at all)
std::string iconData(const std::string& iconGroup, 
      const std::string& iconName,
      const std::string& iconPath)
{
   if (iconPath.empty())
   {
      // convert the icon name into the format of our shipped icons, which is
      // all lowercase with no whitespace (e.g. "SQL Server" => "sqlserver.png")
      std::string iconFilename(string_utils::toLower(iconName));
      iconFilename = boost::regex_replace(iconFilename,
            boost::regex("\\s"), "") + ".png";

      // the package did not supply an icon; see if there's one baked in
      FilePath path = options().rResourcesPath().childPath("connections")
         .childPath(iconGroup)
         .childPath(iconFilename);
      if (path.exists())
         return std::string("connections/") + iconGroup + "/" + iconFilename;

      if (iconGroup == "drivers")
         return std::string("connections/drivers/odbc.png");

      // didn't find anything
      return std::string();
   }

   // expand the path 
   FilePath icon = module_context::resolveAliasedPath(iconPath);
   std::string iconData;

   // ensure that the icon file exists and is a small GIF, JPG, or PNG image
   if (icon.exists() && icon.size() < kMaxIconSize &&
       (icon.hasExtensionLowerCase(".gif") ||
        icon.hasExtensionLowerCase(".png") ||
        icon.hasExtensionLowerCase(".jpg") ||
        icon.hasExtensionLowerCase(".jpeg")))
   {
      Error error = base64::encode(icon, &iconData);
      if (error)
         LOG_ERROR(error);
      else
      {
         iconData = "data:" + icon.mimeContentType("image/png") + 
                    ";base64," + iconData;
      }
   }
   return iconData;
}
Error HunspellCustomDictionaries::add(const FilePath& dicPath) const
{
   // validate .dic extension
   if (!dicPath.hasExtensionLowerCase(".dic"))
   {
      return systemError(boost::system::errc::invalid_argument,
                         ERROR_LOCATION);
   }

   // remove existing with same name
   std::string name = dicPath.stem();
   Error error = remove(name);
   if (error)
      LOG_ERROR(error);

   // add it
   return dicPath.copy(dictionaryPath(name));
}
Ejemplo n.º 3
0
void onDocSaved(FilePath &path)
{
   Error error;
   // ignore non-R Markdown saves
   if (!path.hasExtensionLowerCase(".rmd"))
      return;

   // find cache folder (bail out if it doesn't exist)
   FilePath cache = chunkCacheFolder(path, "", notebookCtxId());
   if (!cache.exists())
      return;

   FilePath saved = chunkCacheFolder(path, "", kSavedCtx);
   if (saved.exists())
   {
      // tidy up: remove any saved chunks that no longer exist
      error = removeStaleSavedChunks(path, saved);
      if (error)
         LOG_ERROR(error);
   }
   else
   {
      // no saved context yet; ensure we have a place to put it
      saved.ensureDirectory();
   }

   // move all the chunk definitions over to the saved context
   std::vector<FilePath> children;
   error = cache.children(&children);
   if (error)
   {
      LOG_ERROR(error);
      return;
   }
   BOOST_FOREACH(const FilePath source, children)
   {
      // compute the target path 
      FilePath target = saved.complete(source.filename());

      if (source.filename() == kNotebookChunkDefFilename) 
      {
         // the definitions should be copied (we always want them in both
         // contexts)
         error = target.removeIfExists();
         if (!error)
            error = source.copy(target);
      }
      else if (source.isDirectory())
      {
         // library folders should be merged and then removed, so we don't
         // lose library contents 
         if (source.filename() == kChunkLibDir)
         {
            error = mergeLib(source, target);
            if (!error)
               error = source.remove();
         }
         else
         {
            // the chunk output folders should be moved; destroy the old copy
            error = target.removeIfExists();
            if (!error)
               error = source.move(target);
         }
      }
      else
      {
         // nothing besides the chunks.json and chunk folders should be here,
         // so ignore other files/content
         continue;
      }

      if (error)
         LOG_ERROR(error);
   }