mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
shift relationship ids down by one after deleting one to maintain contiguity, fixes #104
This commit is contained in:
parent
e9c8116b0d
commit
44b11d342c
|
@ -102,9 +102,12 @@ public:
|
|||
std::string register_relationship(const class relationship &rel);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Delete the relationship with the given id from source part. Returns a mapping
|
||||
/// of relationship IDs since IDs are shifted down. For example, if there are three
|
||||
/// relationships for part a.xml like [rId1, rId2, rId3] and rId2 is deleted, the
|
||||
/// resulting map would look like [rId3->rId2].
|
||||
/// </summary>
|
||||
void unregister_relationship(const uri &source, const std::string &rel_id);
|
||||
std::unordered_map<std::string, std::string> unregister_relationship(const uri &source, const std::string &rel_id);
|
||||
|
||||
// Content Types
|
||||
|
||||
|
|
|
@ -227,9 +227,38 @@ std::string manifest::register_relationship(const class relationship &rel)
|
|||
return rel.id();
|
||||
}
|
||||
|
||||
void manifest::unregister_relationship(const uri &source, const std::string &rel_id)
|
||||
std::unordered_map<std::string, std::string> manifest::unregister_relationship(const uri &source, const std::string &rel_id)
|
||||
{
|
||||
relationships_.at(source.path()).erase(rel_id);
|
||||
// This shouldn't happen, but just in case...
|
||||
if (rel_id.substr(0, 3) != "rId" || rel_id.size() < 4)
|
||||
{
|
||||
throw xlnt::invalid_parameter();
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> id_map;
|
||||
auto rel_index = static_cast<std::size_t>(std::stoull(rel_id.substr(3)));
|
||||
auto &part_rels = relationships_.at(source.path());
|
||||
|
||||
for (auto i = rel_index; i <= part_rels.size() + 1; ++i)
|
||||
{
|
||||
auto old_id = "rId" + std::to_string(i);
|
||||
|
||||
// Don't re-add the relationship to be deleted
|
||||
if (i > rel_index)
|
||||
{
|
||||
// Shift all relationships with IDs greater than the deleted one
|
||||
// down by one (e.g. rId7->rId6).
|
||||
auto new_id = "rId" + std::to_string(i - 1);
|
||||
const auto &old_rel = part_rels.at(old_id);
|
||||
register_relationship(xlnt::relationship(new_id, old_rel.type(),
|
||||
old_rel.source(), old_rel.target(), old_rel.target_mode()));
|
||||
id_map[old_id] = new_id;
|
||||
}
|
||||
|
||||
part_rels.erase(old_id);
|
||||
}
|
||||
|
||||
return id_map;
|
||||
}
|
||||
|
||||
bool manifest::has_default_type(const std::string &extension) const
|
||||
|
|
|
@ -799,10 +799,16 @@ void workbook::remove_sheet(worksheet ws)
|
|||
auto wb_rel = d_->manifest_.relationship(xlnt::path("/"), xlnt::relationship_type::office_document);
|
||||
auto ws_rel = d_->manifest_.relationship(wb_rel.target().path(), ws_rel_id);
|
||||
d_->manifest_.unregister_override_type(ws_rel.target().path());
|
||||
d_->manifest_.unregister_relationship(wb_rel.target(), ws_rel_id);
|
||||
;
|
||||
auto rel_id_map = d_->manifest_.unregister_relationship(wb_rel.target(), ws_rel_id);
|
||||
d_->sheet_title_rel_id_map_.erase(ws.title());
|
||||
d_->worksheets_.erase(match_iter);
|
||||
|
||||
// Shift sheet title->ID mappings down as a result of manifest::unregister_relationship above.
|
||||
for (auto &title_rel_id_pair : d_->sheet_title_rel_id_map_)
|
||||
{
|
||||
title_rel_id_pair.second = rel_id_map.count(title_rel_id_pair.second) > 0
|
||||
? rel_id_map[title_rel_id_pair.second] : title_rel_id_pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
worksheet workbook::create_sheet(std::size_t index)
|
||||
|
|
Loading…
Reference in New Issue
Block a user