1 /*
2  * Copyright © 2004-2010 Jens Oknelid, paskharen@gmail.com
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * In addition, as a special exception, compiling, linking, and/or
19  * using OpenSSL with this program is allowed.
20  */
21 
22 #include "bookentry.hh"
23 #include "wulformanager.hh"
24 #include "settingsmanager.hh"
25 
26 using namespace std;
27 
BookEntry(const EntryType type,const string & text,const string & ui,const string & id)28 BookEntry::BookEntry(const EntryType type, const string &text, const string &ui, const string &id):
29     Entry(type, ui, id),
30     bold(FALSE),
31     urgent(FALSE)
32 {
33     GSList *group = NULL;
34 #if GTK_CHECK_VERSION(3, 2, 0)
35     labelBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
36 #else
37     labelBox = gtk_hbox_new(FALSE, 5);
38 #endif
39 
40 
41     eventBox = gtk_event_box_new();
42     gtk_event_box_set_above_child(GTK_EVENT_BOX(eventBox), TRUE);
43     gtk_event_box_set_visible_window(GTK_EVENT_BOX(eventBox), FALSE);
44 
45         // icon
46         icon = gtk_image_new();
47         gtk_box_pack_start(GTK_BOX(labelBox), icon, FALSE, FALSE, 0);
48 
49     // Make the eventbox fill to all left-over space.
50     gtk_box_pack_start(GTK_BOX(labelBox), GTK_WIDGET(eventBox), TRUE, TRUE, 0);
51 
52     label = GTK_LABEL(gtk_label_new(text.c_str()));
53     gtk_container_add(GTK_CONTAINER(eventBox), GTK_WIDGET(label));
54 
55     // Align text to the left (x = 0) and in the vertical center (0.5)
56     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
57 
58     closeButton = gtk_button_new();
59     gtk_button_set_relief(GTK_BUTTON(closeButton), GTK_RELIEF_NONE);
60     gtk_button_set_focus_on_click(GTK_BUTTON(closeButton), FALSE);
61 
62 #if !GTK_CHECK_VERSION(3, 0, 0)
63     // Shrink the padding around the close button
64     GtkRcStyle *rcstyle = gtk_rc_style_new();
65     rcstyle->xthickness = rcstyle->ythickness = 0;
66     gtk_widget_modify_style(closeButton, rcstyle);
67     g_object_unref(rcstyle);
68 #endif
69 
70     // Add the stock icon to the close button
71     GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
72     gtk_container_add(GTK_CONTAINER(closeButton), image);
73     gtk_box_pack_start(GTK_BOX(labelBox), closeButton, FALSE, FALSE, 0);
74 
75     gtk_widget_set_tooltip_text(closeButton, _("Close tab"));
76     gtk_widget_show_all(labelBox);
77 
78     tabMenuItem = gtk_radio_menu_item_new_with_label(group, text.c_str());
79     group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(tabMenuItem));
80 
81     setLabel_gui(text);
82     setIcon_gui(type);
83 
84     // Associates entry to the widget for later retrieval in MainWindow::switchPage_gui()
85     g_object_set_data(G_OBJECT(getContainer()), "entry", (gpointer)this);
86 }
87 
getContainer()88 GtkWidget* BookEntry::getContainer()
89 {
90     return getWidget("mainBox");
91 }
92 
setIcon_gui(const EntryType type)93 void BookEntry::setIcon_gui(const EntryType type)
94 {
95     string stock;
96     switch (type)
97     {
98         case Entry::FAVORITE_HUBS : stock = WGETS("icon-favorite-hubs"); break;
99         case Entry::FAVORITE_USERS : stock = WGETS("icon-favorite-users"); break;
100         case Entry::PUBLIC_HUBS : stock = WGETS("icon-public-hubs"); break;
101         case Entry::DOWNLOAD_QUEUE : stock = WGETS("icon-queue"); break;
102         case Entry::SEARCH : stock = WGETS("icon-search"); break;
103         case Entry::SEARCH_ADL : stock = WGETS("icon-search-adl"); break;
104         case Entry::SEARCH_SPY : stock = WGETS("icon-search-spy"); break;
105         case Entry::FINISHED_DOWNLOADS : stock = WGETS("icon-finished-downloads"); break;
106         case Entry::FINISHED_UPLOADS : stock = WGETS("icon-finished-uploads"); break;
107         case Entry::PRIVATE_MESSAGE : stock = WGETS("icon-pm-online"); break;
108         case Entry::HUB : stock = WGETS("icon-hub-offline"); break;
109         case Entry::SHARE_BROWSER : stock = WGETS("icon-directory"); break;
110         default: ; // Default to empty string to indicate no icon should be shown below
111     }
112     // If user doesn't have the icon in their theme, default to showing no icon instead
113     // of showing some generic missing icon. This may occur if the user's system
114     // doesn't implement the full freedesktop.org Icon Naming Specification.
115     GtkIconTheme *iconTheme = gtk_icon_theme_get_default();
116     if (!stock.empty() && gtk_icon_theme_has_icon(iconTheme, stock.c_str()))
117         gtk_image_set_from_icon_name(GTK_IMAGE(icon), stock.c_str(), GTK_ICON_SIZE_BUTTON);
118 }
119 
setIcon_gui(const std::string & stock)120 void BookEntry::setIcon_gui(const std::string &stock)
121 {
122     GtkIconTheme *iconTheme = gtk_icon_theme_get_default();
123     if (!stock.empty() && gtk_icon_theme_has_icon(iconTheme, stock.c_str()))
124         gtk_image_set_from_icon_name(GTK_IMAGE(icon), stock.c_str(), GTK_ICON_SIZE_BUTTON);
125 }
126 
setLabel_gui(string text)127 void BookEntry::setLabel_gui(string text)
128 {
129     // Update the tab menu item label
130     GtkWidget *child = gtk_bin_get_child(GTK_BIN(tabMenuItem));
131     if (child && GTK_IS_LABEL(child))
132         gtk_label_set_text(GTK_LABEL(child), text.c_str());
133 
134     // Update the notebook tab label
135     gtk_widget_set_tooltip_text(eventBox, text.c_str());
136     glong len = g_utf8_strlen(text.c_str(), -1);
137 
138     // Truncate the label text
139     if (len > labelSize)
140     {
141         gchar truncatedText[text.size()];
142         const string clipText = "...";
143         len = labelSize - g_utf8_strlen(clipText.c_str(), -1);
144         g_utf8_strncpy(truncatedText, text.c_str(), len);
145         truncatedLabelText = truncatedText + clipText;
146     }
147     else
148     {
149         truncatedLabelText = text;
150     }
151 
152     labelText = text;
153     updateLabel_gui();
154 
155     // Update the main window title if the current tab is selected.
156     if (isActive_gui())
157         WulforManager::get()->getMainWindow()->setTitle(getLabelText());
158 }
159 
setBold_gui()160 void BookEntry::setBold_gui()
161 {
162     if (!bold && !isActive_gui())
163     {
164         bold = TRUE;
165         updateLabel_gui();
166     }
167 }
168 
setUrgent_gui()169 void BookEntry::setUrgent_gui()
170 {
171     if (!isActive_gui())
172     {
173         MainWindow *mw = WulforManager::get()->getMainWindow();
174 
175         if (!urgent)
176         {
177             bold = TRUE;
178             urgent = TRUE;
179             updateLabel_gui();
180         }
181 
182         if (!mw->isActive_gui())
183             mw->setUrgent_gui();
184     }
185 }
186 
setActive_gui()187 void BookEntry::setActive_gui()
188 {
189     if (bold || urgent)
190     {
191         bold = FALSE;
192         urgent = FALSE;
193         updateLabel_gui();
194     }
195 }
196 
isActive_gui()197 bool BookEntry::isActive_gui()
198 {
199     MainWindow *mw = WulforManager::get()->getMainWindow();
200 
201     return mw->isActive_gui() && mw->currentPage_gui() == getContainer();
202 }
203 
updateLabel_gui()204 void BookEntry::updateLabel_gui()
205 {
206     const char *format = "%s";
207 
208     if (urgent)
209         format = "<i><b>%s</b></i>";
210     else if (bold)
211         format = "<b>%s</b>";
212 
213     char *markup = g_markup_printf_escaped(format, truncatedLabelText.c_str());
214     gtk_label_set_markup(label, markup);
215     g_free(markup);
216 #if GTK_CHECK_VERSION(3, 0, 0)
217     gtk_widget_queue_draw (GTK_WIDGET (label));
218 #endif
219 }
220 
getLabelText()221 const string& BookEntry::getLabelText()
222 {
223     return labelText;
224 }
225