Store discontinuous selections as multiple strings on clipboard

This commit is contained in:
Allan Odgaard
2020-04-12 21:32:16 +07:00
parent 34eb6967c8
commit f2efe71aff
3 changed files with 37 additions and 14 deletions

View File

@@ -21,7 +21,14 @@ static clipboard_t::entry_ptr to_entry (OakPasteboardEntry* src, BOOL includeFin
map["ignoreCase"] = [[NSUserDefaults standardUserDefaults] boolForKey:kUserDefaultsFindIgnoreCase] ? "1" : "0";
}
return std::make_shared<clipboard_t::entry_t>(to_s(src.string), map);
std::vector<std::string> contents;
for(NSString* str in src.strings)
contents.push_back(to_s(str));
if(contents.size() > 1)
map[kClipboardOptionFragments] = std::to_string(contents.size());
return std::make_shared<clipboard_t::entry_t>(contents, map);
}
struct oak_pasteboard_t : clipboard_t
@@ -38,7 +45,12 @@ struct oak_pasteboard_t : clipboard_t
entry_ptr current () const { return to_entry([pasteboard current], includeFindOptions); }
entry_ptr next () { return to_entry([pasteboard next], includeFindOptions); }
void push_back (entry_ptr entry) { [pasteboard addEntryWithString:[NSString stringWithCxxString:entry->content()] options:(__bridge NSDictionary*)((CFDictionaryRef)cf::wrap(entry->options()))]; }
void push_back (entry_ptr entry)
{
if(OakPasteboardEntry* res = [pasteboard addEntryWithStrings:(__bridge NSArray*)((CFArrayRef)cf::wrap(entry->contents())) options:(__bridge NSDictionary*)((CFDictionaryRef)cf::wrap(entry->options()))])
[pasteboard updatePasteboardWithEntry:res];
}
private:
OakPasteboard* pasteboard;
BOOL includeFindOptions;

View File

@@ -8,29 +8,38 @@ std::string const kClipboardOptionComplete = "complete";
std::string const kClipboardOptionFragments = "fragments";
std::string const kClipboardOptionColumnar = "columnar";
clipboard_t::entry_t::entry_t (std::string const& content, std::map<std::string, std::string> const& options) : _content(content), _options(options)
clipboard_t::entry_t::entry_t (std::string const& content, std::map<std::string, std::string> const& options) : _contents(1, content), _options(options)
{
if(!utf8::is_valid(_content.begin(), _content.end()))
{
std::string const prefix = "*** malformed UTF-8 data on clipboard:\n";
_content = prefix + text::to_hex(_content.begin(), _content.end()) + "\n";
}
}
static std::map<std::string, std::string> create_clipboard_options (std::string const& indent, bool complete, size_t fragments, bool columnar)
clipboard_t::entry_t::entry_t (std::vector<std::string> const& contents, std::map<std::string, std::string> const& options) : _contents(contents), _options(options)
{
}
static std::map<std::string, std::string> create_clipboard_options (std::string const& indent, bool complete, bool columnar)
{
std::map<std::string, std::string> res;
if(indent != NULL_STR) res[kClipboardOptionIndent] = indent;
if(complete) res[kClipboardOptionComplete] = "1";
if(fragments > 1) res[kClipboardOptionFragments] = std::to_string(fragments);
if(columnar) res[kClipboardOptionColumnar] = "1";
return res;
}
clipboard_t::entry_t::entry_t (std::vector<std::string> const& contents, std::string const& indent, bool complete, bool columnar) : entry_t(text::join(contents, "\n"), create_clipboard_options(indent, complete, contents.size(), columnar))
clipboard_t::entry_t::entry_t (std::vector<std::string> const& contents, std::string const& indent, bool complete, bool columnar) : entry_t(contents, create_clipboard_options(indent, complete, columnar))
{
}
std::string clipboard_t::entry_t::content () const
{
std::string res = _contents.size() == 1 ? _contents.back() : text::join(_contents, "\n");
if(!utf8::is_valid(res.begin(), res.end()))
{
std::string const prefix = "*** malformed UTF-8 data on clipboard:\n";
res = prefix + text::to_hex(res.begin(), res.end()) + "\n";
}
return res;
}
struct simple_clipboard_t : clipboard_t
{
simple_clipboard_t () : _index(0) { }

View File

@@ -12,13 +12,15 @@ struct PUBLIC clipboard_t
{
struct PUBLIC entry_t
{
entry_t (std::string const& content, std::map<std::string, std::string> const& options = { });
entry_t (std::vector<std::string> const& contents, std::map<std::string, std::string> const& options = { });
entry_t (std::vector<std::string> const& contents, std::string const& indent, bool complete, bool columnar);
entry_t (std::string const& content, std::map<std::string, std::string> const& options = { });
~entry_t () { }
std::string const& content () const { return _content; }
std::string content () const;
std::vector<std::string> const& contents () const { return _contents; }
std::map<std::string, std::string> const& options () const { return _options; }
private:
std::string _content;
std::vector<std::string> _contents;
std::map<std::string, std::string> _options;
};