diff options
author | Gary Kramlich <grim@reaperworld.com> | 2022-05-06 00:37:05 -0500 |
---|---|---|
committer | Gary Kramlich <grim@reaperworld.com> | 2022-05-06 00:37:05 -0500 |
commit | 30361d4f644501570a336eea22c0c8c9193beab5 (patch) | |
tree | 7bc7983a4f2d5e2f921b09430c8fc4d6149e4c0a /pidgin/pidginstatuseditor.c | |
parent | 4c73b14dc59f97f4d353aecd6c57991452aa4a48 (diff) | |
download | pidgin-30361d4f644501570a336eea22c0c8c9193beab5.tar.gz |
Add a new templated PidginStatusEditor and wire it up.
The substatuses were ignored for now as their future remains unclear. This
greatly simplified this widget.
Testing Done:
Tested everything I could think of in the UI as well as ran the docs without issue.
Reviewed at https://reviews.imfreedom.org/r/1363/
Diffstat (limited to 'pidgin/pidginstatuseditor.c')
-rw-r--r-- | pidgin/pidginstatuseditor.c | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/pidgin/pidginstatuseditor.c b/pidgin/pidginstatuseditor.c new file mode 100644 index 0000000000..51b2800db2 --- /dev/null +++ b/pidgin/pidginstatuseditor.c @@ -0,0 +1,297 @@ +/* + * Pidgin - Internet Messenger + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * + * Pidgin is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * 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 2 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, see <https://www.gnu.org/licenses/>. + */ + +#include <talkatu/talkatu.h> + +#include "pidginstatuseditor.h" + +#include "pidginstatusprimitivechooser.h" + +enum { + PROP_0, + PROP_STATUS, + N_PROPERTIES +}; +static GParamSpec *properties[N_PROPERTIES] = {NULL, }; + +enum { + RESPONSE_USE, + RESPONSE_SAVE +}; + +struct _PidginStatusEditor { + GtkDialog parent; + + PurpleSavedStatus *status; + + GtkTextBuffer *buffer; + + GtkWidget *title; + GtkWidget *primitive; + GtkWidget *message; + + GtkWidget *use; + GtkWidget *save; +}; + +G_DEFINE_TYPE(PidginStatusEditor, pidgin_status_editor, GTK_TYPE_DIALOG) + +/****************************************************************************** + * Helpers + *****************************************************************************/ +static void +pidgin_status_editor_set_status(PidginStatusEditor *editor, + PurpleSavedStatus *status) +{ + PurpleStatusPrimitive primitive; + PidginStatusPrimitiveChooser *chooser = NULL; + const gchar *title = NULL, *message = NULL; + + editor->status = status; + + if(editor->status != NULL) { + title = purple_savedstatus_get_title(editor->status); + primitive = purple_savedstatus_get_primitive_type(editor->status); + message = purple_savedstatus_get_message(editor->status); + } else { + primitive = PURPLE_STATUS_AWAY; + } + + if(title == NULL) { + title = ""; + } + + if(message == NULL) { + message = ""; + } + + gtk_entry_set_text(GTK_ENTRY(editor->title), title); + chooser = PIDGIN_STATUS_PRIMITIVE_CHOOSER(editor->primitive); + pidgin_status_primitive_chooser_set_selected(chooser, primitive); + talkatu_markup_set_html(TALKATU_BUFFER(editor->buffer), message, -1); + + g_object_notify_by_pspec(G_OBJECT(editor), properties[PROP_STATUS]); +} + +static void +pidgin_status_editor_save_status(PidginStatusEditor *editor) { + PidginStatusPrimitiveChooser *chooser = NULL; + PurpleStatusPrimitive primitive; + gchar *message = NULL; + const gchar *title = NULL; + + title = gtk_entry_get_text(GTK_ENTRY(editor->title)); + + chooser = PIDGIN_STATUS_PRIMITIVE_CHOOSER(editor->primitive); + primitive = pidgin_status_primitive_chooser_get_selected(chooser); + + message = talkatu_markup_get_html(editor->buffer, NULL); + + if(editor->status == NULL) { + editor->status = purple_savedstatus_new(title, primitive); + } else { + const gchar *current_title = NULL; + + /* purple_savedstatus_set_title throws a warning if you try to save a + * status with an existing title, which means we can't just save the + * title if it hasn't changed. + */ + current_title = purple_savedstatus_get_title(editor->status); + if(!purple_strequal(title, current_title)) { + purple_savedstatus_set_title(editor->status, title); + } + + purple_savedstatus_set_primitive_type(editor->status, primitive); + } + + purple_savedstatus_set_message(editor->status, message); + + g_free(message); +} + +/****************************************************************************** + * Callbacks + *****************************************************************************/ +static void +pidgin_status_editor_response_cb(GtkDialog *dialog, gint response_id, + gpointer data) +{ + PidginStatusEditor *editor = data; + + switch(response_id) { + case RESPONSE_USE: + pidgin_status_editor_save_status(editor); + purple_savedstatus_activate(editor->status); + break; + case RESPONSE_SAVE: + pidgin_status_editor_save_status(editor); + break; + } + + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + +static void +pidgin_status_editor_title_changed_cb(GtkEditable *editable, gpointer data) { + PidginStatusEditor *editor = data; + gboolean title_changed = FALSE, sensitive = FALSE; + const gchar *title = NULL; + + title = gtk_entry_get_text(GTK_ENTRY(editor->title)); + + if(editor->status != NULL) { + /* If we're editing a status, check if the title is the same. */ + title_changed = !purple_strequal(title, + purple_savedstatus_get_title(editor->status)); + } else { + /* If this is a new status, check if the title is empty or not. */ + title_changed = !purple_strequal(title, ""); + } + + if(title_changed) { + gboolean duplicated = purple_savedstatus_find(title) != NULL; + + if(duplicated) { + gtk_widget_set_sensitive(editor->use, FALSE); + gtk_widget_set_sensitive(editor->save, FALSE); + + return; + } + } + + sensitive = !purple_strequal(title, ""); + + gtk_widget_set_sensitive(editor->use, sensitive); + gtk_widget_set_sensitive(editor->save, sensitive); +} + +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +static void +pidgin_status_editor_get_property(GObject *obj, guint param_id, GValue *value, + GParamSpec *pspec) +{ + PidginStatusEditor *editor = PIDGIN_STATUS_EDITOR(obj); + + switch(param_id) { + case PROP_STATUS: + g_value_set_pointer(value, + pidgin_status_editor_get_status(editor)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +pidgin_status_editor_set_property(GObject *obj, guint param_id, + const GValue *value, GParamSpec *pspec) +{ + PidginStatusEditor *editor = PIDGIN_STATUS_EDITOR(obj); + + switch(param_id) { + case PROP_STATUS: + pidgin_status_editor_set_status(editor, + g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +pidgin_status_editor_init(PidginStatusEditor *manager) { + gtk_widget_init_template(GTK_WIDGET(manager)); +} + +static void +pidgin_status_editor_class_init(PidginStatusEditorClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + + obj_class->get_property = pidgin_status_editor_get_property; + obj_class->set_property = pidgin_status_editor_set_property; + + /** + * PidginStatusEditor::status: + * + * The [type@Purple.SavedStatus] that this editor is responsible for. + * This may be %NULL if it is creating a new status. + * + * Since: 3.0.0. + */ + /* we don't used boxed here because of the way status are currently + * managed. + */ + properties[PROP_STATUS] = g_param_spec_pointer( + "status", "status", + "The saved status we're editing", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); + + gtk_widget_class_set_template_from_resource( + widget_class, + "/im/pidgin/Pidgin3/Status/editor.ui" + ); + + gtk_widget_class_bind_template_child(widget_class, PidginStatusEditor, + buffer); + + gtk_widget_class_bind_template_child(widget_class, PidginStatusEditor, + title); + gtk_widget_class_bind_template_child(widget_class, PidginStatusEditor, + primitive); + gtk_widget_class_bind_template_child(widget_class, PidginStatusEditor, + message); + + gtk_widget_class_bind_template_child(widget_class, PidginStatusEditor, + use); + gtk_widget_class_bind_template_child(widget_class, PidginStatusEditor, + save); + + gtk_widget_class_bind_template_callback(widget_class, + pidgin_status_editor_response_cb); + gtk_widget_class_bind_template_callback(widget_class, + pidgin_status_editor_title_changed_cb); +} + +/****************************************************************************** + * Public API + *****************************************************************************/ +GtkWidget * +pidgin_status_editor_new(PurpleSavedStatus *status) { + return g_object_new( + PIDGIN_TYPE_STATUS_EDITOR, + "status", status, + NULL); +} + +PurpleSavedStatus * +pidgin_status_editor_get_status(PidginStatusEditor *editor) { + g_return_val_if_fail(PIDGIN_IS_STATUS_EDITOR(editor), NULL); + + return editor->status; +} |