/*
 *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
 *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

#include "recentcontactsview.h"

#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "models/gtkqtreemodel.h"
#include "utils/calling.h"
#include <memory>
#include <globalinstances.h>
#include "native/pixbufmanipulator.h"
#include <contactmethod.h>
#include "defines.h"
#include "utils/models.h"
#include <recentmodel.h>
#include <call.h>
#include "utils/menus.h"
#include <itemdataroles.h>
#include <callmodel.h>
#include <QtCore/QItemSelectionModel>
#include <historytimecategorymodel.h>
#include <QtCore/QDateTime>
#include <QtCore/QMimeData>
#include "utils/drawing.h"
#include <numbercategory.h>
#include "contactpopupmenu.h"

static constexpr const char* CALL_TARGET    = "CALL_TARGET";
static constexpr int         CALL_TARGET_ID = 0;

struct _RecentContactsView
{
    GtkTreeView parent;
};

struct _RecentContactsViewClass
{
    GtkTreeViewClass parent_class;
};

typedef struct _RecentContactsViewPrivate RecentContactsViewPrivate;

struct _RecentContactsViewPrivate
{
    GtkWidget *popup_menu;

    QMetaObject::Connection selection_updated;
    QMetaObject::Connection layout_changed;
};

G_DEFINE_TYPE_WITH_PRIVATE(RecentContactsView, recent_contacts_view, GTK_TYPE_TREE_VIEW);

#define RECENT_CONTACTS_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), RECENT_CONTACTS_VIEW_TYPE, RecentContactsViewPrivate))

static void
update_selection(GtkTreeSelection *selection)
{
    if (gtk_q_tree_model_ignore_selection_change(selection)) return;

    auto current_proxy = get_index_from_selection(selection);
    auto current = RecentModel::instance().peopleProxy()->mapToSource(current_proxy);

    RecentModel::instance().selectionModel()->setCurrentIndex(current, QItemSelectionModel::ClearAndSelect);

    // update the CallModel selection since we rely on the UserActionModel
    if (auto call_to_select = RecentModel::instance().getActiveCall(current)) {
        CallModel::instance().selectCall(call_to_select);
    } else {
        CallModel::instance().selectionModel()->clearCurrentIndex();
    }
}

static void
render_contact_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
                     GtkCellRenderer *cell,
                     GtkTreeModel *model,
                     GtkTreeIter *iter,
                     G_GNUC_UNUSED gpointer data)
{
    QModelIndex idx = gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), iter);

    std::shared_ptr<GdkPixbuf> image;
    /* we only want to render a photo for the top nodes: Person, ContactMethod (, later Conference) */
    QVariant object = idx.data(static_cast<int>(Ring::Role::Object));
    if (idx.isValid() && object.isValid()) {
        QVariant var_photo;
        if (auto person = object.value<Person *>()) {
            var_photo = GlobalInstances::pixmapManipulator().contactPhoto(person, QSize(50, 50), true);
        } else if (auto cm = object.value<ContactMethod *>()) {
            /* get photo, note that this should in all cases be the fallback avatar, since there
             * shouldn't be a person associated with this contact method */
            var_photo = GlobalInstances::pixmapManipulator().callPhoto(cm, QSize(50, 50), true);
        } else if (auto call = object.value<Call *>()) {
            if (call->type() == Call::Type::CONFERENCE) {
                var_photo = GlobalInstances::pixmapManipulator().callPhoto(call, QSize(50, 50), true);
            }
        }
        image = var_photo.value<std::shared_ptr<GdkPixbuf>>();
    }

    // set the width of the cell rendered to the width of the photo
    // so that the other renderers are shifted to the right
    g_object_set(G_OBJECT(cell), "width", 50, NULL);
    g_object_set(G_OBJECT(cell), "pixbuf", image.get(), NULL);
}

/**
 * This is the 2nd column in the treeview; for Person and ContactMethod items we want to DisplayRole
 * the name in the first row and the number (Ring registered name or URI) in the second row. for
 * Conferences we simply display the name, and for calls we simply display the Call status (note:
 * that if the item is a Call, it is not a top level item)
 */
static void
render_name_and_number(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
                       GtkCellRenderer *cell,
                       GtkTreeModel *model,
                       GtkTreeIter *iter,
                       GtkTreeView *treeview)
{
    gchar *text = nullptr;

    QModelIndex idx = gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), iter);

    // check if this iter is selected
    gboolean is_selected = FALSE;
    if (GTK_IS_TREE_VIEW(treeview)) {
        auto selection = gtk_tree_view_get_selection(treeview);
        is_selected = gtk_tree_selection_iter_is_selected(selection, iter);
    }

    auto type = idx.data(static_cast<int>(Ring::Role::ObjectType));
    if (idx.isValid() && type.isValid()) {
        switch (type.value<Ring::ObjectType>()) {
            case Ring::ObjectType::Person:
            case Ring::ObjectType::ContactMethod:
            {
                auto name = idx.data(static_cast<int>(Ring::Role::Name)).toString();
                auto number = idx.data(static_cast<int>(Ring::Role::Number)).toString();

                /* we want the color of the status text to be the default color if this iter is
                 * selected so that the treeview is able to invert it against the selection color */
                if (is_selected) {
                     text = g_markup_printf_escaped(
                         "<span font_weight=\"bold\">%s</span>\n<span size=\"smaller\">%s</span>",
                        // "%s\n<span size=\"smaller\">%s</span>",
                         name.toUtf8().constData(),
                         number.toUtf8().constData()
                     );
                } else {
                     text = g_markup_printf_escaped(
                         "<span font_weight=\"bold\">%s</span>\n<span color=\"gray\" size=\"smaller\">%s</span>",
                        //  "%s\n<span color=\"gray\" size=\"smaller\">%s</span>",
                         name.toUtf8().constData(),
                         number.toUtf8().constData()
                     );
                 }
            }
            break;
            case Ring::ObjectType::Call:
            {
                // check if it is a conference
                auto idx_source = RecentModel::instance().peopleProxy()->mapToSource(idx);
                auto is_conference = RecentModel::instance().isConference(idx_source);

                if (is_conference) {
                    auto var_name = idx.data(static_cast<int>(Ring::Role::Name));
                    text = g_markup_escape_text(var_name.value<QString>().toUtf8().constData(), -1);
                } else {
                    auto parent_source = RecentModel::instance().peopleProxy()->mapToSource(idx.parent());
                    if (RecentModel::instance().isConference(parent_source)) {
                        // part of conference, simply display the name
                        auto var_name = idx.data(static_cast<int>(Ring::Role::Name));

                        /* we want the color of the name text to be the default color if this iter is
                         * selected so that the treeview is able to invert it against the selection color */
                        if (is_selected) {
                            text = g_markup_printf_escaped("<span size=\"smaller\">%s</span>",
                                                           var_name.value<QString>().toUtf8().constData());
                        } else {
                            text = g_markup_printf_escaped("<span size=\"smaller\" color=\"gray\">%s</span>",
                                                           var_name.value<QString>().toUtf8().constData());
                        }
                    } else {
                        // just a call, so display the state
                        auto var_status = idx.data(static_cast<int>(Ring::Role::FormattedState));

                        QString status;

                        if (var_status.isValid())
                            status += var_status.value<QString>();

                        /* we want the color of the status text to be the default color if this iter is
                         * selected so that the treeview is able to invert it against the selection color */
                        if (is_selected) {
                            text = g_markup_printf_escaped("<span size=\"smaller\">%s</span>",
                                                           status.toUtf8().constData());
                        } else {
                            text = g_markup_printf_escaped("<span size=\"smaller\" color=\"gray\">%s</span>",
                                                           status.toUtf8().constData());
                        }
                    }
                }
            }
            break;
            case Ring::ObjectType::Media:
            case Ring::ObjectType::Certificate:
            case Ring::ObjectType::ContactRequest:
            // nothing to do for now
            case Ring::ObjectType::COUNT__:
            break;
        }
    }

    g_object_set(G_OBJECT(cell), "markup", text, NULL);
    g_free(text);
}

/**
 * This is the 3rd column in the treeview. For Person and ContactMethod items we want to display
 * in the first row the call status or else the last used date. In the second row we want to display
 * either the call duration or else the number of unread messages. In the case of a Call item we
 * simply display the call duration.
 */
static void
render_info(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
            GtkCellRenderer *cell,
            GtkTreeModel *model,
            GtkTreeIter *iter,
            GtkTreeView *treeview)
{
    gchar *text = nullptr;

    QModelIndex idx = gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), iter);

    // check if this iter is selected
    gboolean is_selected = FALSE;
    if (GTK_IS_TREE_VIEW(treeview)) {
        auto selection = gtk_tree_view_get_selection(treeview);
        is_selected = gtk_tree_selection_iter_is_selected(selection, iter);
    }

    auto type = idx.data(static_cast<int>(Ring::Role::ObjectType));
    if (idx.isValid() && type.isValid()) {
        switch (type.value<Ring::ObjectType>()) {
            case Ring::ObjectType::Person:
            case Ring::ObjectType::ContactMethod:
            {
                gchar *row0 = nullptr; // either call status or last used
                gchar *row1 = nullptr; // either call duration or unread msg count

                QString status;
                auto var_status = idx.data(static_cast<int>(Ring::Role::FormattedState));
                auto var_lastused = idx.data(static_cast<int>(Ring::Role::LastUsed));

                // show the status if there is a call, otherwise the last used date/time
                if (var_status.isValid()) {
                    status = var_status.value<QString>();
                } else if (var_lastused.isValid()) {
                    auto date_time = var_lastused.value<QDateTime>();
                    auto category = HistoryTimeCategoryModel::timeToHistoryConst(date_time.toTime_t());

                    /* If it is 'today', then we show the time; otherwise we will show date category
                     * (the day or long ago it was). The day and the time together take up too much
                     * space */
                    if (category == HistoryTimeCategoryModel::HistoryConst::Today) {
                        status = QLocale::system().toString(date_time.time(), QLocale::ShortFormat);
                    } else {
                        status = HistoryTimeCategoryModel::timeToHistoryCategory(date_time.toTime_t());
                    }
                }

                if (is_selected) {
                    row0 = g_markup_printf_escaped(
                        "<span size=\"smaller\">%s</span>",
                        status.toUtf8().constData()
                    );
                } else {
                    row0 = g_markup_printf_escaped(
                        "<span size=\"smaller\" color=\"gray\">%s</span>",
                        status.toUtf8().constData()
                    );
                }

                // check if there are any children (calls); we need to convert to source model in
                // case there is only one
                auto idx_source = RecentModel::instance().peopleProxy()->mapToSource(idx);
                auto duration = idx.data(static_cast<int>(Ring::Role::Length));
                if (idx_source.isValid()
                    && (idx_source.model()->rowCount(idx_source) == 1)
                    && duration.isValid())
                {
                    row1 = g_markup_printf_escaped("%s", duration.toString().toUtf8().constData());
                }
                else
                {
                    auto unread = idx.data(static_cast<int>(Ring::Role::UnreadTextMessageCount)).toInt();
                    if (unread > 0) {
                        if (is_selected) {
                            row1 = g_markup_printf_escaped(
                                "<span font_weight=\"bold\">%d</span>",
                                unread
                            );
                        } else {
                            row1 = g_markup_printf_escaped(
                                "<span color=\"red\" font_weight=\"bold\">%d</span>",
                                unread
                            );
                        }
                    }
                }

                text = g_strconcat(row0, "\n", row1, nullptr);
                g_free(row0);
                g_free(row1);
            }
            break;
            case Ring::ObjectType::Call:
            {
                // do not display the duration if the call is part of a conference
                auto parent_source = RecentModel::instance().peopleProxy()->mapToSource(idx.parent());
                auto in_conference = RecentModel::instance().isConference(parent_source);

                if (!in_conference) {
                    auto duration = idx.data(static_cast<int>(Ring::Role::Length));

                    if (duration.isValid())
                        text = g_markup_escape_text(duration.value<QString>().toUtf8().constData(), -1);
                }
            }
            break;
            case Ring::ObjectType::Media:
            case Ring::ObjectType::Certificate:
            case Ring::ObjectType::ContactRequest:
            // nothing to do for now
            case Ring::ObjectType::COUNT__:
            break;
        }
    }

    g_object_set(G_OBJECT(cell), "markup", text, NULL);
    g_free(text);
}

static void
activate_item(GtkTreeView *tree_view,
              GtkTreePath *path,
              G_GNUC_UNUSED GtkTreeViewColumn *column,
              G_GNUC_UNUSED gpointer user_data)
{
    auto model = gtk_tree_view_get_model(tree_view);
    GtkTreeIter iter;
    if (gtk_tree_model_get_iter(model, &iter, path)) {
        QModelIndex idx = gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), &iter);
        auto type = idx.data(static_cast<int>(Ring::Role::ObjectType));
        if (idx.isValid() && type.isValid()) {
            switch (type.value<Ring::ObjectType>()) {
                case Ring::ObjectType::Person:
                {
                    // call the last used contact method
                    // TODO: if no contact methods have been used, offer a popup to Choose
                    auto p_var = idx.data(static_cast<int>(Ring::Role::Object));
                    if (p_var.isValid()) {
                        auto person = p_var.value<Person *>();
                        auto cms = person->phoneNumbers();

                        if (!cms.isEmpty()) {
                            auto last_used_cm = cms.at(0);
                            for (int i = 1; i < cms.size(); ++i) {
                                auto new_cm = cms.at(i);
                                if (difftime(new_cm->lastUsed(), last_used_cm->lastUsed()) > 0)
                                    last_used_cm = new_cm;
                            }

                            place_new_call(last_used_cm);
                        }
                    }
                }
                break;
                case Ring::ObjectType::ContactMethod:
                {
                    // call the contact method
                    auto cm = idx.data(static_cast<int>(Ring::Role::Object));
                    if (cm.isValid())
                        place_new_call(cm.value<ContactMethod *>());
                }
                break;
                case Ring::ObjectType::Call:
                case Ring::ObjectType::Media:
                case Ring::ObjectType::Certificate:
                case Ring::ObjectType::ContactRequest:
                // nothing to do for now
                case Ring::ObjectType::COUNT__:
                break;
            }
        }
    }
}

static void
expand_if_child(G_GNUC_UNUSED GtkTreeModel *tree_model,
                GtkTreePath  *path,
                G_GNUC_UNUSED GtkTreeIter  *iter,
                GtkTreeView  *treeview)
{
    if (gtk_tree_path_get_depth(path) > 1)
        gtk_tree_view_expand_to_path(treeview, path);
}

static void
scroll_to_selection(GtkTreeSelection *selection)
{
    auto treeview = gtk_tree_selection_get_tree_view(selection);
    auto model = gtk_tree_view_get_model(treeview);
    if (gtk_q_tree_model_is_layout_changing(GTK_Q_TREE_MODEL(model))) {
        /* during a layout change, the GtkTreeModel items will be removed, so the GTK selection will
         * be empty, we want to ignore this */
        return;
    }

    GtkTreeIter iter;
    if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
        auto path = gtk_tree_model_get_path(model, &iter);
        auto treeview = gtk_tree_selection_get_tree_view(selection);
        gtk_tree_view_scroll_to_cell(treeview, path, nullptr, FALSE, 0.0, 0.0);
    }
}

static void
on_drag_data_get(GtkWidget        *treeview,
                 G_GNUC_UNUSED GdkDragContext *context,
                 GtkSelectionData *data,
                 G_GNUC_UNUSED guint info,
                 G_GNUC_UNUSED guint time,
                 G_GNUC_UNUSED gpointer user_data)
{
    g_return_if_fail(IS_RECENT_CONTACTS_VIEW(treeview));

    /* we always drag the selected row */
    auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
    GtkTreeModel *model = NULL;
    GtkTreeIter iter;

    if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
        auto path_str = gtk_tree_model_get_string_from_iter(model, &iter);

        gtk_selection_data_set(data,
                               gdk_atom_intern_static_string(CALL_TARGET),
                               8, /* bytes */
                               (guchar *)path_str,
                               strlen(path_str) + 1);

        g_free(path_str);
    } else {
        g_warning("drag selection not valid");
    }
}

static gboolean
on_drag_drop(GtkWidget      *treeview,
             GdkDragContext *context,
             gint            x,
             gint            y,
             guint           time,
             G_GNUC_UNUSED gpointer user_data)
{
    g_return_val_if_fail(IS_RECENT_CONTACTS_VIEW(treeview), FALSE);

    GtkTreePath *path = NULL;
    GtkTreeViewDropPosition drop_pos;

    if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(treeview),
                                          x, y, &path, &drop_pos)) {

        GdkAtom target_type = gtk_drag_dest_find_target(treeview, context, NULL);

        if (target_type != GDK_NONE) {
            g_debug("can drop");
            gtk_drag_get_data(treeview, context, target_type, time);
            return TRUE;
        }

        gtk_tree_path_free(path);
    }

    return FALSE;
}

static gboolean
on_drag_motion(GtkWidget      *treeview,
               GdkDragContext *context,
               gint            x,
               gint            y,
               guint           time,
               G_GNUC_UNUSED gpointer user_data)
{
    g_return_val_if_fail(IS_RECENT_CONTACTS_VIEW(treeview), FALSE);

    GtkTreePath *path = NULL;
    GtkTreeViewDropPosition drop_pos;

    if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(treeview),
                                          x, y, &path, &drop_pos)) {
        // we only want to drop on a row, not before or after
        if (drop_pos == GTK_TREE_VIEW_DROP_BEFORE) {
            gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(treeview), path, GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
        } else if (drop_pos == GTK_TREE_VIEW_DROP_AFTER) {
            gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(treeview), path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
        }
        gdk_drag_status(context, gdk_drag_context_get_suggested_action(context), time);
        return TRUE;
    } else {
        // not a row in the treeview, so we cannot drop
        return FALSE;
    }
}

static void
on_drag_data_received(GtkWidget        *treeview,
                      GdkDragContext   *context,
                      gint              x,
                      gint              y,
                      GtkSelectionData *data,
                      G_GNUC_UNUSED guint info,
                      guint             time,
                      G_GNUC_UNUSED gpointer user_data)
{
    g_return_if_fail(IS_RECENT_CONTACTS_VIEW(treeview));

    gboolean success = FALSE;

    /* get the source and destination calls */
    auto path_str_source = (gchar *)gtk_selection_data_get_data(data);
    auto type = gtk_selection_data_get_data_type(data);
    g_debug("data type: %s", gdk_atom_name(type));
    if (path_str_source && strlen(path_str_source) > 0) {
        g_debug("source path: %s", path_str_source);

        /* get the destination path */
        GtkTreePath *dest_path = NULL;
        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));

            GtkTreeIter source;
            gtk_tree_model_get_iter_from_string(model, &source, path_str_source);
            auto idx_source_proxy = gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), &source);

            GtkTreeIter dest;
            gtk_tree_model_get_iter(model, &dest, dest_path);
            auto idx_dest_proxy = gtk_q_tree_model_get_source_idx(GTK_Q_TREE_MODEL(model), &dest);

            // get call objects and indeces from RecentModel indeces being drag and dropped
            auto idx_source = RecentModel::instance().peopleProxy()->mapToSource(idx_source_proxy);
            auto idx_dest = RecentModel::instance().peopleProxy()->mapToSource(idx_dest_proxy);
            auto call_source = RecentModel::instance().getActiveCall(idx_source);
            auto call_dest = RecentModel::instance().getActiveCall(idx_dest);
            auto idx_call_source = CallModel::instance().getIndex(call_source);
            auto idx_call_dest = CallModel::instance().getIndex(call_dest);

            if (idx_call_source.isValid() && idx_call_dest.isValid()) {
                QModelIndexList source_list;
                source_list << idx_call_source;
                auto mimeData = CallModel::instance().mimeData(source_list);
                auto action = Call::DropAction::Conference;
                mimeData->setProperty("dropAction", action);

                if (CallModel::instance().dropMimeData(mimeData, Qt::MoveAction, idx_call_dest.row(), idx_call_dest.column(), idx_call_dest.parent())) {
                    success = TRUE;
                } else {
                    g_warning("could not drop mime data");
                }
            } else {
                g_warning("source or dest call not valid");
            }

            gtk_tree_path_free(dest_path);
        }
    }

    gtk_drag_finish(context, success, FALSE, time);
}

static gboolean
synchronize_selection(RecentContactsView *self)
{
    auto idx = RecentModel::instance().selectionModel()->currentIndex();
    auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
    auto model = gtk_tree_view_get_model(GTK_TREE_VIEW(self));

    if (gtk_q_tree_model_is_layout_changing(GTK_Q_TREE_MODEL(model))) {
        /* during a layout change, the GtkTreeModel items will be removed, so the GTK selection will
         * be empty, we want to avoid trying to sync during this time, and reschedule it to try
         * again later */
        return G_SOURCE_CONTINUE;
    }

    auto idx_proxy = RecentModel::instance().peopleProxy()->mapFromSource(idx);

    if (idx_proxy.isValid()) {
        /* select the current */
        GtkTreeIter iter;
        if (gtk_q_tree_model_source_index_to_iter(GTK_Q_TREE_MODEL(model), idx_proxy, &iter)) {
            gtk_tree_selection_select_iter(selection, &iter);
        }
    } else {
        gtk_tree_selection_unselect_all(selection);
    }

    return G_SOURCE_REMOVE;
}

static void
recent_contacts_view_init(RecentContactsView *self)
{
    RecentContactsViewPrivate *priv = RECENT_CONTACTS_VIEW_GET_PRIVATE(self);

    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(self), FALSE);
    /* no need to show the expander since it will always be expanded */
    gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(self), FALSE);
    /* disable default search, we will handle it ourselves via LRC;
     * otherwise the search steals input focus on key presses */
    gtk_tree_view_set_enable_search(GTK_TREE_VIEW(self), FALSE);

    GtkQTreeModel *recent_model = gtk_q_tree_model_new(
        RecentModel::instance().peopleProxy(),
        1,
        0, Qt::DisplayRole, G_TYPE_STRING);

    gtk_tree_view_set_model(GTK_TREE_VIEW(self),
                            GTK_TREE_MODEL(recent_model));

    /* photo and name/contact method column */
    GtkCellArea *area = gtk_cell_area_box_new();
    GtkTreeViewColumn *column = gtk_tree_view_column_new_with_area(area);

    /* photo renderer */
    GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
    gtk_cell_area_box_pack_start(GTK_CELL_AREA_BOX(area), renderer, FALSE, FALSE, FALSE);

    /* get the photo */
    gtk_tree_view_column_set_cell_data_func(
        column,
        renderer,
        (GtkTreeCellDataFunc)render_contact_photo,
        NULL,
        NULL);

    /* name/cm and status renderer */
    renderer = gtk_cell_renderer_text_new();
    g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
    gtk_cell_area_box_pack_start(GTK_CELL_AREA_BOX(area), renderer, FALSE, FALSE, FALSE);

    gtk_tree_view_column_set_cell_data_func(
        column,
        renderer,
        (GtkTreeCellDataFunc)render_name_and_number,
        self,
        NULL);

    /* call duration or unread messages */
    renderer = gtk_cell_renderer_text_new();
    g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
    gtk_cell_area_box_pack_end(GTK_CELL_AREA_BOX(area), renderer, FALSE, FALSE, FALSE);
    gtk_tree_view_column_set_cell_data_func(
        column,
        renderer,
        (GtkTreeCellDataFunc)render_info,
        self,
        NULL);

    gtk_tree_view_append_column(GTK_TREE_VIEW(self), column);
    gtk_tree_view_column_set_resizable(column, TRUE);
    gtk_tree_view_column_set_expand(column, TRUE);
    gtk_tree_view_expand_all(GTK_TREE_VIEW(self));

    g_signal_connect(self, "row-activated", G_CALLBACK(activate_item), NULL);
    g_signal_connect(recent_model, "row-inserted", G_CALLBACK(expand_if_child), self);

    GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
    g_signal_connect(selection, "changed", G_CALLBACK(update_selection), NULL);
    g_signal_connect(selection, "changed", G_CALLBACK(scroll_to_selection), NULL);
    g_signal_connect_swapped(recent_model, "rows-reordered", G_CALLBACK(scroll_to_selection), selection);

    /* sync initial selection */
    g_idle_add((GSourceFunc)synchronize_selection, self);

    auto synchronize_selection_idle = [self] () { g_idle_add((GSourceFunc)synchronize_selection, self); };

    /* update the selection based on the RecentModel */
    priv->selection_updated = QObject::connect(
        RecentModel::instance().selectionModel(),
        &QItemSelectionModel::currentChanged,
        synchronize_selection_idle
    );

    /* we may need to update the selection when the layout changes */
    priv->layout_changed = QObject::connect(
        RecentModel::instance().peopleProxy(),
        &QAbstractItemModel::layoutChanged,
        synchronize_selection_idle
    );

    /* drag and drop */
    static GtkTargetEntry targetentries[] = {
        { (gchar *)CALL_TARGET, GTK_TARGET_SAME_WIDGET, CALL_TARGET_ID },
    };

    gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(self),
        GDK_BUTTON1_MASK, targetentries, 1, (GdkDragAction)(GDK_ACTION_DEFAULT | GDK_ACTION_MOVE));

    gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(self),
        targetentries, 1, GDK_ACTION_DEFAULT);

    g_signal_connect(self, "drag-data-get", G_CALLBACK(on_drag_data_get), nullptr);
    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);

    /* init popup menu */
    priv->popup_menu = contact_popup_menu_new(GTK_TREE_VIEW(self));
    g_signal_connect_swapped(self, "button-press-event", G_CALLBACK(contact_popup_menu_show), priv->popup_menu);

    gtk_widget_show_all(GTK_WIDGET(self));
}

static void
recent_contacts_view_dispose(GObject *object)
{
    RecentContactsView *self = RECENT_CONTACTS_VIEW(object);
    RecentContactsViewPrivate *priv = RECENT_CONTACTS_VIEW_GET_PRIVATE(self);

    QObject::disconnect(priv->selection_updated);
    QObject::disconnect(priv->layout_changed);
    gtk_widget_destroy(priv->popup_menu);

    G_OBJECT_CLASS(recent_contacts_view_parent_class)->dispose(object);
}

static void
recent_contacts_view_finalize(GObject *object)
{
    G_OBJECT_CLASS(recent_contacts_view_parent_class)->finalize(object);
}

static void
recent_contacts_view_class_init(RecentContactsViewClass *klass)
{
    G_OBJECT_CLASS(klass)->finalize = recent_contacts_view_finalize;
    G_OBJECT_CLASS(klass)->dispose = recent_contacts_view_dispose;
}

GtkWidget *
recent_contacts_view_new()
{
    gpointer self = g_object_new(RECENT_CONTACTS_VIEW_TYPE, NULL);

    return (GtkWidget *)self;
}
