From 3d8dd56e9d2827f85286473b753f1f2d10334e67 Mon Sep 17 00:00:00 2001 From: Alex Zolotarev Date: Sun, 2 Sep 2012 23:17:46 +0300 Subject: [PATCH] [bookmarks] Added file save/load methods --- map/bookmark.cpp | 51 ++++++++++++++++++++++++++++++++ map/bookmark.hpp | 9 ++++++ map/map_tests/bookmarks_test.cpp | 9 ++++++ 3 files changed, 69 insertions(+) diff --git a/map/bookmark.cpp b/map/bookmark.cpp index a15af9788e..7cd34ebf0a 100644 --- a/map/bookmark.cpp +++ b/map/bookmark.cpp @@ -2,11 +2,15 @@ #include "../indexer/mercator.hpp" +#include "../platform/platform.hpp" + +#include "../coding/file_reader.hpp" #include "../coding/parse_xml.hpp" // LoadFromKML #include "../base/stl_add.hpp" #include "../base/string_utils.hpp" +#include "../std/fstream.hpp" #include "../std/algorithm.hpp" @@ -169,6 +173,23 @@ void BookmarkCategory::LoadFromKML(ReaderPtr const & reader) ParseXML(src, parser, true); } +BookmarkCategory * BookmarkCategory::CreateFromKMLFile(string const & file) +{ + BookmarkCategory * cat = new BookmarkCategory(""); + try + { + cat->LoadFromKML(new FileReader(file)); + cat->m_file = file; + } + catch (std::exception const & e) + { + LOG(LWARNING, ("Error while loading bookmarks from", file, e.what())); + delete cat; + cat = 0; + } + return cat; +} + namespace { char const * kmlHeader = @@ -265,3 +286,33 @@ void BookmarkCategory::SaveToKML(ostream & s) s << kmlFooter; } + +bool BookmarkCategory::SaveToKMLFileAtPath(string const & path) +{ + if (m_file.empty()) + { + // Generate unique file name from category name + string newName = m_name + ".kml"; + // Remove not allowed symbols + char const illegalChars[] = ":/"; + for (size_t i = 0; i < ARRAY_SIZE(illegalChars); ++i) + newName.erase(std::remove(newName.begin(), newName.end(), illegalChars[i]), newName.end()); + if (newName.empty()) + newName = "Bookmarks"; + while (Platform::IsFileExistsByFullPath(path + newName)) + newName.append(strings::to_string(m_name.size())); + m_file = path + newName; + } + try + { + // @TODO On Windows UTF-8 file names are not supported. + ofstream fileToSave(m_file.c_str()); + SaveToKML(fileToSave); + } + catch (std::exception const & e) + { + LOG(LWARNING, ("Can't save bookmarks catebory", m_name, "to file", m_file)); + return false; + } + return true; +} diff --git a/map/bookmark.hpp b/map/bookmark.hpp index 9e23d69e9e..b529bd0797 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -36,6 +36,8 @@ class BookmarkCategory : private noncopyable string m_name; vector m_bookmarks; bool m_visible; + /// Stores file name from which category was loaded + string m_file; public: BookmarkCategory(string const & name) : m_name(name), m_visible(true) {} @@ -49,6 +51,7 @@ public: bool IsVisible() const { return m_visible; } void SetName(string const & name) { m_name = name; } string GetName() const { return m_name; } + string GetFileName() const { return m_file; } inline size_t GetBookmarksCount() const { return m_bookmarks.size(); } Bookmark const * GetBookmark(size_t index) const; @@ -56,6 +59,12 @@ public: void LoadFromKML(ReaderPtr const & reader); void SaveToKML(ostream & s); + /// @return 0 in the case of error + static BookmarkCategory * CreateFromKMLFile(string const & file); + /// Uses the same file name from which was loaded, or + /// creates unique file name on first save and uses it every time + /// @param[in] path directory name where to save + bool SaveToKMLFileAtPath(string const & path); }; /// Non-const category is needed to "edit" bookmark (actually, re-add it) diff --git a/map/map_tests/bookmarks_test.cpp b/map/map_tests/bookmarks_test.cpp index 90ad3b9cc0..ed62cba27f 100644 --- a/map/map_tests/bookmarks_test.cpp +++ b/map/map_tests/bookmarks_test.cpp @@ -149,6 +149,15 @@ UNIT_TEST(Bookmarks_ExportKML) CheckBookmarks(cat); TEST_EQUAL(cat.IsVisible(), true, ()); + BookmarkCategory * cat2 = BookmarkCategory::CreateFromKMLFile(BOOKMARKS_FILE_NAME); + CheckBookmarks(*cat2); + FileWriter::DeleteFileX(BOOKMARKS_FILE_NAME); + + cat2->SaveToKMLFileAtPath("./"); + delete cat2; + + cat2 = BookmarkCategory::CreateFromKMLFile(BOOKMARKS_FILE_NAME); + CheckBookmarks(*cat2); FileWriter::DeleteFileX(BOOKMARKS_FILE_NAME); }