pidgin/pidgin

Modernize XMPP console a bit

21 months ago, Elliott Sales de Andrade
fd32ea10d1cb
Parents eba22f6af173
Children 0a37c380d760
Modernize XMPP console a bit

Convert `GtkComboBox` to `GtkDropDown`.

Changed the invalid XML entry to use error underline instead of the custom CSS background. Unfortunately, the upstream `error` CSS does not apply to a `TextView `, so this was the better alternative.

Fixed alignment on the `` popover.

Add a bit of vertical padding and suggested action CSS in popovers.

Inline some objects in the .ui now that `` can contain children.
Consequently, the popover is closed with `gtk_menu_button_popdown` instead of `gtk_popover_popdown`. I don't know if it makes a difference, but it _seems_ better to use the parent's method instead of the child's.

Testing Done:
Opened XMPP console, picked some of the automated entries, changed to invalid XML to check the invalid styling.

Reviewed at https://reviews.imfreedom.org/r/1714/
--- a/pidgin/plugins/xmppconsole/console.ui Mon Sep 05 22:34:45 2022 -0500
+++ b/pidgin/plugins/xmppconsole/console.ui Mon Sep 05 23:36:14 2022 -0500
@@ -26,75 +26,72 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
- <object class="PidginAccountStore" id="accounts"/>
- <object class="PidginAccountFilterConnected" id="connected_accounts">
- <property name="child-model">accounts</property>
- </object>
- <object class="PidginAccountFilterProtocol" id="connected_xmpp_accounts">
- <property name="child-model">connected_accounts</property>
- <property name="protocol-id">prpl-jabber</property>
- </object>
<object class="GtkTextBuffer" id="entry_buffer">
<signal name="changed" handler="entry_changed_cb" object="PidginXmppConsole" swapped="no"/>
- </object>
- <object class="GtkAdjustment" id="presence.priority_adjustment">
- <property name="lower">-128</property>
- <property name="upper">127</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkTextTagTable" id="tags.table">
- <child type="tag">
- <object class="GtkTextTag" id="tags.info">
- <property name="foreground_rgba">rgb(119,119,119)</property>
- </object>
- </child>
- <child type="tag">
- <object class="GtkTextTag" id="tags.incoming">
- <property name="paragraph_background_rgba">rgb(255,206,206)</property>
- </object>
- </child>
- <child type="tag">
- <object class="GtkTextTag" id="tags.outgoing">
- <property name="paragraph_background_rgba">rgb(220,236,196)</property>
+ <property name="tag-table">
+ <object class="GtkTextTagTable">
+ <child type="tag">
+ <object class="GtkTextTag">
+ <property name="name">invalid</property>
+ <property name="underline">PANGO_UNDERLINE_ERROR</property>
+ </object>
+ </child>
</object>
- </child>
- <child type="tag">
- <object class="GtkTextTag" id="tags.bracket">
- <property name="foreground_rgba">rgb(148,15,140)</property>
- </object>
- </child>
- <child type="tag">
- <object class="GtkTextTag" id="tags.tag">
- <property name="foreground_rgba">rgb(139,29,171)</property>
- <property name="weight">700</property>
- </object>
- </child>
- <child type="tag">
- <object class="GtkTextTag" id="tags.attr">
- <property name="foreground_rgba">rgb(160,41,97)</property>
- <property name="weight">700</property>
- </object>
- </child>
- <child type="tag">
- <object class="GtkTextTag" id="tags.value">
- <property name="foreground_rgba">rgb(50,74,164)</property>
- </object>
- </child>
- <child type="tag">
- <object class="GtkTextTag" id="tags.xmlns">
- <property name="foreground_rgba">rgb(44,177,47)</property>
- <property name="weight">700</property>
- </object>
- </child>
+ </property>
</object>
<object class="GtkTextBuffer" id="buffer">
- <property name="tag_table">tags.table</property>
+ <property name="tag-table">
+ <object class="GtkTextTagTable">
+ <child type="tag">
+ <object class="GtkTextTag" id="tags.info">
+ <property name="foreground-rgba">rgb(119,119,119)</property>
+ </object>
+ </child>
+ <child type="tag">
+ <object class="GtkTextTag" id="tags.incoming">
+ <property name="paragraph-background-rgba">rgb(255,206,206)</property>
+ </object>
+ </child>
+ <child type="tag">
+ <object class="GtkTextTag" id="tags.outgoing">
+ <property name="paragraph-background-rgba">rgb(220,236,196)</property>
+ </object>
+ </child>
+ <child type="tag">
+ <object class="GtkTextTag" id="tags.bracket">
+ <property name="foreground-rgba">rgb(148,15,140)</property>
+ </object>
+ </child>
+ <child type="tag">
+ <object class="GtkTextTag" id="tags.tag">
+ <property name="foreground-rgba">rgb(139,29,171)</property>
+ <property name="weight">700</property>
+ </object>
+ </child>
+ <child type="tag">
+ <object class="GtkTextTag" id="tags.attr">
+ <property name="foreground-rgba">rgb(160,41,97)</property>
+ <property name="weight">700</property>
+ </object>
+ </child>
+ <child type="tag">
+ <object class="GtkTextTag" id="tags.value">
+ <property name="foreground-rgba">rgb(50,74,164)</property>
+ </object>
+ </child>
+ <child type="tag">
+ <object class="GtkTextTag" id="tags.xmlns">
+ <property name="foreground-rgba">rgb(44,177,47)</property>
+ <property name="weight">700</property>
+ </object>
+ </child>
+ </object>
+ </property>
</object>
<template parent="GtkWindow" class="PidginXmppConsole">
- <property name="title" translatable="yes">XMPP Console</property>
- <property name="default_width">580</property>
- <property name="default_height">400</property>
+ <property name="title" translatable="1">XMPP Console</property>
+ <property name="default-width">580</property>
+ <property name="default-height">400</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
@@ -104,12 +101,23 @@
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
- <property name="label" translatable="yes">Account:</property>
+ <property name="label" translatable="1">Account:</property>
</object>
</child>
<child>
- <object class="PidginAccountChooser">
- <property name="model">connected_xmpp_accounts</property>
+ <object class="PidginAccountChooser" id="account_chooser">
+ <property name="model">
+ <object class="PidginAccountFilterProtocol">
+ <property name="child-model">
+ <object class="PidginAccountFilterConnected">
+ <property name="child-model">
+ <object class="PidginAccountStore"/>
+ </property>
+ </object>
+ </property>
+ <property name="protocol-id">prpl-jabber</property>
+ </object>
+ </property>
<property name="active">0</property>
<property name="hexpand">1</property>
<signal name="changed" handler="dropdown_changed_cb" object="PidginXmppConsole" swapped="no"/>
@@ -125,7 +133,7 @@
<object class="GtkTextView">
<property name="focusable">1</property>
<property name="editable">0</property>
- <property name="wrap_mode">word</property>
+ <property name="wrap-mode">word</property>
<property name="buffer">buffer</property>
</object>
</property>
@@ -133,25 +141,384 @@
</child>
<child>
<object class="GtkBox">
- <style>
- <class name="toolbar"/>
- </style>
+ <property name="css-classes">toolbar</property>
<child>
- <object class="GtkMenuButton">
+ <object class="GtkMenuButton" id="iq.button">
<property name="label">&lt;iq/&gt;</property>
- <property name="popover">iq.popover</property>
+ <property name="popover">
+ <object class="GtkPopover">
+ <property name="position">right</property>
+ <property name="child">
+ <object class="GtkGrid">
+ <property name="column-spacing">6</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">To:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">Type:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="iq.to">
+ <property name="focusable">1</property>
+ <property name="activates-default">1</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkDropDown" id="iq.type">
+ <property name="selected">0</property>
+ <property name="model">
+ <object class="GtkStringList">
+ <items>
+ <item>get</item>
+ <item>set</item>
+ <item>result</item>
+ <item>error</item>
+ </items>
+ </object>
+ </property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="label" translatable="1">Insert</property>
+ <property name="focusable">1</property>
+ <property name="receives-default">1</property>
+ <property name="css-classes">suggested-action</property>
+ <signal name="clicked" handler="iq_clicked_cb" swapped="no"/>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">2</property>
+ <property name="column-span">2</property>
+ </layout>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </property>
</object>
</child>
<child>
- <object class="GtkMenuButton">
+ <object class="GtkMenuButton" id="presence.button">
<property name="label">&lt;presence/&gt;</property>
- <property name="popover">presence.popover</property>
+ <property name="popover">
+ <object class="GtkPopover">
+ <property name="position">right</property>
+ <property name="child">
+ <object class="GtkGrid">
+ <property name="column-spacing">6</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">To:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">Type:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">Show:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">2</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">Status:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">3</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">Priority:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">4</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="presence.to">
+ <property name="focusable">1</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkDropDown" id="presence.type">
+ <property name="selected">0</property>
+ <property name="model">
+ <object class="GtkStringList">
+ <items>
+ <item>default</item>
+ <item>unavailable</item>
+ <item>subscribe</item>
+ <item>unsubscribe</item>
+ <item>subscribed</item>
+ <item>unsubscribed</item>
+ <item>probe</item>
+ <item>error</item>
+ </items>
+ </object>
+ </property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkDropDown" id="presence.show">
+ <property name="selected">0</property>
+ <property name="model">
+ <object class="GtkStringList">
+ <items>
+ <item>default</item>
+ <item>away</item>
+ <item>dnd</item>
+ <item>xa</item>
+ <item>chat</item>
+ </items>
+ </object>
+ </property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">2</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="presence.status">
+ <property name="focusable">1</property>
+ <property name="activates-default">1</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">3</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="presence.priority">
+ <property name="focusable">1</property>
+ <property name="adjustment">
+ <object class="GtkAdjustment">
+ <property name="lower">-128</property>
+ <property name="upper">127</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ </property>
+ <property name="numeric">1</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">4</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="label" translatable="1">Insert</property>
+ <property name="focusable">1</property>
+ <property name="receives-default">1</property>
+ <property name="css-classes">suggested-action</property>
+ <signal name="clicked" handler="presence_clicked_cb" swapped="no"/>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">5</property>
+ <property name="column-span">2</property>
+ </layout>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </property>
</object>
</child>
<child>
- <object class="GtkMenuButton">
+ <object class="GtkMenuButton" id="message.button">
<property name="label">&lt;message/&gt;</property>
- <property name="popover">message.popover</property>
+ <property name="popover">
+ <object class="GtkPopover">
+ <property name="position">right</property>
+ <property name="child">
+ <object class="GtkGrid">
+ <property name="column-spacing">6</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">To:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">Type:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">Body:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">2</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">Subject:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">3</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="1">Thread:</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">4</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="message.to">
+ <property name="focusable">1</property>
+ <property name="activates-default">1</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="message.body">
+ <property name="focusable">1</property>
+ <property name="activates-default">1</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">2</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="message.subject">
+ <property name="focusable">1</property>
+ <property name="activates-default">1</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">3</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="message.thread">
+ <property name="focusable">1</property>
+ <property name="activates-default">1</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">4</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="label" translatable="1">Insert</property>
+ <property name="focusable">1</property>
+ <property name="receives-default">1</property>
+ <property name="css-classes">suggested-action</property>
+ <signal name="clicked" handler="message_clicked_cb" swapped="no"/>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">5</property>
+ <property name="column-span">2</property>
+ </layout>
+ </object>
+ </child>
+ <child>
+ <object class="GtkDropDown" id="message.type">
+ <property name="selected">0</property>
+ <property name="model">
+ <object class="GtkStringList">
+ <items>
+ <item>chat</item>
+ <item>headline</item>
+ <item>groupchat</item>
+ <item>normal</item>
+ <item>error</item>
+ </items>
+ </object>
+ </property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </property>
</object>
</child>
</object>
@@ -162,7 +529,7 @@
<property name="child">
<object class="GtkTextView" id="entry">
<property name="focusable">1</property>
- <property name="wrap_mode">word</property>
+ <property name="wrap-mode">word</property>
<property name="buffer">entry_buffer</property>
<child>
<object class="GtkEventControllerKey">
@@ -176,331 +543,4 @@
</object>
</property>
</template>
- <object class="GtkPopover" id="iq.popover">
- <property name="position">right</property>
- <property name="child">
- <object class="GtkGrid">
- <property name="column_spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">To:</property>
- <layout>
- <property name="column">0</property>
- <property name="row">0</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Type:</property>
- <layout>
- <property name="column">0</property>
- <property name="row">1</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkEntry" id="iq.to">
- <property name="focusable">1</property>
- <property name="activates_default">1</property>
- <layout>
- <property name="column">1</property>
- <property name="row">0</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkComboBoxText" id="iq.type">
- <property name="active">0</property>
- <items>
- <item>get</item>
- <item>set</item>
- <item>result</item>
- <item>error</item>
- </items>
- <layout>
- <property name="column">1</property>
- <property name="row">1</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="label" translatable="yes">Insert</property>
- <property name="focusable">1</property>
- <property name="receives_default">1</property>
- <signal name="clicked" handler="iq_clicked_cb" swapped="no"/>
- <layout>
- <property name="column">0</property>
- <property name="row">2</property>
- <property name="column-span">2</property>
- </layout>
- </object>
- </child>
- </object>
- </property>
- </object>
- <object class="GtkPopover" id="message.popover">
- <property name="position">right</property>
- <property name="child">
- <object class="GtkGrid">
- <property name="column_spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">To:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">0</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Type:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">1</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Body:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">2</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Subject:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">3</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Thread:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">4</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkEntry" id="message.to">
- <property name="focusable">1</property>
- <property name="activates_default">1</property>
- <layout>
- <property name="column">1</property>
- <property name="row">0</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkEntry" id="message.body">
- <property name="focusable">1</property>
- <property name="activates_default">1</property>
- <layout>
- <property name="column">1</property>
- <property name="row">2</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkEntry" id="message.subject">
- <property name="focusable">1</property>
- <property name="activates_default">1</property>
- <layout>
- <property name="column">1</property>
- <property name="row">3</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkEntry" id="message.thread">
- <property name="focusable">1</property>
- <property name="activates_default">1</property>
- <layout>
- <property name="column">1</property>
- <property name="row">4</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="label" translatable="yes">Insert</property>
- <property name="focusable">1</property>
- <property name="receives_default">1</property>
- <signal name="clicked" handler="message_clicked_cb" swapped="no"/>
- <layout>
- <property name="column">0</property>
- <property name="row">5</property>
- <property name="column-span">2</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkComboBoxText" id="message.type">
- <property name="active">0</property>
- <items>
- <item>chat</item>
- <item>headline</item>
- <item>groupchat</item>
- <item>normal</item>
- <item>error</item>
- </items>
- <layout>
- <property name="column">1</property>
- <property name="row">1</property>
- </layout>
- </object>
- </child>
- </object>
- </property>
- </object>
- <object class="GtkPopover" id="presence.popover">
- <property name="position">right</property>
- <property name="child">
- <object class="GtkGrid">
- <property name="column_spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">To:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">0</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Type:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">1</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Show:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">2</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Status:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">3</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Priority:</property>
- <property name="xalign">0</property>
- <layout>
- <property name="column">0</property>
- <property name="row">4</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkEntry" id="presence.to">
- <property name="focusable">1</property>
- <layout>
- <property name="column">1</property>
- <property name="row">0</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkComboBoxText" id="presence.type">
- <property name="active">0</property>
- <items>
- <item>default</item>
- <item>unavailable</item>
- <item>subscribe</item>
- <item>unsubscribe</item>
- <item>subscribed</item>
- <item>unsubscribed</item>
- <item>probe</item>
- <item>error</item>
- </items>
- <layout>
- <property name="column">1</property>
- <property name="row">1</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkComboBoxText" id="presence.show">
- <property name="active">0</property>
- <items>
- <item>default</item>
- <item>away</item>
- <item>dnd</item>
- <item>xa</item>
- <item>chat</item>
- </items>
- <layout>
- <property name="column">1</property>
- <property name="row">2</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkEntry" id="presence.status">
- <property name="focusable">1</property>
- <property name="activates_default">1</property>
- <layout>
- <property name="column">1</property>
- <property name="row">3</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="label" translatable="yes">Insert</property>
- <property name="focusable">1</property>
- <property name="receives_default">1</property>
- <signal name="clicked" handler="presence_clicked_cb" swapped="no"/>
- <layout>
- <property name="column">0</property>
- <property name="row">5</property>
- <property name="column-span">2</property>
- </layout>
- </object>
- </child>
- <child>
- <object class="GtkSpinButton" id="presence.priority">
- <property name="focusable">1</property>
- <property name="adjustment">presence.priority_adjustment</property>
- <property name="numeric">1</property>
- <layout>
- <property name="column">1</property>
- <property name="row">4</property>
- </layout>
- </object>
- </child>
- </object>
- </property>
- </object>
</interface>
--- a/pidgin/plugins/xmppconsole/xmppconsole.c Mon Sep 05 22:34:45 2022 -0500
+++ b/pidgin/plugins/xmppconsole/xmppconsole.c Mon Sep 05 23:36:14 2022 -0500
@@ -35,6 +35,7 @@
struct _PidginXmppConsole {
GtkWindow parent;
+ GtkComboBox *account_chooser;
PurpleConnection *gc;
GtkTextBuffer *buffer;
struct {
@@ -52,24 +53,24 @@
GtkWidget *sw;
struct {
- GtkPopover *popover;
+ GtkMenuButton *button;
GtkEntry *to;
- GtkComboBoxText *type;
+ GtkDropDown *type;
} iq;
struct {
- GtkPopover *popover;
+ GtkMenuButton *button;
GtkEntry *to;
- GtkComboBoxText *type;
- GtkComboBoxText *show;
+ GtkDropDown *type;
+ GtkDropDown *show;
GtkEntry *status;
GtkEntry *priority;
} presence;
struct {
- GtkPopover *popover;
+ GtkMenuButton *button;
GtkEntry *to;
- GtkComboBoxText *type;
+ GtkDropDown *type;
GtkEntry *body;
GtkEntry *subject;
GtkEntry *thread;
@@ -265,7 +266,6 @@
int height;
int pad_top, pad_inside, pad_bottom;
PurpleXmlNode *node;
- GtkStyleContext *style;
wrapped_lines = 1;
gtk_text_buffer_get_start_iter(buffer, &iter);
@@ -298,11 +298,12 @@
xmlstr = g_strdup_printf("<xml>%s</xml>", str);
node = purple_xmlnode_from_str(xmlstr, -1);
- style = gtk_widget_get_style_context(console->entry);
if (node) {
- gtk_style_context_remove_class(style, "error");
+ gtk_text_buffer_remove_tag_by_name(console->entry_buffer, "invalid",
+ &start, &end);
} else {
- gtk_style_context_add_class(style, "error");
+ gtk_text_buffer_apply_tag_by_name(console->entry_buffer, "invalid",
+ &start, &end);
}
g_free(str);
g_free(xmlstr);
@@ -314,12 +315,17 @@
load_text_and_set_caret(PidginXmppConsole *console, const gchar *pre_text,
const gchar *post_text)
{
+ GtkTextIter start, end;
GtkTextIter where;
GtkTextMark *mark;
+ g_signal_handlers_block_by_func(console->entry_buffer, entry_changed_cb,
+ console);
gtk_text_buffer_begin_user_action(console->entry_buffer);
- gtk_text_buffer_set_text(console->entry_buffer, pre_text, -1);
+ gtk_text_buffer_get_bounds(console->entry_buffer, &start, &end);
+ gtk_text_buffer_delete(console->entry_buffer, &start, &end);
+ gtk_text_buffer_insert(console->entry_buffer, &end, pre_text, -1);
gtk_text_buffer_get_end_iter(console->entry_buffer, &where);
mark = gtk_text_buffer_create_mark(console->entry_buffer, NULL, &where, TRUE);
@@ -331,132 +337,148 @@
gtk_text_buffer_delete_mark(console->entry_buffer, mark);
gtk_text_buffer_end_user_action(console->entry_buffer);
+ g_signal_handlers_unblock_by_func(console->entry_buffer, entry_changed_cb,
+ console);
+
+ entry_changed_cb(console->entry_buffer, console);
}
static void
iq_clicked_cb(GtkWidget *w, gpointer data)
{
PidginXmppConsole *console = data;
- const gchar *to;
- char *stanza;
+ GtkStringObject *obj = NULL;
+ const gchar *to, *type;
+ gchar *stanza;
to = gtk_editable_get_text(GTK_EDITABLE(console->iq.to));
- stanza = g_strdup_printf(
- "<iq %s%s%s id='console%x' type='%s'>", to && *to ? "to='" : "",
- to && *to ? to : "", to && *to ? "'" : "", g_random_int(),
- gtk_combo_box_text_get_active_text(console->iq.type));
+ obj = gtk_drop_down_get_selected_item(console->iq.type);
+ type = gtk_string_object_get_string(obj);
+
+ if(to != NULL && *to != '\0') {
+ stanza = g_strdup_printf("<iq to='%s' id='console%x' type='%s'>",
+ to, g_random_int(), type);
+ } else {
+ stanza = g_strdup_printf("<iq id='console%x' type='%s'>",
+ g_random_int(), type);
+ }
+
load_text_and_set_caret(console, stanza, "</iq>");
gtk_widget_grab_focus(console->entry);
g_free(stanza);
/* Reset everything. */
gtk_editable_set_text(GTK_EDITABLE(console->iq.to), "");
- gtk_combo_box_set_active(GTK_COMBO_BOX(console->iq.type), 0);
- gtk_popover_popdown(console->iq.popover);
+ gtk_drop_down_set_selected(console->iq.type, 0);
+ gtk_menu_button_popdown(console->iq.button);
}
static void
presence_clicked_cb(GtkWidget *w, gpointer data)
{
PidginXmppConsole *console = data;
+ GtkStringObject *obj = NULL;
const gchar *to, *status, *priority;
- gchar *type, *show;
- char *stanza;
+ const gchar *type, *show;
+ GString *stanza = NULL;
to = gtk_editable_get_text(GTK_EDITABLE(console->presence.to));
- type = gtk_combo_box_text_get_active_text(console->presence.type);
+ obj = gtk_drop_down_get_selected_item(console->presence.type);
+ type = gtk_string_object_get_string(obj);
if (purple_strequal(type, "default")) {
- g_free(type);
- type = g_strdup("");
+ type = "";
}
- show = gtk_combo_box_text_get_active_text(console->presence.show);
+ obj = gtk_drop_down_get_selected_item(console->presence.show);
+ show = gtk_string_object_get_string(obj);
if (purple_strequal(show, "default")) {
- g_free(show);
- show = g_strdup("");
+ show = "";
}
status = gtk_editable_get_text(GTK_EDITABLE(console->presence.status));
priority = gtk_editable_get_text(GTK_EDITABLE(console->presence.priority));
- if (purple_strequal(priority, "0"))
+ if (purple_strequal(priority, "0")) {
priority = "";
+ }
- stanza = g_strdup_printf("<presence %s%s%s id='console%x' %s%s%s>"
- "%s%s%s%s%s%s%s%s%s",
- *to ? "to='" : "",
- *to ? to : "",
- *to ? "'" : "",
- g_random_int(),
-
- *type ? "type='" : "",
- *type ? type : "",
- *type ? "'" : "",
+ stanza = g_string_new("<presence");
+ if(*to != '\0') {
+ g_string_append_printf(stanza, " to='%s'", to);
+ }
+ g_string_append_printf(stanza, " id='console%x'", g_random_int());
+ if(*type != '\0') {
+ g_string_append_printf(stanza, " type='%s'", type);
+ }
+ g_string_append_c(stanza, '>');
- *show ? "<show>" : "",
- *show ? show : "",
- *show ? "</show>" : "",
+ if(*show != '\0') {
+ g_string_append_printf(stanza, "<show>%s</show>", show);
+ }
- *status ? "<status>" : "",
- *status ? status : "",
- *status ? "</status>" : "",
+ if(*status != '\0') {
+ g_string_append_printf(stanza, "<status>%s</status>", status);
+ }
- *priority ? "<priority>" : "",
- *priority ? priority : "",
- *priority ? "</priority>" : "");
+ if(*priority != '\0') {
+ g_string_append_printf(stanza, "<priority>%s</priority>", priority);
+ }
- load_text_and_set_caret(console, stanza, "</presence>");
+ load_text_and_set_caret(console, stanza->str, "</presence>");
gtk_widget_grab_focus(console->entry);
- g_free(stanza);
- g_free(type);
- g_free(show);
+ g_string_free(stanza, TRUE);
/* Reset everything. */
gtk_editable_set_text(GTK_EDITABLE(console->presence.to), "");
- gtk_combo_box_set_active(GTK_COMBO_BOX(console->presence.type), 0);
- gtk_combo_box_set_active(GTK_COMBO_BOX(console->presence.show), 0);
+ gtk_drop_down_set_selected(console->presence.type, 0);
+ gtk_drop_down_set_selected(console->presence.show, 0);
gtk_editable_set_text(GTK_EDITABLE(console->presence.status), "");
gtk_editable_set_text(GTK_EDITABLE(console->presence.priority), "0");
- gtk_popover_popdown(console->presence.popover);
+ gtk_menu_button_popdown(console->presence.button);
}
static void
message_clicked_cb(GtkWidget *w, gpointer data)
{
PidginXmppConsole *console = data;
- const gchar *to, *body, *thread, *subject;
- char *stanza;
+ GtkStringObject *obj = NULL;
+ const gchar *to, *body, *thread, *subject, *type;
+ GString *stanza = NULL;
to = gtk_editable_get_text(GTK_EDITABLE(console->message.to));
body = gtk_editable_get_text(GTK_EDITABLE(console->message.body));
thread = gtk_editable_get_text(GTK_EDITABLE(console->message.thread));
subject = gtk_editable_get_text(GTK_EDITABLE(console->message.subject));
+ obj = gtk_drop_down_get_selected_item(console->message.type);
+ type = gtk_string_object_get_string(obj);
- stanza = g_strdup_printf(
- "<message %s%s%s id='console%x' type='%s'>"
- "%s%s%s%s%s%s%s%s%s",
-
- *to ? "to='" : "", *to ? to : "", *to ? "'" : "",
- g_random_int(),
- gtk_combo_box_text_get_active_text(console->message.type),
+ stanza = g_string_new("<message");
+ if(*to != '\0') {
+ g_string_append_printf(stanza, " to='%s'", to);
+ }
+ g_string_append_printf(stanza, " id='console%x' type='%s'>",
+ g_random_int(), type);
- *body ? "<body>" : "", *body ? body : "",
- *body ? "</body>" : "",
+ if(*body != '\0') {
+ g_string_append_printf(stanza, "<body>%s</body>", body);
+ }
- *subject ? "<subject>" : "", *subject ? subject : "",
- *subject ? "</subject>" : "",
+ if(*subject != '\0') {
+ g_string_append_printf(stanza, "<subject>%s</subject>", subject);
+ }
- *thread ? "<thread>" : "", *thread ? thread : "",
- *thread ? "</thread>" : "");
+ if(*thread != '\0') {
+ g_string_append_printf(stanza, "<thread>%s</thread>", thread);
+ }
- load_text_and_set_caret(console, stanza, "</message>");
+ load_text_and_set_caret(console, stanza->str, "</message>");
gtk_widget_grab_focus(console->entry);
- g_free(stanza);
+ g_string_free(stanza, TRUE);
/* Reset everything. */
gtk_editable_set_text(GTK_EDITABLE(console->message.to), "");
- gtk_combo_box_set_active(GTK_COMBO_BOX(console->message.type), 0);
+ gtk_drop_down_set_selected(console->message.type, 0);
gtk_editable_set_text(GTK_EDITABLE(console->message.body), "");
gtk_editable_set_text(GTK_EDITABLE(console->message.subject), "0");
gtk_editable_set_text(GTK_EDITABLE(console->message.thread), "0");
- gtk_popover_popdown(console->message.popover);
+ gtk_menu_button_popdown(console->message.button);
}
static void
@@ -494,6 +516,8 @@
"/im/pidgin/Pidgin3/Plugin/XMPPConsole/console.ui"
);
+ gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
+ account_chooser);
gtk_widget_class_bind_template_callback(widget_class, dropdown_changed_cb);
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
@@ -517,7 +541,7 @@
/* Popover for <iq/> button. */
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
- iq.popover);
+ iq.button);
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
iq.to);
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
@@ -526,7 +550,7 @@
/* Popover for <presence/> button. */
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
- presence.popover);
+ presence.button);
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
presence.to);
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
@@ -541,7 +565,7 @@
/* Popover for <message/> button. */
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
- message.popover);
+ message.button);
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
message.to);
gtk_widget_class_bind_template_child(widget_class, PidginXmppConsole,
@@ -566,19 +590,9 @@
static void
pidgin_xmpp_console_init(PidginXmppConsole *console) {
- GtkCssProvider *entry_css;
- GtkStyleContext *context;
-
gtk_widget_init_template(GTK_WIDGET(console));
- entry_css = gtk_css_provider_new();
- gtk_css_provider_load_from_data(entry_css,
- "textview.error text {background-color:#ffcece;}",
- -1);
- context = gtk_widget_get_style_context(console->entry);
- gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(entry_css),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-
+ dropdown_changed_cb(console->account_chooser, console);
entry_changed_cb(console->entry_buffer, console);
gtk_widget_show(GTK_WIDGET(console));