gui2/tchat_log: Refactor log formatting and page extents calculation

This functionality will be shared with a new Copy to Clipboard button
and its callback in the next commit, so it has to be refactored so that
we don't wind up with duplicate code. This is also why
gui2::tchat_log::model::stream_log() now has a 'raw' parameter which
defaults to 'false'.

I couldn't resist the temptation so I added some const specifications to
a few write-once variables, in particular those that ended up in
gui2::tchat_log::controller::calculate_log_line_range().

While I didn't change any existing behavior (to my knowledge, anyway), I
changed the algorithm for the 'count_of_pages' value as follows:

  // Before:
  count_of_pages = model_.count_of_pages() != 0
                   ? model_.count_of_pages()
                   : 1;
  // After:
  count_of_pages = model_.count_of_pages() >= 1
                  ? model_.count_of_pages()
                  : 1;

I don't believe model_.count_of_pages() can yield a value less than
zero, so this shouldn't alter the previous behavior in practice.
This commit is contained in:
Ignacio R. Morelle 2014-06-11 20:17:10 -04:00
parent 474f30c759
commit 16e642b654

View file

@ -104,54 +104,93 @@ public:
: (size / COUNT_PER_PAGE) + 1;
}
void populate_chat_message_list(int first, int last)
void stream_log(std::ostringstream& s,
int first,
int last,
bool raw = false)
{
if(first >= last) {
return;
}
const std::string& lcfilter = utils::lowercase(filter->get_value());
std::stringstream str;
LOG_CHAT_LOG
<< "entering tchat_log::model::add_row_to_chat_message_list\n";
if(first < last) {
FOREACH(const AUTO & t,
make_pair(chat_log_history.begin() + first,
chat_log_history.begin() + last))
{
LOG_CHAT_LOG << "entering tchat_log::model::stream_log\n";
const std::string& timestamp
= preferences::get_chat_timestamp(t.time());
FOREACH(const AUTO & t, make_pair(chat_log_history.begin() + first,
chat_log_history.begin() + last))
{
const std::string& timestamp
= preferences::get_chat_timestamp(t.time());
if(lcfilter.empty() == false) {
const std::string& lcsample = utils::lowercase(timestamp)
+ utils::lowercase(t.nick())
+ utils::lowercase(t.text());
if(!lcfilter.empty()) {
const std::string& lcsample = utils::lowercase(timestamp)
+ utils::lowercase(t.nick())
+ utils::lowercase(t.text());
if(lcsample.find(lcfilter) == std::string::npos) {
continue;
}
}
std::string prefix("/me");
bool me = false;
if(!t.text().compare(0, prefix.size(), prefix)) {
me = true;
}
const std::string& color = t.color();
std::string nick_prefix = "<span color=\"" + color + "\">";
std::string nick_suffix = "</span> ";
if(me) {
str << nick_prefix << "&lt;" << font::escape_text(timestamp)
<< font::escape_text(t.nick())
<< font::escape_text(t.text().substr(3)) << "&gt;"
<< nick_suffix << std::endl;
} else {
str << nick_prefix << "&lt;" << font::escape_text(timestamp)
<< font::escape_text(t.nick()) << "&gt;" << nick_suffix
<< font::escape_text(t.text()) << std::endl;
if(lcsample.find(lcfilter) == std::string::npos) {
continue;
}
}
const std::string me_prefix = "/me";
const bool is_me = t.text().compare(0, me_prefix.size(),
me_prefix) == 0;
std::string nick_prefix, nick_suffix;
if(!raw) {
nick_prefix = "<span color=\"" + t.color() + "\">";
nick_suffix = "</span> ";
} else {
nick_suffix = " ";
}
const std::string lbracket = raw ? "<" : "&lt;";
const std::string rbracket = raw ? ">" : "&gt;";
//
// Chat line format:
//
// is_me == true: "<[TS] nick message text here>\n"
// is_me == false: "<[TS] nick> message text here\n"
//
s << nick_prefix << lbracket;
if(raw) {
s << timestamp
<< t.nick();
} else {
s << font::escape_text(timestamp)
<< font::escape_text(t.nick());
}
if(is_me) {
if(!raw) {
s << font::escape_text(t.text().substr(3));
} else {
s << t.text().substr(3);
}
s << rbracket << nick_suffix;
} else {
// <[TS] nick> message text here
s << rbracket << nick_suffix;
if(!raw) {
s << font::escape_text(t.text());
} else {
s << t.text();
}
}
s << '\n';
}
msg_label->set_label(str.str());
LOG_CHAT_LOG
<< "exited tchat_log::model::add_row_to_chat_message_list\n";
}
void populate_chat_message_list(int first, int last)
{
std::ostringstream s;
stream_log(s, first, last);
msg_label->set_label(s.str());
}
};
@ -214,6 +253,27 @@ public:
<< std::endl;
}
std::pair<int, int> calculate_log_line_range()
{
const int log_size = model_.chat_log_history.size();
const int page_size = model_.COUNT_PER_PAGE;
const int page = model_.page;
const int count_of_pages = std::max(1, model_.count_of_pages());
LOG_CHAT_LOG << "Page: " << page + 1 << " of " << count_of_pages
<< '\n';
const int first = page * page_size;
const int last = page < (count_of_pages - 1)
? first + page_size
: log_size;
LOG_CHAT_LOG << "First " << first << ", last " << last << '\n';
return std::make_pair(first, last);
}
void update_view_from_model()
{
LOG_CHAT_LOG << "Entering tchat_log::controller::update_view_from_model"
@ -222,20 +282,13 @@ public:
int size = model_.chat_log_history.size();
LOG_CHAT_LOG << "Number of chat messages: " << size << std::endl;
// get page
int page = model_.page;
const int page = model_.page;
// determine count of pages
int count_of_pages = model_.count_of_pages();
if(count_of_pages == 0) {
count_of_pages = 1;
}
LOG_CHAT_LOG << "Page: " << page + 1 << " of " << count_of_pages
<< std::endl;
// determine first
int first = model_.page * model_.COUNT_PER_PAGE;
// determine last
int last = (page < count_of_pages - 1) ? first + model_.COUNT_PER_PAGE
: size;
LOG_CHAT_LOG << "First " << first << ", last " << last << std::endl;
const int count_of_pages = std::max(1, model_.count_of_pages());
// determine first and last
const std::pair<int, int>& range = calculate_log_line_range();
const int first = range.first;
const int last = range.second;
// determine has previous, determine has next
bool has_next = page + 1 < count_of_pages;
bool has_previous = page > 0;