blob: cd15bb9932ba2ef53aee6678f0dfc469e6b6953d [file] [log] [blame]
Stepan Salenikovichde896112015-05-11 16:46:33 -04001/*
Stepan Salenikovichbe87d2c2016-01-25 14:14:34 -05002 * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
Stepan Salenikovichde896112015-05-11 16:46:33 -04003 * Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Stepan Salenikovichde896112015-05-11 16:46:33 -040018 */
19
20#include "generalsettingsview.h"
21
22#include <gtk/gtk.h>
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -040023#include <glib/gi18n.h>
Stepan Salenikovichde896112015-05-11 16:46:33 -040024#include <categorizedhistorymodel.h>
Stepan Salenikovichfb7f2952015-05-25 16:44:19 -040025#include "utils/files.h"
Nicolas Jager6f5e04a2016-05-18 15:04:59 -040026#include "avatarmanipulation.h"
27
28/* lrc */
29#include <person.h>
30#include <profile.h>
31#include <profilemodel.h>
Stepan Salenikovichde896112015-05-11 16:46:33 -040032
33struct _GeneralSettingsView
34{
Stepan Salenikovichab0f5be2016-02-05 15:16:35 -050035 GtkScrolledWindow parent;
Stepan Salenikovichde896112015-05-11 16:46:33 -040036};
37
38struct _GeneralSettingsViewClass
39{
Stepan Salenikovichab0f5be2016-02-05 15:16:35 -050040 GtkScrolledWindowClass parent_class;
Stepan Salenikovichde896112015-05-11 16:46:33 -040041};
42
43typedef struct _GeneralSettingsViewPrivate GeneralSettingsViewPrivate;
44
45struct _GeneralSettingsViewPrivate
46{
Stepan Salenikovichfb7f2952015-05-25 16:44:19 -040047 GSettings *settings;
48
49 /* Rint settings */
50 GtkWidget *checkbutton_autostart;
Stepan Salenikovich982b2882016-06-15 13:13:37 -040051 GtkWidget *checkbutton_showstatusicon;
Stepan Salenikovichbc6c4be2015-07-31 16:07:54 -040052 GtkWidget *checkbutton_bringtofront;
Stepan Salenikovicha5e8e362015-11-05 16:50:48 -050053 GtkWidget *radiobutton_chatright;
54 GtkWidget *radiobutton_chatbottom;
Nicolas Jager6f5e04a2016-05-18 15:04:59 -040055 GtkWidget *box_profil_settings;
56 GtkWidget *avatarmanipulation;
57 GtkWidget *profile_name;
Stepan Salenikovichfb7f2952015-05-25 16:44:19 -040058
Stepan Salenikovichde896112015-05-11 16:46:33 -040059 /* history settings */
60 GtkWidget *adjustment_history_duration;
61 GtkWidget *button_clear_history;
62};
63
Stepan Salenikovichab0f5be2016-02-05 15:16:35 -050064G_DEFINE_TYPE_WITH_PRIVATE(GeneralSettingsView, general_settings_view, GTK_TYPE_SCROLLED_WINDOW);
Stepan Salenikovichde896112015-05-11 16:46:33 -040065
66#define GENERAL_SETTINGS_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GENERAL_SETTINGS_VIEW_TYPE, GeneralSettingsViewPrivate))
67
68static void
69general_settings_view_dispose(GObject *object)
70{
Stepan Salenikovichfb7f2952015-05-25 16:44:19 -040071 GeneralSettingsViewPrivate *priv = GENERAL_SETTINGS_VIEW_GET_PRIVATE(object);
72
73 g_clear_object(&priv->settings);
74
Nicolas Jager6f5e04a2016-05-18 15:04:59 -040075 //make sure the VideoWidget is destroyed
76 general_settings_view_show_profile(GENERAL_SETTINGS_VIEW(object), FALSE);
77
Stepan Salenikovichde896112015-05-11 16:46:33 -040078 G_OBJECT_CLASS(general_settings_view_parent_class)->dispose(object);
79}
80
81static void
82history_limit_changed(GtkAdjustment *adjustment, G_GNUC_UNUSED gpointer user_data)
83{
84 int limit = (int)gtk_adjustment_get_value(GTK_ADJUSTMENT(adjustment));
Guillaume Roguez5d1514b2015-10-22 15:55:31 -040085 CategorizedHistoryModel::instance().setHistoryLimit(limit);
Stepan Salenikovichde896112015-05-11 16:46:33 -040086}
87
88static gboolean
89clear_history_dialog(GeneralSettingsView *self)
90{
91 gboolean response = FALSE;
92 GtkWidget *dialog = gtk_message_dialog_new(NULL,
93 (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
94 GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
Stepan Salenikovicha1b8cb32015-09-11 14:58:35 -040095 _("Are you sure you want to clear all your history?\nThis operation will also reset the Frequent Contacts list"));
Stepan Salenikovichde896112015-05-11 16:46:33 -040096
97 gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
98
99 /* get parent window so we can center on it */
100 GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(self));
101 if (gtk_widget_is_toplevel(parent)) {
102 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
103 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
104 }
105
106 switch (gtk_dialog_run(GTK_DIALOG(dialog))) {
107 case GTK_RESPONSE_OK:
108 response = TRUE;
109 break;
110 default:
111 response = FALSE;
112 break;
113 }
114
115 gtk_widget_destroy(dialog);
116
117 return response;
118}
119
120static void
121clear_history(G_GNUC_UNUSED GtkWidget *button, GeneralSettingsView *self)
122{
123 g_return_if_fail(IS_GENERAL_SETTINGS_VIEW(self));
124
125 if (clear_history_dialog(self) )
Guillaume Roguez5d1514b2015-10-22 15:55:31 -0400126 CategorizedHistoryModel::instance().clearAllCollections();
Stepan Salenikovichde896112015-05-11 16:46:33 -0400127}
128
129static void
130general_settings_view_init(GeneralSettingsView *self)
131{
132 gtk_widget_init_template(GTK_WIDGET(self));
133
134 GeneralSettingsViewPrivate *priv = GENERAL_SETTINGS_VIEW_GET_PRIVATE(self);
135
Stepan Salenikovichfb7f2952015-05-25 16:44:19 -0400136 priv->settings = g_settings_new_full(get_ring_schema(), NULL, NULL);
137
Stepan Salenikovichbc6c4be2015-07-31 16:07:54 -0400138 /* bind client option to gsettings */
Stepan Salenikovichfb7f2952015-05-25 16:44:19 -0400139 g_settings_bind(priv->settings, "start-on-login",
140 priv->checkbutton_autostart, "active",
141 G_SETTINGS_BIND_DEFAULT);
Stepan Salenikovich982b2882016-06-15 13:13:37 -0400142 g_settings_bind(priv->settings, "show-status-icon",
143 priv->checkbutton_showstatusicon, "active",
Stepan Salenikovichbc6c4be2015-07-31 16:07:54 -0400144 G_SETTINGS_BIND_DEFAULT);
145 g_settings_bind(priv->settings, "bring-window-to-front",
146 priv->checkbutton_bringtofront, "active",
147 G_SETTINGS_BIND_DEFAULT);
Stepan Salenikovicha5e8e362015-11-05 16:50:48 -0500148 g_settings_bind(priv->settings, "chat-pane-horizontal",
149 priv->radiobutton_chatright, "active",
150 G_SETTINGS_BIND_DEFAULT);
151 g_settings_bind(priv->settings, "chat-pane-horizontal",
152 priv->radiobutton_chatbottom, "active",
153 (GSettingsBindFlags) (G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_INVERT_BOOLEAN));
Stepan Salenikovichfb7f2952015-05-25 16:44:19 -0400154
Stepan Salenikovichde896112015-05-11 16:46:33 -0400155 /* history limit */
156 gtk_adjustment_set_value(GTK_ADJUSTMENT(priv->adjustment_history_duration),
Guillaume Roguez5d1514b2015-10-22 15:55:31 -0400157 CategorizedHistoryModel::instance().historyLimit());
Stepan Salenikovichde896112015-05-11 16:46:33 -0400158 g_signal_connect(priv->adjustment_history_duration,
159 "value-changed", G_CALLBACK(history_limit_changed), NULL);
160
161 /* clear history */
162 g_signal_connect(priv->button_clear_history, "clicked", G_CALLBACK(clear_history), self);
163}
164
165static void
166general_settings_view_class_init(GeneralSettingsViewClass *klass)
167{
168 G_OBJECT_CLASS(klass)->dispose = general_settings_view_dispose;
169
170 gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass),
171 "/cx/ring/RingGnome/generalsettingsview.ui");
172
Stepan Salenikovichfb7f2952015-05-25 16:44:19 -0400173 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_autostart);
Stepan Salenikovich982b2882016-06-15 13:13:37 -0400174 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_showstatusicon);
Stepan Salenikovichbc6c4be2015-07-31 16:07:54 -0400175 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_bringtofront);
Stepan Salenikovicha5e8e362015-11-05 16:50:48 -0500176 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, radiobutton_chatright);
177 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, radiobutton_chatbottom);
Stepan Salenikovichde896112015-05-11 16:46:33 -0400178 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, adjustment_history_duration);
179 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, button_clear_history);
Nicolas Jager6f5e04a2016-05-18 15:04:59 -0400180 gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, box_profil_settings);
Stepan Salenikovichde896112015-05-11 16:46:33 -0400181}
182
183GtkWidget *
184general_settings_view_new()
185{
186 gpointer view = g_object_new(GENERAL_SETTINGS_VIEW_TYPE, NULL);
187
188 return (GtkWidget *)view;
189}
Nicolas Jager6f5e04a2016-05-18 15:04:59 -0400190
191static void
192change_profile_name(GtkEntry *entry)
193{
194 auto profile = ProfileModel::instance().selectedProfile();
195 profile->person()->setFormattedName(gtk_entry_get_text(entry));
196 profile->save();
197}
198
199void
200general_settings_view_show_profile(GeneralSettingsView *self, gboolean show_profile)
201{
202 g_return_if_fail(GENERAL_SETTINGS_VIEW(self));
203 GeneralSettingsViewPrivate *priv = GENERAL_SETTINGS_VIEW_GET_PRIVATE(self);
204
205 /* We will construct and destroy the profile (AvatarManipulation widget) each time the profile
206 * should be visible and hidden, respectively. It is not the "prettiest" way of doing things,
207 * but this way we ensure 1. that the profile is updated correctly when it is shown and 2. that
208 * the VideoWidget inside is destroyed when it is not being shown.
209 */
210 if (show_profile) {
211 /* avatar manipulation widget */
212 priv->avatarmanipulation = avatar_manipulation_new();
213 gtk_box_pack_start(GTK_BOX(priv->box_profil_settings), priv->avatarmanipulation, true, true, 0);
214 gtk_widget_set_visible(priv->avatarmanipulation, true);
215
216 /* print the profile name. as long as we have only one profil, profil name = person name (a.k.a formatedName) */
217 priv->profile_name = gtk_entry_new();
218 gtk_entry_set_text (GTK_ENTRY(priv->profile_name),
219 ProfileModel::instance().selectedProfile()->person()->formattedName().toUtf8().constData());
220 gtk_widget_set_visible(priv->profile_name, true);
221 gtk_entry_set_alignment(GTK_ENTRY(priv->profile_name), 0.5);
222 gtk_box_pack_start(GTK_BOX(priv->box_profil_settings), priv->profile_name, true, true, 0);
223 g_signal_connect(priv->profile_name, "changed", G_CALLBACK(change_profile_name), NULL);
224 } else {
225 if (priv->avatarmanipulation) {
226 gtk_container_remove(GTK_CONTAINER(priv->box_profil_settings), priv->avatarmanipulation);
227 priv->avatarmanipulation = nullptr;
228 }
229 if (priv->profile_name) {
230 gtk_container_remove(GTK_CONTAINER(priv->box_profil_settings), priv->profile_name);
231 priv->profile_name = nullptr;
232 }
233 }
234}