summaryrefslogtreecommitdiffstats
path: root/src/resource-manager.cpp
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2018-10-13 07:37:26 +0000
committerTavmjong Bah <tavmjong@free.fr>2018-10-13 07:37:26 +0000
commitfaf43f2ffa88561acb95909861bb28fcdfaeb858 (patch)
tree77f397b880ec970981a754c9549b24842161855b /src/resource-manager.cpp
parentCI/AppVeyor: increase clone depth (diff)
downloadinkscape-faf43f2ffa88561acb95909861bb28fcdfaeb858.tar.gz
inkscape-faf43f2ffa88561acb95909861bb28fcdfaeb858.zip
Move some files to 'io' directory.
Diffstat (limited to 'src/resource-manager.cpp')
-rw-r--r--src/resource-manager.cpp445
1 files changed, 0 insertions, 445 deletions
diff --git a/src/resource-manager.cpp b/src/resource-manager.cpp
deleted file mode 100644
index 6a455a8cc..000000000
--- a/src/resource-manager.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Inkscape::ResourceManager - tracks external resources such as image and css files.
- *
- * Copyright 2011 Jon A. Cruz <jon@joncruz.org>
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <string>
-#include <vector>
-#include <algorithm>
-
-#include <gtkmm/recentmanager.h>
-#include <glibmm/i18n.h>
-#include <glibmm/miscutils.h>
-#include <glibmm/fileutils.h>
-#include <glibmm/uriutils.h>
-#include <glibmm/convert.h>
-
-#include "resource-manager.h"
-
-#include "document.h"
-#include "document-undo.h"
-#include "verbs.h"
-
-#include "object/sp-object.h"
-
-#include "xml/node.h"
-
-namespace Inkscape {
-
-static std::vector<std::string> splitPath( std::string const &path )
-{
- std::vector<std::string> parts;
-
- std::string prior;
- std::string tmp = path;
- while ( !tmp.empty() && (tmp != prior) ) {
- prior = tmp;
-
- parts.push_back( Glib::path_get_basename(tmp) );
- tmp = Glib::path_get_dirname(tmp);
- }
- if ( !parts.empty() ) {
- std::reverse(parts.begin(), parts.end());
- if ( (parts[0] == ".") && (path[0] != '.') ) {
- parts.erase(parts.begin());
- }
- }
-
- return parts;
-}
-
-static std::string convertPathToRelative( std::string const &path, std::string const &docbase )
-{
- std::string result = path;
-
- if ( !path.empty() && Glib::path_is_absolute(path) ) {
- // Whack the parts into pieces
-
- std::vector<std::string> parts = splitPath(path);
- std::vector<std::string> baseParts = splitPath(docbase);
-
- // TODO debug g_message("+++++++++++++++++++++++++");
- for ( std::vector<std::string>::iterator it = parts.begin(); it != parts.end(); ++it ) {
- // TODO debug g_message(" [%s]", it->c_str());
- }
- // TODO debug g_message(" - - - - - - - - - - - - - - - ");
- for ( std::vector<std::string>::iterator it = baseParts.begin(); it != baseParts.end(); ++it ) {
- // TODO debug g_message(" [%s]", it->c_str());
- }
- // TODO debug g_message("+++++++++++++++++++++++++");
-
- if ( !parts.empty() && !baseParts.empty() && (parts[0] == baseParts[0]) ) {
- // Both paths have the same root. We can proceed.
- while ( !parts.empty() && !baseParts.empty() && (parts[0] == baseParts[0]) ) {
- parts.erase( parts.begin() );
- baseParts.erase( baseParts.begin() );
- }
-
- // TODO debug g_message("+++++++++++++++++++++++++");
- for ( std::vector<std::string>::iterator it = parts.begin(); it != parts.end(); ++it ) {
- // TODO debug g_message(" [%s]", it->c_str());
- }
- // TODO debug g_message(" - - - - - - - - - - - - - - - ");
- for ( std::vector<std::string>::iterator it = baseParts.begin(); it != baseParts.end(); ++it ) {
- // TODO debug g_message(" [%s]", it->c_str());
- }
- // TODO debug g_message("+++++++++++++++++++++++++");
-
- if ( !parts.empty() ) {
- result.clear();
-
- for ( size_t i = 0; i < baseParts.size(); ++i ) {
- parts.insert(parts.begin(), "..");
- }
- result = Glib::build_filename( parts );
- // TODO debug g_message("----> [%s]", result.c_str());
- }
- }
- }
-
- return result;
-}
-
-
-class ResourceManagerImpl : public ResourceManager {
-public:
- ResourceManagerImpl();
- ~ResourceManagerImpl() override;
-
- bool fixupBrokenLinks(SPDocument *doc) override;
-
-
- /**
- * Walk all links in a document and create a listing of unique broken links.
- *
- * @return a list of all broken links.
- */
- std::vector<Glib::ustring> findBrokenLinks(SPDocument *doc);
-
- /**
- * Resolve broken links as a whole and return a map for those that can be found.
- *
- * Note: this will allow for future enhancements including relinking to new locations
- * with the most broken files found, etc.
- *
- * @return a map of found links.
- */
- std::map<Glib::ustring, Glib::ustring> locateLinks(Glib::ustring const & docbase, std::vector<Glib::ustring> const & brokenLinks);
-
-
- /**
- * Try to parse href into a local filename using standard methods.
- *
- * @return true if successful.
- */
- bool extractFilepath( Glib::ustring const &href, std::string &uri );
-
- /**
- * Try to parse href into a local filename using some non-standard methods.
- * This means the href is likely invalid and should be rewritten.
- *
- * @return true if successful.
- */
- bool reconstructFilepath( Glib::ustring const &href, std::string &uri );
-
- bool searchUpwards( std::string const &base, std::string const &subpath, std::string &dest );
-
-protected:
-};
-
-
-ResourceManagerImpl::ResourceManagerImpl()
- : ResourceManager()
-{
-}
-
-ResourceManagerImpl::~ResourceManagerImpl()
-= default;
-
-bool ResourceManagerImpl::extractFilepath( Glib::ustring const &href, std::string &uri )
-{
- bool isFile = false;
-
- uri.clear();
-
- std::string scheme = Glib::uri_parse_scheme(href);
- if ( !scheme.empty() ) {
- // TODO debug g_message("Scheme is now [%s]", scheme.c_str());
- if ( scheme == "file" ) {
- // TODO debug g_message("--- is a file URI [%s]", href.c_str());
-
- // throws Glib::ConvertError:
- try {
- uri = Glib::filename_from_uri(href);
- // TODO debug g_message(" [%s]", uri.c_str());
- isFile = true;
- } catch(Glib::ConvertError e) {
- g_warning("%s", e.what().c_str());
- }
- }
- } else {
- // No scheme. Assuming it is a file path (absolute or relative).
- // throws Glib::ConvertError:
- uri = Glib::filename_from_utf8( href );
- isFile = true;
- }
-
- return isFile;
-}
-
-bool ResourceManagerImpl::reconstructFilepath( Glib::ustring const &href, std::string &uri )
-{
- bool isFile = false;
-
- uri.clear();
-
- std::string scheme = Glib::uri_parse_scheme(href);
- if ( !scheme.empty() ) {
- if ( scheme == "file" ) {
- // try to build a relative filename for URIs like "file:image.png"
- // they're not standard conformant but not uncommon
- Glib::ustring href_new = Glib::ustring(href, 5);
- uri = Glib::filename_from_utf8(href_new);
- // TODO debug g_message("reconstructed path for '%s' into '%s'", href.c_str(), uri.c_str());
- isFile = true;
- }
- }
- return isFile;
-}
-
-
-std::vector<Glib::ustring> ResourceManagerImpl::findBrokenLinks( SPDocument *doc )
-{
- std::vector<Glib::ustring> result;
- std::set<Glib::ustring> uniques;
-
- if ( doc ) {
- std::vector<SPObject *> images = doc->getResourceList("image");
- for (std::vector<SPObject *>::const_iterator it = images.begin(); it != images.end(); ++it) {
- Inkscape::XML::Node *ir = (*it)->getRepr();
-
- gchar const *href = ir->attribute("xlink:href");
- if ( href && ( uniques.find(href) == uniques.end() ) ) {
- std::string uri;
- if ( extractFilepath( href, uri ) ) {
- if ( Glib::path_is_absolute(uri) ) {
- if ( !Glib::file_test(uri, Glib::FILE_TEST_EXISTS) ) {
- result.emplace_back(href);
- uniques.insert(href);
- }
- } else {
- std::string combined = Glib::build_filename(doc->getBase(), uri);
- if ( !Glib::file_test(combined, Glib::FILE_TEST_EXISTS) ) {
- result.emplace_back(href);
- uniques.insert(href);
- }
- }
- } else if ( reconstructFilepath( href, uri ) ) {
- result.emplace_back(href);
- uniques.insert(href);
- }
- }
- }
- }
-
- return result;
-}
-
-
-std::map<Glib::ustring, Glib::ustring> ResourceManagerImpl::locateLinks(Glib::ustring const & docbase, std::vector<Glib::ustring> const & brokenLinks)
-{
- std::map<Glib::ustring, Glib::ustring> result;
-
-
- // Note: we use a vector because we want them to stay in order:
- std::vector<std::string> priorLocations;
-
- Glib::RefPtr<Gtk::RecentManager> recentMgr = Gtk::RecentManager::get_default();
- std::vector< Glib::RefPtr<Gtk::RecentInfo> > recentItems = recentMgr->get_items();
- for ( std::vector< Glib::RefPtr<Gtk::RecentInfo> >::iterator it = recentItems.begin(); it != recentItems.end(); ++it ) {
- Glib::ustring uri = (*it)->get_uri();
- std::string scheme = Glib::uri_parse_scheme(uri);
- if ( scheme == "file" ) {
- try {
- std::string path = Glib::filename_from_uri(uri);
- path = Glib::path_get_dirname(path);
- if ( std::find(priorLocations.begin(), priorLocations.end(), path) == priorLocations.end() ) {
- // TODO debug g_message(" ==>[%s]", path.c_str());
- priorLocations.push_back(path);
- }
- } catch (Glib::ConvertError e) {
- g_warning("%s", e.what().c_str());
- }
- }
- }
-
- // At the moment we expect this list to contain file:// references, or simple relative or absolute paths.
- for ( std::vector<Glib::ustring>::const_iterator it = brokenLinks.begin(); it != brokenLinks.end(); ++it ) {
- // TODO debug g_message("========{%s}", it->c_str());
-
- std::string uri;
- if ( extractFilepath( *it, uri ) || reconstructFilepath( *it, uri ) ) {
- // We were able to get some path. Check it
- std::string origPath = uri;
-
- if ( !Glib::path_is_absolute(uri) ) {
- uri = Glib::build_filename(docbase, uri);
- // TODO debug g_message(" not absolute. Fixing up as [%s]", uri.c_str());
- }
-
- bool exists = Glib::file_test(uri, Glib::FILE_TEST_EXISTS);
-
- // search in parent folders
- if (!exists) {
- exists = searchUpwards( docbase, origPath, uri );
- }
-
- // Check if the MRU bases point us to it.
- if ( !exists ) {
- if ( !Glib::path_is_absolute(origPath) ) {
- for ( std::vector<std::string>::iterator it = priorLocations.begin(); !exists && (it != priorLocations.end()); ++it ) {
- exists = searchUpwards( *it, origPath, uri );
- }
- }
- }
-
- if ( exists ) {
- if ( Glib::path_is_absolute( uri ) ) {
- // TODO debug g_message("Need to convert to relative if possible [%s]", uri.c_str());
- uri = convertPathToRelative( uri, docbase );
- }
-
- bool isAbsolute = Glib::path_is_absolute( uri );
- Glib::ustring replacement = isAbsolute ? Glib::filename_to_uri( uri ) : Glib::filename_to_utf8( uri );
- result[*it] = replacement;
- }
- }
- }
-
- return result;
-}
-
-bool ResourceManagerImpl::fixupBrokenLinks(SPDocument *doc)
-{
- bool changed = false;
- if ( doc ) {
- // TODO debug g_message("FIXUP FIXUP FIXUP FIXUP FIXUP FIXUP FIXUP FIXUP FIXUP FIXUP");
- // TODO debug g_message(" base is [%s]", doc->getBase());
-
- std::vector<Glib::ustring> brokenHrefs = findBrokenLinks(doc);
- if ( !brokenHrefs.empty() ) {
- // TODO debug g_message(" FOUND SOME LINKS %d", static_cast<int>(brokenHrefs.size()));
- for ( std::vector<Glib::ustring>::iterator it = brokenHrefs.begin(); it != brokenHrefs.end(); ++it ) {
- // TODO debug g_message(" [%s]", it->c_str());
- }
- }
-
- std::map<Glib::ustring, Glib::ustring> mapping = locateLinks(doc->getBase(), brokenHrefs);
- for ( std::map<Glib::ustring, Glib::ustring>::iterator it = mapping.begin(); it != mapping.end(); ++it )
- {
- // TODO debug g_message(" [%s] ==> {%s}", it->first.c_str(), it->second.c_str());
- }
-
- bool savedUndoState = DocumentUndo::getUndoSensitive(doc);
- DocumentUndo::setUndoSensitive(doc, true);
-
- std::vector<SPObject *> images = doc->getResourceList("image");
- for (std::vector<SPObject *>::const_iterator it = images.begin(); it != images.end(); ++it) {
- Inkscape::XML::Node *ir = (*it)->getRepr();
-
- gchar const *href = ir->attribute("xlink:href");
- if ( href ) {
- // TODO debug g_message(" consider [%s]", href);
-
- if ( mapping.find(href) != mapping.end() ) {
- // TODO debug g_message(" Found a replacement");
-
- ir->setAttribute( "xlink:href", mapping[href].c_str() );
- if ( ir->attribute( "sodipodi:absref" ) ) {
- ir->setAttribute( "sodipodi:absref", nullptr ); // Remove this attribute
- }
-
- SPObject *updated = doc->getObjectByRepr(ir);
- if (updated) {
- // force immediate update of dependent attributes
- updated->updateRepr();
- }
-
- changed = true;
- }
- }
- }
- if ( changed ) {
- DocumentUndo::done( doc, SP_VERB_DIALOG_XML_EDITOR, _("Fixup broken links") );
- }
- DocumentUndo::setUndoSensitive(doc, savedUndoState);
- }
-
- return changed;
-}
-
-
-bool ResourceManagerImpl::searchUpwards( std::string const &base, std::string const &subpath, std::string &dest )
-{
- bool exists = false;
- // TODO debug g_message("............");
-
- std::vector<std::string> parts = splitPath(subpath);
- std::vector<std::string> baseParts = splitPath(base);
-
- while ( !exists && !baseParts.empty() ) {
- std::vector<std::string> current;
- current.insert(current.begin(), parts.begin(), parts.end());
- // TODO debug g_message(" ---{%s}", Glib::build_filename( baseParts ).c_str());
- while ( !exists && !current.empty() ) {
- std::vector<std::string> combined;
- combined.insert( combined.end(), baseParts.begin(), baseParts.end() );
- combined.insert( combined.end(), current.begin(), current.end() );
- std::string filepath = Glib::build_filename( combined );
- exists = Glib::file_test(filepath, Glib::FILE_TEST_EXISTS);
- // TODO debug g_message(" ...[%s] %s", filepath.c_str(), (exists ? "XXX" : ""));
- if ( exists ) {
- dest = filepath;
- }
- current.erase( current.begin() );
- }
- baseParts.pop_back();
- }
-
- return exists;
-}
-
-
-static ResourceManagerImpl* theInstance = nullptr;
-
-ResourceManager::ResourceManager()
- : Glib::Object()
-{
-}
-
-ResourceManager::~ResourceManager() = default;
-
-ResourceManager& ResourceManager::getManager() {
- if ( !theInstance ) {
- theInstance = new ResourceManagerImpl();
- }
-
- return *theInstance;
-}
-
-
-} // namespace Inkscape
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :