1 // ========================================================================
2 // gnubiff -- a mail notification program
3 // Copyright (c) 2000-2009 Nicolas Rougier, 2004-2009 Robert Sowada
4 //
5 // This program is free software: you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation, either version 3 of the
8 // License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // 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, see <http://www.gnu.org/licenses/>.
17 // ========================================================================
18 //
19 // File : $RCSfile: ui-applet.cc,v $
20 // Revision : $Revision: 1.39.2.4 $
21 // Revision date : $Date: 2009/04/05 16:08:05 $
22 // Author(s) : Nicolas Rougier, Robert Sowada
23 // Short :
24 //
25 // This file is part of gnubiff.
26 //
27 // -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
28 // ========================================================================
29
30 #include <sstream>
31 #include <iomanip>
32 #include <cstdio>
33 #include <string>
34 #include <glib.h>
35
36 #include "mailbox.h"
37 #include "support.h"
38 #include "ui-applet.h"
39
40 /**
41 * Constructor.
42 *
43 * @param biff Pointer to the biff object of the current gnubiff session.
44 */
Applet(Biff * biff)45 Applet::Applet (Biff *biff)
46 {
47 biff_ = biff;
48 update_mutex_ = g_mutex_new ();
49 }
50
51 /// Destructor
~Applet(void)52 Applet::~Applet (void)
53 {
54 g_mutex_lock (update_mutex_);
55 g_mutex_unlock (update_mutex_);
56 g_mutex_free (update_mutex_);
57 }
58
59 /**
60 * Start the applet.
61 *
62 * @param showpref If true and supported by the frontend the preferences
63 * dialog is shown before monitoring starts (the default is
64 * false).
65 */
66 void
start(gboolean showpref)67 Applet::start (gboolean showpref)
68 {
69 if (!showpref)
70 if (biff_->value_uint ("check_mode") == AUTOMATIC_CHECK)
71 biff_->start_monitoring (3);
72 }
73
74 /**
75 * Update the applet status. If new messages are present the new
76 * mail command is executed.
77 *
78 * @param init True if called when initializing gnubiff (the default is
79 * false)
80 * @return True if new messages are present
81 */
82 gboolean
update(gboolean init)83 Applet::update (gboolean init)
84 {
85 #ifdef DEBUG
86 g_message ("Applet update");
87 #endif
88
89 // Check if there is new mail
90 guint unread = 0;
91 gboolean newmail = biff_->get_number_of_unread_messages (unread);
92
93 // New mail command
94 if ((newmail == true) && (unread > 0))
95 execute_command ("newmail_command", "use_newmail_command");
96
97 // Messages have been displayed now
98 biff_->messages_displayed ();
99
100 return newmail;
101 }
102
103 /**
104 * Mark all messages from all mailboxes as read and update the applet
105 * status. The config file is saved with the information which
106 * messages have been read.
107 */
108 void
mark_messages_as_read(void)109 Applet::mark_messages_as_read (void)
110 {
111 // Mark messages as read
112 biff_->mark_messages_as_read ();
113
114 // Save config file (especially the seen messages)
115 biff_->save ();
116
117 // Update the applet status
118 update ();
119 }
120
121 /**
122 * Execute a shell command that is stored in the biff string option
123 * {\em option_command} if the biff boolean option {\em option_use_command}
124 * is true.
125 *
126 * @param option_command Name of the biff string option that stores the
127 * command.
128 * @param option_use_command Name of the biff boolean option that indicates
129 * whether the command should be executed or not.
130 * If this string is empty the command will be
131 * executed (the default is the empty string).
132 */
133 void
execute_command(std::string option_command,std::string option_use_command)134 Applet::execute_command (std::string option_command,
135 std::string option_use_command)
136 {
137 // Shall the command be executed?
138 if ((!option_use_command.empty()) &&
139 (!(biff_->value_bool (option_use_command))))
140 return;
141 // Execute the command (if there is one).
142 std::string command = biff_->value_string (option_command);
143 if (!command.empty ()) {
144 command += " &";
145 int result = system (command.c_str ());
146 if (result == -1)
147 g_warning ("Cannot execute command \"%s\".", command.c_str());
148 }
149 }
150
151 /**
152 * Get the number of unread messages in all mailboxes as a string.
153 *
154 * @return Number of unread messages as a string.
155 */
156 std::string
get_number_of_unread_messages(void)157 Applet::get_number_of_unread_messages (void)
158 {
159 std::stringstream smax, text_zero, text_num;
160 std::string text;
161
162 // Get number of unread messages
163 guint unread;
164 biff_->get_number_of_unread_messages (unread);
165
166 // Zero padded number of unread messages
167 smax << biff_->value_uint ("max_mail");
168 text_zero << std::setfill('0') << std::setw (smax.str().size()) << unread;
169
170 // Number of unread messages
171 text_num << unread;
172
173 // Use the correct user supplied message to create the text
174 const std::string chars = "dD";
175 std::vector<std::string> vec(2);
176 vec[0] = text_zero.str (); // 'd'
177 vec[1] = text_num.str (); // 'D'
178 if (unread == 0)
179 text = substitute (biff_->value_string ("nomail_text"), chars, vec);
180 else if (unread < biff_->value_uint ("max_mail"))
181 text = substitute (biff_->value_string ("newmail_text"), chars, vec);
182 else {
183 vec[0] = std::string (std::string(smax.str().size(), '+'));
184 vec[1] = "+";
185 text = substitute (biff_->value_string ("newmail_text"), chars, vec);
186 }
187
188 return text;
189 }
190
191 /**
192 * Returns a string with a overview of the statuses of all
193 * mailboxes. Each mailbox's status is presented on a separate line,
194 * if there is no problem the number of unread messages is
195 * given. This text is suitable for displaying as a tooltip.
196 *
197 * @return String that contains the mailboxes' statuses.
198 */
199 std::string
get_mailbox_status_text(void)200 Applet::get_mailbox_status_text (void)
201 {
202 // Get max collected mail number in a stringstream
203 // just to have a default string size.
204 std::stringstream smax;
205 smax << biff_->value_uint ("max_mail");
206
207 std::string tooltip;
208 for (unsigned int i=0; i < biff_->get_number_of_mailboxes (); i++) {
209 if (i > 0)
210 tooltip += "\n";
211 // Mailbox's name
212 tooltip += biff_->mailbox(i)->name();
213 tooltip += ": ";
214
215 // No protocol?
216 if (biff_->mailbox(i)->protocol() == PROTOCOL_NONE) {
217 tooltip += _(" unknown");
218 continue;
219 }
220 // Error?
221 if (biff_->mailbox(i)->status() == MAILBOX_ERROR) {
222 tooltip += _(" error");
223 continue;
224 }
225 // Put number of unread messages in the current mailbox into a string
226 guint unread = biff_->mailbox(i)->unreads();
227 std::stringstream s;
228 s << std::setfill('0') << std::setw (smax.str().size()) << unread;
229 // Checking mailbox?
230 if (biff_->mailbox(i)->status() == MAILBOX_CHECK) {
231 tooltip += "(" + s.str() + ")" + _(" checking...");
232 continue;
233 }
234 // More unread messages in mailbox than got by gnubiff?
235 if (unread >= biff_->value_uint ("max_mail")) {
236 tooltip += std::string(smax.str().size(), '+');
237 continue;
238 }
239 // Just the number of unread messages
240 tooltip += s.str();
241 }
242 return tooltip;
243 }
244
245 /**
246 * The return value indicates whether the applet wants the mailboxes to be
247 * monitored.
248 *
249 * @return true, if the applet thinks monitoring the mailboxes is okay
250 */
251 gboolean
can_monitor_mailboxes(void)252 Applet::can_monitor_mailboxes (void)
253 {
254 return true;
255 }
256
257 /**
258 * Return an AppletGUI pointer of the applet or NULL if the applet is no
259 * AppletGUI applet.
260 *
261 * @return see description above
262 */
263 class AppletGUI *
appletgui_ptr(void)264 Applet::appletgui_ptr (void)
265 {
266 return NULL;
267 }
268