diff --git a/src/conversationpopupmenu.cpp b/src/conversationpopupmenu.cpp index 1a232e923cb1caa8d851b499415c3afeb9f8d358..082f01d78c9b924ddfbf8cb3cdce29231eb21665 100644 --- a/src/conversationpopupmenu.cpp +++ b/src/conversationpopupmenu.cpp @@ -33,6 +33,10 @@ // Qt #include <QItemSelectionModel> +namespace { namespace details { +class CppImpl; +}} + struct _ConversationPopupMenu { GtkMenu parent; @@ -50,18 +54,30 @@ struct _ConversationPopupMenuPrivate GtkTreeView *treeview; AccountInfoPointer const *accountInfo_; - int row_; + details::CppImpl* cpp {nullptr}; }; G_DEFINE_TYPE_WITH_PRIVATE(ConversationPopupMenu, conversation_popup_menu, GTK_TYPE_MENU); #define CONVERSATION_POPUP_MENU_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CONVERSATION_POPUP_MENU_TYPE, ConversationPopupMenuPrivate)) +namespace { namespace details { +class CppImpl +{ +public: + explicit CppImpl(); + QString uid_; +}; +CppImpl::CppImpl() + : uid_("") +{} +}} + static void show_profile(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* priv) { - if (!priv) return; - auto *profile = profile_view_new(*priv->accountInfo_, priv->row_); + if (!priv or !priv->cpp) return; + auto *profile = profile_view_new(*priv->accountInfo_, priv->cpp->uid_); if (profile) gtk_widget_show_all(GTK_WIDGET(profile)); } @@ -70,12 +86,13 @@ remove_history_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenu { try { - auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_); + if (!priv->cpp) return; + auto conversation = (*priv->accountInfo_)->conversationModel->getConversationForUID(priv->cpp->uid_); (*priv->accountInfo_)->conversationModel->clearHistory(conversation.uid); } catch (...) { - g_warning("Can't get conversation at row %i", priv->row_); + g_warning("Can't get conversation %s", priv->cpp? priv->cpp->uid_.toStdString().c_str() : ""); } } @@ -84,12 +101,12 @@ remove_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* { try { - auto conversationUid = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_).uid; - (*priv->accountInfo_)->conversationModel->removeConversation(conversationUid); + if (!priv->cpp) return; + (*priv->accountInfo_)->conversationModel->removeConversation(priv->cpp->uid_); } catch (...) { - g_warning("Can't get conversation at row %i", priv->row_); + g_warning("Can't get conversation %s", priv->cpp? priv->cpp->uid_.toStdString().c_str() : ""); } } @@ -98,7 +115,8 @@ unblock_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate { try { - auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_); + if (!priv->cpp) return; + auto conversation = (*priv->accountInfo_)->conversationModel->getConversationForUID(priv->cpp->uid_); auto uri = conversation.participants[0]; auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(uri); @@ -112,7 +130,7 @@ unblock_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate } catch (...) { - g_warning("Can't get conversation at row %i", priv->row_); + g_warning("Can't get conversation %s", priv->cpp? priv->cpp->uid_.toStdString().c_str() : ""); } } @@ -121,12 +139,12 @@ block_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* { try { - auto conversationUid = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_).uid; - (*priv->accountInfo_)->conversationModel->removeConversation(conversationUid, true); + if (!priv->cpp) return; + (*priv->accountInfo_)->conversationModel->removeConversation(priv->cpp->uid_, true); } catch (...) { - g_warning("Can't get conversation at row %i", priv->row_); + g_warning("Can't get conversation %s", priv->cpp? priv->cpp->uid_.toStdString().c_str() : ""); } } @@ -135,12 +153,12 @@ add_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* pr { try { - auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_); - (*priv->accountInfo_)->conversationModel->makePermanent(conversation.uid); + if (!priv->cpp) return; + (*priv->accountInfo_)->conversationModel->makePermanent(priv->cpp->uid_); } catch (...) { - g_warning("Can't get conversation at row %i", priv->row_); + g_warning("Can't get conversation %s", priv->cpp? priv->cpp->uid_.toStdString().c_str() : ""); } } @@ -149,10 +167,11 @@ place_video_call(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* pr { try { - auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_); + if (!priv->cpp) return; + auto conversation = (*priv->accountInfo_)->conversationModel->getConversationForUID(priv->cpp->uid_); (*priv->accountInfo_)->conversationModel->placeCall(conversation.uid); } catch (...) { - g_warning("Can't get conversation at row %i", priv->row_); + g_warning("Can't get conversation %s", priv->cpp? priv->cpp->uid_.toStdString().c_str() : ""); } } @@ -161,10 +180,11 @@ place_audio_call(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* pr { try { - auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_); + if (!priv->cpp) return; + auto conversation = (*priv->accountInfo_)->conversationModel->getConversationForUID(priv->cpp->uid_); (*priv->accountInfo_)->conversationModel->placeAudioOnlyCall(conversation.uid); } catch (...) { - g_warning("Can't get conversation at row %i", priv->row_); + g_warning("Can't get conversation %s", priv->cpp? priv->cpp->uid_.toStdString().c_str() : ""); } } @@ -182,13 +202,24 @@ update(GtkTreeSelection *selection, ConversationPopupMenu *self) GtkTreeIter iter; GtkTreeModel *model; if (!gtk_tree_selection_get_selected(selection, &model, &iter)) return; - auto path = gtk_tree_model_get_path(model, &iter); - auto idx = gtk_tree_path_get_indices(path); - auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(idx[0]); - priv->row_ = idx[0]; + + gchar *uid; + gtk_tree_model_get (model, &iter, + 0 /* col# */, &uid /* data */, + -1); + + auto conversation = (*priv->accountInfo_)->conversationModel->getConversationForUID(uid); + if (priv->cpp) priv->cpp->uid_ = uid; try { + if (conversation.participants.isEmpty()) { + g_free(uid); + return; + } auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(conversation.participants.front()); - if (contactInfo.profileInfo.uri.isEmpty()) return; + if (contactInfo.profileInfo.uri.isEmpty()) { + g_free(uid); + return; + } // we always build a menu, however in some cases some or all of the conversations will be deactivated // we prefer this to having an empty menu because GTK+ behaves weird in the empty menu case @@ -248,11 +279,16 @@ update(GtkTreeSelection *selection, ConversationPopupMenu *self) } catch (const std::out_of_range&) { // ContactModel::getContact() exception } + + g_free(uid); } static void conversation_popup_menu_dispose(GObject *object) { + auto* priv = CONVERSATION_POPUP_MENU_GET_PRIVATE(object); + delete priv->cpp; + priv->cpp = nullptr; G_OBJECT_CLASS(conversation_popup_menu_parent_class)->dispose(object); } @@ -284,6 +320,7 @@ conversation_popup_menu_new (GtkTreeView *treeview, AccountInfoPointer const & a priv->accountInfo_ = &accountInfo; priv->treeview = treeview; + priv->cpp = new details::CppImpl(); GtkTreeSelection *selection = gtk_tree_view_get_selection(priv->treeview); // build the menu for the first time diff --git a/src/conversationsview.cpp b/src/conversationsview.cpp index ee1d97f072af4d0b9561fff31527e65824972590..4e02566173361193cb7f58c2c1e75a0870659cfa 100644 --- a/src/conversationsview.cpp +++ b/src/conversationsview.cpp @@ -57,6 +57,10 @@ struct _ConversationsViewClass typedef struct _ConversationsViewPrivate ConversationsViewPrivate; +namespace { namespace details { +class CppImpl; +}} + struct _ConversationsViewPrivate { AccountInfoPointer const *accountInfo_; @@ -64,10 +68,13 @@ struct _ConversationsViewPrivate GtkWidget* popupMenu_; bool useDarkTheme {false}; + details::CppImpl* cpp {nullptr}; QMetaObject::Connection selection_updated; QMetaObject::Connection layout_changed; QMetaObject::Connection modelSortedConnection_; + QMetaObject::Connection searchChangedConnection_; + QMetaObject::Connection searchStatusChangedConnection_; QMetaObject::Connection conversationUpdatedConnection_; QMetaObject::Connection filterChangedConnection_; QMetaObject::Connection callChangedConnection_; @@ -77,6 +84,22 @@ G_DEFINE_TYPE_WITH_PRIVATE(ConversationsView, conversations_view, GTK_TYPE_TREE_ #define CONVERSATIONS_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CONVERSATIONS_VIEW_TYPE, ConversationsViewPrivate)) +namespace { namespace details { + +class CppImpl +{ +public: + explicit CppImpl(); + + QString status; +}; + +CppImpl::CppImpl() + : status("") +{} + +}} + static void render_contact_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, @@ -90,18 +113,30 @@ render_contact_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column, if (row == -1) return; auto priv = CONVERSATIONS_VIEW_GET_PRIVATE(self); if (!priv) return; + gchar *uid; + + gtk_tree_model_get (model, iter, + 0 /* col# */, &uid /* data */, + -1); + try { // Draw first contact. // NOTE: We just draw the first contact, must change this for conferences when they will have their own object - auto conversationInfo = (*priv->accountInfo_)->conversationModel->filteredConversation(row); - auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(conversationInfo.participants.front()); + auto conversation = (*priv->accountInfo_)->conversationModel->getConversationForUID(uid); + auto isPresent = false; + auto isBanned = false; + if (not conversation.participants.empty()) { + auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(conversation.participants.front()); + isPresent = contactInfo.isPresent; + isBanned = contactInfo.isBanned; + } std::shared_ptr<GdkPixbuf> image; auto var_photo = GlobalInstances::pixmapManipulator().conversationPhoto( - conversationInfo, + conversation, **(priv->accountInfo_), QSize(50, 50), - contactInfo.isPresent + isPresent ); image = var_photo.value<std::shared_ptr<GdkPixbuf>>(); @@ -111,12 +146,14 @@ 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 - g_object_set(G_OBJECT(cell), "cell-background", contactInfo.isBanned ? "#BDBDBD" : NULL, NULL); + g_object_set(G_OBJECT(cell), "cell-background", isBanned ? "#BDBDBD" : NULL, NULL); } catch (const std::exception&) { g_warning("Can't get conversation at row %i", row); } + + g_free(uid); } static void @@ -141,10 +178,6 @@ render_name_and_last_interaction(G_GNUC_UNUSED GtkTreeViewColumn *tree_column, auto priv = CONVERSATIONS_VIEW_GET_PRIVATE(treeview); if (!priv) return; - auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(row); - auto contactUri = conversation.participants.front(); - auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri); - auto grey = priv->useDarkTheme? "#bbb" : "#666"; gtk_tree_model_get (model, iter, @@ -156,7 +189,16 @@ render_name_and_last_interaction(G_GNUC_UNUSED GtkTreeViewColumn *tree_column, -1); auto bestId = std::string(registeredName).empty() ? uri: registeredName; - if (contactInfo.isBanned) { + + auto conversation = (*priv->accountInfo_)->conversationModel->getConversationForUID(uid); + auto isBanned = false; + if (not conversation.participants.empty()) { + auto contactUri = conversation.participants.front(); + auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri); + isBanned = contactInfo.isBanned; + } + + if (isBanned) { // Contact is banned, display it clearly text = g_markup_printf_escaped( "<span font_weight=\"bold\">%s</span>\n<span size=\"smaller\" font_weight=\"bold\">Banned contact</span>", @@ -191,7 +233,7 @@ render_name_and_last_interaction(G_GNUC_UNUSED GtkTreeViewColumn *tree_column, } // Banned contacts should be displayed with grey bg - g_object_set(G_OBJECT(cell), "cell-background", contactInfo.isBanned ? "#BDBDBD" : NULL, NULL); + g_object_set(G_OBJECT(cell), "cell-background", isBanned ? "#BDBDBD" : NULL, NULL); g_object_set(G_OBJECT(cell), "markup", text, NULL); g_free(text); @@ -216,9 +258,23 @@ render_time(G_GNUC_UNUSED GtkTreeViewColumn *tree_column, auto path = gtk_tree_model_get_path(model, iter); auto row = std::atoi(gtk_tree_path_to_string(path)); g_return_if_fail(row != -1); + gchar *uid; - try { - auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(row); + gtk_tree_model_get (model, iter, + 0 /* col# */, &uid /* data */, + -1); + if (g_strcmp0(uid, "") == 0) { + g_object_set(G_OBJECT(cell), "markup", "", NULL); + g_free(uid); + return; + } + + try + { + // Draw first contact. + // NOTE: We just draw the first contact, must change this for conferences when they will have their own object + auto conversation = (*priv->accountInfo_)->conversationModel->getConversationForUID(uid); + if (conversation.participants.empty()) return; auto contactUri = conversation.participants.front(); auto& contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri); @@ -230,6 +286,7 @@ render_time(G_GNUC_UNUSED GtkTreeViewColumn *tree_column, auto call = (*priv->accountInfo_)->callModel->getCall(callId); if (call.status != lrc::api::call::Status::ENDED) { g_object_set(G_OBJECT(cell), "markup", qUtf8Printable(lrc::api::call::to_string(call.status)), NULL); + g_free(uid); return; } } @@ -249,12 +306,14 @@ render_time(G_GNUC_UNUSED GtkTreeViewColumn *tree_column, g_object_set(G_OBJECT(cell), "markup", text, NULL); g_free(text); + g_free(uid); return; } } catch (const std::exception&) { g_warning("Can't get conversation at row %i", row); } + g_free(uid); g_object_set(G_OBJECT(cell), "markup", "", NULL); } @@ -321,33 +380,51 @@ create_and_fill_model(ConversationsView *self) if(!priv) GTK_TREE_MODEL (store); GtkTreeIter iter; - for (auto conversation : (*priv->accountInfo_)->conversationModel->allFilteredConversations()) { - if (conversation.participants.empty()) { - g_debug("Found conversation with empty list of participants - most likely the result of earlier bug."); - break; - } + if (priv->cpp && !priv->cpp->status.isEmpty()) { + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0 /* col # */ , "" /* celldata */, + 1 /* col # */ , qUtf8Printable(priv->cpp->status) /* celldata */, + 2 /* col # */ , "" /* celldata */, + 3 /* col # */ , "" /* celldata */, + 4 /* col # */ , "" /* celldata */, + 5 /* col # */ , "" /* celldata */, + -1 /* end */); + } - auto contactUri = conversation.participants.front(); - try { - auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri); - auto lastMessage = conversation.interactions.empty() ? "" : - conversation.interactions.at(conversation.lastMessageUid).body; - std::replace(lastMessage.begin(), lastMessage.end(), '\n', ' '); - gtk_list_store_append (store, &iter); - auto alias = contactInfo.profileInfo.alias; - alias.remove('\r'); - gtk_list_store_set (store, &iter, - 0 /* col # */ , qUtf8Printable(conversation.uid) /* celldata */, - 1 /* col # */ , qUtf8Printable(alias) /* celldata */, - 2 /* col # */ , qUtf8Printable(contactInfo.profileInfo.uri) /* celldata */, - 3 /* col # */ , qUtf8Printable(contactInfo.registeredName) /* celldata */, - 4 /* col # */ , qUtf8Printable(contactInfo.profileInfo.avatar) /* celldata */, - 5 /* col # */ , qUtf8Printable(lastMessage) /* celldata */, - -1 /* end */); - } catch (const std::out_of_range&) { - // ContactModel::getContact() exception + + auto fillModelLambda = [&](const auto& queue) { + for (auto conversation : queue) { + if (conversation.participants.empty()) { + g_debug("Found conversation with empty list of participants - most likely the result of earlier bug."); + break; + } + + auto contactUri = conversation.participants.front(); + try { + auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri); + auto lastMessage = conversation.interactions.empty() ? "" : + conversation.interactions.at(conversation.lastMessageUid).body; + std::replace(lastMessage.begin(), lastMessage.end(), '\n', ' '); + gtk_list_store_append (store, &iter); + auto alias = contactInfo.profileInfo.alias; + alias.remove('\r'); + gtk_list_store_set (store, &iter, + 0 /* col # */ , qUtf8Printable(conversation.uid) /* celldata */, + 1 /* col # */ , qUtf8Printable(alias) /* celldata */, + 2 /* col # */ , qUtf8Printable(contactInfo.profileInfo.uri) /* celldata */, + 3 /* col # */ , qUtf8Printable(contactInfo.registeredName) /* celldata */, + 4 /* col # */ , qUtf8Printable(contactInfo.profileInfo.avatar) /* celldata */, + 5 /* col # */ , qUtf8Printable(lastMessage) /* celldata */, + -1 /* end */); + } catch (const std::out_of_range&) { + // ContactModel::getContact() exception + } } - } + }; + + fillModelLambda((*priv->accountInfo_)->conversationModel->getAllSearchResults()); + fillModelLambda((*priv->accountInfo_)->conversationModel->allFilteredConversations()); return GTK_TREE_MODEL (store); } @@ -568,7 +645,7 @@ on_drag_data_received(GtkWidget *treeview, static void build_conversations_view(ConversationsView *self) { - auto priv = CONVERSATIONS_VIEW_GET_PRIVATE(self); + auto* priv = CONVERSATIONS_VIEW_GET_PRIVATE(self); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(self), FALSE); auto model = create_and_fill_model(self); @@ -629,6 +706,60 @@ build_conversations_view(ConversationsView *self) gtk_tree_view_set_model(GTK_TREE_VIEW(self), GTK_TREE_MODEL(model)); }); + + + priv->searchChangedConnection_ = QObject::connect( + &*(*priv->accountInfo_)->conversationModel, + &lrc::api::ConversationModel::searchResultUpdated, + [self] () { + auto model = create_and_fill_model(self); + + gtk_tree_view_set_model(GTK_TREE_VIEW(self), + GTK_TREE_MODEL(model)); + }); + priv->searchStatusChangedConnection_ = QObject::connect( + &*(*priv->accountInfo_)->conversationModel, + &lrc::api::ConversationModel::searchStatusChanged, + [self] (const QString& status) { + auto priv = CONVERSATIONS_VIEW_GET_PRIVATE(self); + if (!priv or !priv->cpp) return; + priv->cpp->status = status; + if (status.isEmpty()) return; + + auto model = gtk_tree_view_get_model(GTK_TREE_VIEW(self)); + GtkTreeIter iter; + + auto addItem = true; + if (gtk_tree_model_iter_children(model, &iter, nullptr)) { + gchar *conversationUid = nullptr; + gtk_tree_model_get(model, &iter, 0, &conversationUid, -1); + if (g_strcmp0(conversationUid, "") == 0) { + addItem = false; + gtk_list_store_set (GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(self))), &iter, + 0 /* col # */ , "" /* celldata */, + 1 /* col # */ , qUtf8Printable(status) /* celldata */, + 2 /* col # */ , "" /* celldata */, + 3 /* col # */ , "" /* celldata */, + 4 /* col # */ , "" /* celldata */, + 5 /* col # */ , "" /* celldata */, + -1 /* end */); + } + g_free(conversationUid); + } + + if (addItem) { + gtk_list_store_append (GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(self))), &iter); + gtk_list_store_set (GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(self))), &iter, + 0 /* col # */ , "" /* celldata */, + 1 /* col # */ , qUtf8Printable(status) /* celldata */, + 2 /* col # */ , "" /* celldata */, + 3 /* col # */ , "" /* celldata */, + 4 /* col # */ , "" /* celldata */, + 5 /* col # */ , "" /* celldata */, + -1 /* end */); + } + + }); priv->conversationUpdatedConnection_ = QObject::connect( &*(*priv->accountInfo_)->conversationModel, &lrc::api::ConversationModel::conversationUpdated, @@ -665,6 +796,8 @@ build_conversations_view(ConversationsView *self) // make sure conversation remains selected conversations_view_select_conversation(self, conversationUid); + + g_free(conversationUid); }); gtk_widget_show_all(GTK_WIDGET(self)); @@ -694,6 +827,8 @@ build_conversations_view(ConversationsView *self) g_signal_connect(self, "drag-drop", G_CALLBACK(on_drag_drop), nullptr); g_signal_connect(self, "drag-motion", G_CALLBACK(on_drag_motion), nullptr); g_signal_connect(self, "drag_data_received", G_CALLBACK(on_drag_data_received), nullptr); + + priv->cpp = new details::CppImpl(); } static void @@ -705,11 +840,15 @@ conversations_view_dispose(GObject *object) QObject::disconnect(priv->selection_updated); QObject::disconnect(priv->layout_changed); QObject::disconnect(priv->modelSortedConnection_); + QObject::disconnect(priv->searchChangedConnection_); + QObject::disconnect(priv->searchStatusChangedConnection_); QObject::disconnect(priv->conversationUpdatedConnection_); QObject::disconnect(priv->filterChangedConnection_); QObject::disconnect(priv->callChangedConnection_); gtk_widget_destroy(priv->popupMenu_); + delete priv->cpp; + priv->cpp = nullptr; G_OBJECT_CLASS(conversations_view_parent_class)->dispose(object); } @@ -780,7 +919,6 @@ conversations_view_select_conversation(ConversationsView *self, const std::strin int conversations_view_get_current_selected(ConversationsView *self) { - g_return_val_if_fail(IS_CONVERSATIONS_VIEW(self), -1); /* we always drag the selected row */ diff --git a/src/native/pixbufmanipulator.cpp b/src/native/pixbufmanipulator.cpp index 8421fd57c4f3a954e353aa28418b7cf8233fcd37..f1d9188db4555d2da59d0c9bceeaf6fa0333f4fb 100644 --- a/src/native/pixbufmanipulator.cpp +++ b/src/native/pixbufmanipulator.cpp @@ -220,7 +220,7 @@ PixbufManipulator::conversationPhoto(const lrc::api::conversation::Info& convers } } catch (...) {} } - return QVariant::fromValue(scaleAndFrame(generateAvatar("", "").get(), size, displayInformation)); + return QVariant::fromValue(scaleAndFrame(temporaryItemAvatar().get(), size, displayInformation)); } diff --git a/src/profileview.cpp b/src/profileview.cpp index 4b7c2b47d14d37990b38922b1ebd296b1abe27d8..31f299296d07a9964d1ceb360633919b039d314a 100644 --- a/src/profileview.cpp +++ b/src/profileview.cpp @@ -33,6 +33,10 @@ #include <api/conversationmodel.h> #include <globalinstances.h> +namespace { namespace details { +class CppImpl; +}} + struct _ProfileView { GtkDialog parent; @@ -43,7 +47,7 @@ typedef struct _ProfileViewPrivate ProfileViewPrivate; struct _ProfileViewPrivate { AccountInfoPointer const *accountInfo_ = nullptr; - int row_; + details::CppImpl* cpp {nullptr}; GtkWidget* avatar; @@ -57,6 +61,18 @@ struct _ProfileViewPrivate G_DEFINE_TYPE_WITH_PRIVATE(ProfileView, profile_view, GTK_TYPE_DIALOG) #define PROFILE_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PROFILE_VIEW_TYPE, _ProfileViewPrivate)) +namespace { namespace details { +class CppImpl +{ +public: + explicit CppImpl(); + QString uid_; +}; +CppImpl::CppImpl() + : uid_("") +{} +}} + static void profile_view_init(ProfileView *prefs) { @@ -66,6 +82,9 @@ profile_view_init(ProfileView *prefs) static void profile_view_dispose(GObject *object) { + auto* priv = PROFILE_VIEW_GET_PRIVATE(object); + delete priv->cpp; + priv->cpp = nullptr; G_OBJECT_CLASS(profile_view_parent_class)->dispose(object); } @@ -93,7 +112,7 @@ build_view(ProfileView* view) try { - const auto& conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_); + const auto conversation = (*priv->accountInfo_)->conversationModel->getConversationForUID(priv->cpp->uid_); if (conversation.participants.empty()) return false; const auto& contact = (*priv->accountInfo_)->contactModel->getContact(conversation.participants.front()); @@ -143,19 +162,20 @@ build_view(ProfileView* view) } catch (...) { - g_warning("Can't get conversation at row %i", priv->row_); + g_warning("Can't get conversation %s", priv->cpp? priv->cpp->uid_.toStdString().c_str() : ""); return false; } return true; } GtkWidget* -profile_view_new(AccountInfoPointer const & accountInfo, int row) +profile_view_new(AccountInfoPointer const & accountInfo, const QString& uid) { gpointer view = g_object_new(PROFILE_VIEW_TYPE, NULL); auto* priv = PROFILE_VIEW_GET_PRIVATE(view); priv->accountInfo_ = &accountInfo; - priv->row_ = row; + priv->cpp = new details::CppImpl(); + priv->cpp->uid_ = uid; if (!build_view(PROFILE_VIEW(view))) return nullptr; auto provider = gtk_css_provider_new(); diff --git a/src/profileview.h b/src/profileview.h index 0205f72277f2fcb47bc526393469f5782de66d4f..15fcf3afc84b1d024393374e8b7a0539f7c94495 100644 --- a/src/profileview.h +++ b/src/profileview.h @@ -20,6 +20,7 @@ #pragma once #include <gtk/gtk.h> +#include <QString> #include "accountinfopointer.h" @@ -29,4 +30,4 @@ G_DECLARE_FINAL_TYPE (ProfileView, profile_view, PROFILE, VIEW, GtkDialog) -GtkWidget* profile_view_new(AccountInfoPointer const & accountInfo, int row_); \ No newline at end of file +GtkWidget* profile_view_new(AccountInfoPointer const & accountInfo, const QString& uid); \ No newline at end of file