1 // Copyright (C) 2010-2015 Petr Pavlu <setup@dagobah.cz>
3 // This file is part of CenterIM.
5 // CenterIM 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 2 of the License, or
8 // (at your option) any later version.
10 // CenterIM 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.
15 // You should have received a copy of the GNU General Public License
16 // along with CenterIM. If not, see <http://www.gnu.org/licenses/>.
25 Notify
*Notify::my_instance_
= nullptr;
27 Notify
*Notify::instance()
32 Notify::UserInfoDialog::UserInfoDialog(const char *title
) : SplitDialog(title
)
34 setColorScheme(CenterIM::SCHEME_GENERALWINDOW
);
36 treeview_
= new CppConsUI::TreeView(AUTOSIZE
, AUTOSIZE
);
37 setContainer(*treeview_
);
40 _("Done"), sigc::hide(sigc::mem_fun(this, &UserInfoDialog::close
)));
45 void Notify::UserInfoDialog::onScreenResized()
47 moveResizeRect(CENTERIM
->getScreenArea(CenterIM::CHAT_AREA
));
50 void Notify::UserInfoDialog::update(
51 PurpleConnection
*gc
, const char *who
, PurpleNotifyUserInfo
*user_info
)
54 CppConsUI::TreeView::NodeReference parent
;
55 CppConsUI::Button
*button
;
58 PurpleAccount
*account
= purple_connection_get_account(gc
);
59 PurpleBuddy
*buddy
= purple_find_buddy(account
, who
);
60 if (buddy
!= nullptr) {
61 // Note that we should always be able to find the specified buddy, unless
62 // something goes very wrong.
64 new CppConsUI::TreeView::ToggleCollapseButton(_("Local information"));
65 parent
= treeview_
->appendNode(treeview_
->getRootNode(), *button
);
67 button
= new CppConsUI::Button(
68 CppConsUI::Button::FLAG_VALUE
, _("Alias"), purple_buddy_get_alias(buddy
));
69 treeview_
->appendNode(parent
, *button
);
73 const char *formatted_time
;
76 if (PURPLE_BUDDY_IS_ONLINE(buddy
))
77 formatted_time
= _("Now");
79 saved_time
= static_cast<time_t>(
80 purple_blist_node_get_int(PURPLE_BLIST_NODE(buddy
), "last_seen"));
81 if (saved_time
!= 0 && localtime_r(&saved_time
, &local_time
) != nullptr)
82 formatted_time
= purple_date_format_long(&local_time
);
84 formatted_time
= _("Unknown");
86 button
= new CppConsUI::Button(
87 CppConsUI::Button::FLAG_VALUE
, _("Last seen"), formatted_time
);
88 treeview_
->appendNode(parent
, *button
);
91 saved_time
= static_cast<time_t>(
92 purple_blist_node_get_int(PURPLE_BLIST_NODE(buddy
), "last_activity"));
93 if (saved_time
!= 0 && localtime_r(&saved_time
, &local_time
) != nullptr)
94 formatted_time
= purple_date_format_long(&local_time
);
96 formatted_time
= _("Unknown");
97 button
= new CppConsUI::Button(
98 CppConsUI::Button::FLAG_VALUE
, _("Last activity"), formatted_time
);
99 treeview_
->appendNode(parent
, *button
);
102 // Remote information.
104 new CppConsUI::TreeView::ToggleCollapseButton(_("Remote information"));
105 parent
= treeview_
->appendNode(treeview_
->getRootNode(), *button
);
106 CppConsUI::TreeView::NodeReference subparent
= parent
;
107 for (GList
*i
= purple_notify_user_info_get_entries(user_info
); i
!= nullptr;
109 PurpleNotifyUserInfoEntry
*entry
=
110 reinterpret_cast<PurpleNotifyUserInfoEntry
*>(i
->data
);
111 PurpleNotifyUserInfoEntryType type
=
112 purple_notify_user_info_entry_get_type(entry
);
114 const char *label
= purple_notify_user_info_entry_get_label(entry
);
115 if (label
== nullptr)
117 const char *value
= purple_notify_user_info_entry_get_value(entry
);
118 char *nohtml
= purple_markup_strip_html(value
);
120 case PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR
:
121 button
= new CppConsUI::Button(
122 nohtml
? CppConsUI::Button::FLAG_VALUE
: 0, label
, nohtml
);
123 treeview_
->appendNode(subparent
, *button
);
125 case PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK
:
126 // Ignore section breaks.
128 case PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER
:
129 button
= new CppConsUI::TreeView::ToggleCollapseButton(label
);
130 subparent
= treeview_
->appendNode(parent
, *button
);
133 LOG
->error(_("Unhandled userinfo entry type '%d'."), type
);
139 treeview_
->grabFocus();
144 std::memset(¢erim_notify_ui_ops_
, 0, sizeof(centerim_notify_ui_ops_
));
146 // Set the purple notify callbacks.
147 centerim_notify_ui_ops_
.notify_message
= notify_message_
;
148 // centerim_notify_ui_ops_.notify_email = notify_email_;
149 // centerim_notify_ui_ops_.notify_emails = notify_emails_;
150 // centerim_notify_ui_ops_.notify_formatted = notify_formatted_;
151 // centerim_notify_ui_ops_.notify_searchresults = notify_searchresults_;
152 // centerim_notify_ui_ops_.notify_searchresults_new_rows =
153 // notify_searchresults_new_rows_;
154 centerim_notify_ui_ops_
.notify_userinfo
= notify_userinfo_
;
155 // centerim_notify_ui_ops_.notify_uri = notify_uri_;
156 centerim_notify_ui_ops_
.close_notify
= close_notify_
;
157 purple_notify_set_ui_ops(¢erim_notify_ui_ops_
);
162 purple_notify_set_ui_ops(nullptr);
167 g_assert(my_instance_
== nullptr);
169 my_instance_
= new Notify
;
172 void Notify::finalize()
174 g_assert(my_instance_
!= nullptr);
177 my_instance_
= nullptr;
180 void Notify::onDialogClose(CppConsUI::Window
&activator
, PurpleNotifyType type
)
182 CppConsUI::AbstractDialog
*dialog
=
183 dynamic_cast<CppConsUI::AbstractDialog
*>(&activator
);
184 g_assert(dialog
!= nullptr);
186 if (notifications_
.find(dialog
) == notifications_
.end())
189 notifications_
.erase(dialog
);
190 purple_notify_close(type
, dialog
);
193 void Notify::onUserInfoDialogClose(CppConsUI::Window
& /*activator*/, User user
)
195 // The userinfo dialog is gone.
196 user_infos_
.erase(user
);
199 void *Notify::notify_message(PurpleNotifyMsgType
/*type*/, const char *title
,
200 const char *primary
, const char *secondary
)
202 char *text
= g_strdup_printf("%s\n\n%s", primary
, secondary
);
203 auto dialog
= new CppConsUI::MessageDialog(title
, text
);
205 dialog
->signal_close
.connect(sigc::bind(
206 sigc::mem_fun(this, &Notify::onDialogClose
), PURPLE_NOTIFY_MESSAGE
));
209 notifications_
.insert(dialog
);
213 void *Notify::notify_userinfo(
214 PurpleConnection
*gc
, const char *who
, PurpleNotifyUserInfo
*user_info
)
216 User
user(purple_connection_get_account(gc
), who
);
217 UserInfos::iterator i
= user_infos_
.find(user
);
218 UserInfoDialog
*dialog
;
219 if (i
== user_infos_
.end()) {
220 // Create a new dialog to display this user info.
221 char *title
= g_strdup_printf(_("User information for %s"), who
);
222 dialog
= new UserInfoDialog(title
);
225 dialog
->signal_close
.connect(
226 sigc::bind(sigc::mem_fun(this, &Notify::onUserInfoDialogClose
), user
));
227 dialog
->signal_close
.connect(sigc::bind(
228 sigc::mem_fun(this, &Notify::onDialogClose
), PURPLE_NOTIFY_USERINFO
));
231 notifications_
.insert(dialog
);
232 user_infos_
[user
] = dialog
;
235 // Update already opened dialog.
239 dialog
->update(gc
, who
, user_info
);
243 void Notify::close_notify(PurpleNotifyType type
, void *ui_handle
)
245 // Only some notifications are currently supported.
246 g_assert(type
== PURPLE_NOTIFY_MESSAGE
|| type
== PURPLE_NOTIFY_USERINFO
);
248 CppConsUI::AbstractDialog
*dialog
=
249 reinterpret_cast<CppConsUI::AbstractDialog
*>(ui_handle
);
250 if (notifications_
.find(dialog
) == notifications_
.end())
253 notifications_
.erase(dialog
);
254 // Close the notification dialog if one is still opened.
258 // vim: set tabstop=2 shiftwidth=2 textwidth=80 expandtab: