Commit 5cb8696d authored by Hugo Lefeuvre's avatar Hugo Lefeuvre Committed by Philippe Gorley

conversationsview: various bugs, modern C++, leaks

Fix a bunch of newly discovered memory leaks, port some code parts
using C-style fixed-length buffers to modern C++ and check call
status before displaying it as last interaction.

Change-Id: I6114585e80411717e89990653eff26bf7fc49de5
Reviewed-by: Philippe Gorley's avatarPhilippe Gorley <philippe.gorley@savoirfairelinux.com>
parent 55d24730
......@@ -2,6 +2,7 @@
* Copyright (C) 2017-2018 Savoir-faire Linux *
* Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com> *
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com> *
* Author: Hugo Lefeuvre <hugo.lefeuvre@savoirfairelinux.com> *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
......@@ -21,6 +22,10 @@
// std
#include <algorithm>
#include <chrono>
#include <iomanip> // for std::put_time
#include <string>
#include <sstream>
// GTK+ related
#include <QSize>
......@@ -104,11 +109,7 @@ render_contact_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
g_object_set(G_OBJECT(cell), "pixbuf", image.get(), NULL);
// Banned contacts should be displayed with grey bg
if (contactInfo.isBanned) {
g_object_set(G_OBJECT(cell), "cell-background", "#BDBDBD", NULL);
} else {
g_object_set(G_OBJECT(cell), "cell-background", NULL, NULL);
}
g_object_set(G_OBJECT(cell), "cell-background", contactInfo.isBanned ? "#BDBDBD" : NULL, NULL);
}
catch (const std::exception&)
{
......@@ -182,13 +183,10 @@ render_name_and_last_interaction(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
}
// Banned contacts should be displayed with grey bg
if (contactInfo.isBanned) {
g_object_set(G_OBJECT(cell), "cell-background", "#BDBDBD", NULL);
} else {
g_object_set(G_OBJECT(cell), "cell-background", NULL, NULL);
}
g_object_set(G_OBJECT(cell), "cell-background", contactInfo.isBanned ? "#BDBDBD" : NULL, NULL);
g_object_set(G_OBJECT(cell), "markup", text, NULL);
g_free(text);
g_free(uid);
g_free(uri);
g_free(alias);
......@@ -202,64 +200,54 @@ render_time(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
GtkTreeIter *iter,
G_GNUC_UNUSED GtkTreeView *treeview)
{
g_return_if_fail(IS_CONVERSATIONS_VIEW(treeview));
auto priv = CONVERSATIONS_VIEW_GET_PRIVATE(treeview);
g_return_if_fail(priv);
// Get active conversation
auto path = gtk_tree_model_get_path(model, iter);
auto row = std::atoi(gtk_tree_path_to_string(path));
if (row == -1) return;
auto priv = CONVERSATIONS_VIEW_GET_PRIVATE(treeview);
if (!priv) return;
char empty[] = {'\0'};
gchar *text = empty;
g_return_if_fail(row != -1);
try
{
try {
auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(row);
auto contactUri = conversation.participants.front();
auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri);
auto& contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri);
// Banned contacts should be displayed with grey bg
if (contactInfo.isBanned) {
g_object_set(G_OBJECT(cell), "cell-background", "#BDBDBD", NULL);
} else {
g_object_set(G_OBJECT(cell), "cell-background", NULL, NULL);
}
g_object_set(G_OBJECT(cell), "cell-background", contactInfo.isBanned ? "#BDBDBD" : NULL, NULL);
auto callId = conversation.confId.empty() ? conversation.callId : conversation.confId;
if (!callId.empty()) {
auto call = (*priv->accountInfo_)->callModel->getCall(callId);
text = g_markup_printf_escaped("%s",
lrc::api::call::to_string(call.status).c_str()
);
} else if (conversation.interactions.empty()) {
} else {
auto lastUid = conversation.lastMessageUid;
if (conversation.interactions.find(lastUid) == conversation.interactions.end()) {
} else {
std::time_t lastInteractionTimestamp = conversation.interactions[lastUid].timestamp;
std::time_t now = std::time(nullptr);
char interactionDay[100];
char nowDay[100];
std::strftime(interactionDay, sizeof(interactionDay), "%x", std::localtime(&lastInteractionTimestamp));
std::strftime(nowDay, sizeof(nowDay), "%x", std::localtime(&now));
if (std::string(interactionDay) == std::string(nowDay)) {
char interactionTime[100];
std::strftime(interactionTime, sizeof(interactionTime), "%R", std::localtime(&lastInteractionTimestamp));
text = g_markup_printf_escaped("<span size=\"smaller\" color=\"#666\">%s</span>", &interactionTime[0]);
} else {
text = g_markup_printf_escaped("<span size=\"smaller\" color=\"#666\">%s</span>", &interactionDay[0]);
}
if (call.status != lrc::api::call::Status::ENDED) {
g_object_set(G_OBJECT(cell), "markup", lrc::api::call::to_string(call.status).c_str(), NULL);
return;
}
}
}
catch (const std::exception&)
{
auto& interactions = conversation.interactions;
auto lastUid = conversation.lastMessageUid;
if (!interactions.empty() && interactions.find(lastUid) != interactions.end()) {
std::time_t lastTimestamp = interactions[lastUid].timestamp;
std::chrono::time_point<std::chrono::system_clock> lastTs = std::chrono::system_clock::from_time_t(lastTimestamp);
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
std::chrono::hours diff = std::chrono::duration_cast<std::chrono::hours>(now - lastTs);
std::stringstream timestamp;
timestamp << std::put_time(std::localtime(&lastTimestamp), diff.count() < 24 ? "%R" : "%x");
gchar* text = g_markup_printf_escaped("<span size=\"smaller\" color=\"#666\">%s</span>", timestamp.str().c_str());
g_object_set(G_OBJECT(cell), "markup", text, NULL);
g_free(text);
return;
}
} catch (const std::exception&) {
g_warning("Can't get conversation at row %i", row);
}
g_object_set(G_OBJECT(cell), "markup", text, NULL);
g_object_set(G_OBJECT(cell), "markup", "", NULL);
}
void
......@@ -525,7 +513,7 @@ on_drag_data_received(GtkWidget *treeview,
g_debug("source path: %s", path_str_source);
/* get the destination path */
GtkTreePath *dest_path = NULL;
GtkTreePath *dest_path = nullptr;
if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(treeview), x, y, &dest_path, NULL)) {
auto model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
......@@ -549,6 +537,10 @@ on_drag_data_received(GtkWidget *treeview,
);
gtk_tree_path_free(dest_path);
g_free(conversationUidSrc);
g_free(conversationUidDest);
success = TRUE;
}
}
......@@ -637,7 +629,7 @@ build_conversations_view(ConversationsView *self)
priv->callChangedConnection_ = QObject::connect(
&*(*priv->accountInfo_)->callModel,
&lrc::api::NewCallModel::callStatusChanged,
[self, priv] (const std::string& callId) {
[self, priv] (const std::string&) {
// retrieve currently selected conversation
GtkTreeIter iter;
GtkTreeModel *model = nullptr;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment