14 #include "ygtkpkgsearchentry.h"
15 #include "YGPackageSelector.h"
19 GtkWidget *box, *entry, *combo;
22 static void entry_icons_sync (GtkWidget *widget)
24 static GdkColor yellow = { 0, 0xf7f7, 0xf7f7, 0xbdbd };
25 static GdkColor black = { 0, 0, 0, 0 };
27 GtkEntry *entry = GTK_ENTRY (widget);
28 const gchar *name = gtk_entry_get_text (entry);
29 bool showIcon = *name;
30 if (showIcon != gtk_entry_get_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY)) {
31 gtk_entry_set_icon_activatable (entry,
32 GTK_ENTRY_ICON_SECONDARY, showIcon);
33 gtk_entry_set_icon_from_stock (entry,
34 GTK_ENTRY_ICON_SECONDARY, showIcon ? GTK_STOCK_CLEAR : NULL);
37 gtk_entry_set_icon_tooltip_text (entry,
38 GTK_ENTRY_ICON_SECONDARY, _(
"Clear"));
39 gtk_widget_modify_base (widget, GTK_STATE_NORMAL, &yellow);
40 gtk_widget_modify_text (widget, GTK_STATE_NORMAL, &black);
43 gtk_widget_modify_base (widget, GTK_STATE_NORMAL, NULL);
44 gtk_widget_modify_text (widget, GTK_STATE_NORMAL, NULL);
51 int item = gtk_combo_box_get_active (GTK_COMBO_BOX (pThis->impl->combo));
52 pThis->notifyDelay (item == 0 ? 150 : 500);
53 entry_icons_sync (GTK_WIDGET (editable));
58 const gchar *name = gtk_entry_get_text (GTK_ENTRY (pThis->impl->entry));
61 gtk_editable_select_region (GTK_EDITABLE (pThis->impl->entry), 0, -1);
62 gtk_widget_grab_focus (pThis->impl->entry);
65 static void icon_press_cb (GtkEntry *entry, GtkEntryIconPosition pos,
68 if (pos == GTK_ENTRY_ICON_PRIMARY)
69 gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
71 gtk_entry_set_text (entry,
"");
72 gtk_widget_grab_focus (GTK_WIDGET (entry));
75 static void activate_cb (GtkEntry *entry, GtkWidget *widget)
76 { gtk_widget_grab_focus (widget); }
78 YGtkPkgSearchEntry::YGtkPkgSearchEntry()
81 impl->entry = gtk_entry_new();
82 gtk_widget_set_size_request (impl->entry, 180, -1);
83 g_signal_connect (G_OBJECT (impl->entry),
"realize",
84 G_CALLBACK (gtk_widget_grab_focus), NULL);
85 g_signal_connect (G_OBJECT (impl->entry),
"changed",
86 G_CALLBACK (entry_changed_cb),
this);
87 g_signal_connect (G_OBJECT (impl->entry),
"icon-press",
88 G_CALLBACK (icon_press_cb),
this);
89 gtk_widget_set_tooltip_markup (impl->entry,
90 _(
"<b>Package search:</b> Use spaces to separate your keywords.\n"
91 "(usage example: a name search for \"yast dhcp\" would match yast dhcpd tool)"));
93 gtk_entry_set_icon_from_stock (GTK_ENTRY (impl->entry),
94 GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_FIND);
95 gtk_entry_set_icon_activatable (GTK_ENTRY (impl->entry), GTK_ENTRY_ICON_PRIMARY, TRUE);
97 std::string label_str (YGUtils::mapKBAccel (_(
"&Find:")));
98 GtkWidget *label = gtk_label_new_with_mnemonic (label_str.c_str());
99 gtk_label_set_mnemonic_widget (GTK_LABEL (label), impl->entry);
101 impl->combo = gtk_combo_box_text_new();
102 GtkComboBoxText *combot = GTK_COMBO_BOX_TEXT (impl->combo);
103 gtk_combo_box_text_append (combot, 0, _(
"Name & Summary"));
104 gtk_combo_box_text_append (combot, 0, _(
"Description"));
105 if (!YGPackageSelector::get()->onlineUpdateMode()) {
106 gtk_combo_box_text_append (combot, 0, _(
"File name"));
107 gtk_combo_box_text_append (combot, 0,
"RPM Provides");
108 gtk_combo_box_text_append (combot, 0,
"RPM Requires");
110 gtk_combo_box_set_active (GTK_COMBO_BOX (impl->combo), 0);
111 YGUtils::shrinkWidget (impl->combo);
112 g_signal_connect (G_OBJECT (impl->combo),
"changed",
113 G_CALLBACK (combo_changed_cb),
this);
114 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (impl->combo),
115 YGUtils::empty_row_is_separator_cb, GINT_TO_POINTER (0), NULL);
117 impl->box = gtk_hbox_new (FALSE, 3);
118 gtk_box_pack_start (GTK_BOX (impl->box), label, FALSE, TRUE, 0);
119 gtk_box_pack_start (GTK_BOX (impl->box), impl->entry, TRUE, TRUE, 0);
120 gtk_box_pack_start (GTK_BOX (impl->box), gtk_label_new (_(
"by")), FALSE, TRUE, 0);
121 gtk_box_pack_start (GTK_BOX (impl->box), impl->combo, TRUE, TRUE, 0);
122 gtk_widget_show_all (impl->box);
125 YGtkPkgSearchEntry::~YGtkPkgSearchEntry()
128 GtkWidget *YGtkPkgSearchEntry::getWidget()
129 {
return impl->box; }
131 void YGtkPkgSearchEntry::clearSelection()
132 { setText (Ypp::PoolQuery::NAME,
""); }
136 const gchar *text = gtk_entry_get_text (GTK_ENTRY (impl->entry));
138 int item = gtk_combo_box_get_active (GTK_COMBO_BOX (impl->combo));
139 if (item >= 0 && item <= 1) {
143 attrbs = Ypp::StrMatch::NAME | Ypp::StrMatch::SUMMARY;
146 attrbs = Ypp::StrMatch::DESCRIPTION;
151 const gchar delimiter[2] = {
' ',
'\0' };
152 gchar **keywords = g_strsplit (text, delimiter, -1);
153 for (gchar **i = keywords; *i; i++)
155 g_strfreev (keywords);
157 query.addCriteria (match);
160 query.setStringMode (
false, Ypp::PoolQuery::CONTAINS);
164 query.addStringAttribute (Ypp::PoolQuery::PROVIDES);
165 query.addStringAttribute (Ypp::PoolQuery::FILELIST);
168 query.addStringAttribute (Ypp::PoolQuery::PROVIDES);
171 query.addStringAttribute (Ypp::PoolQuery::REQUIRES);
175 query.addStringOr (text);
182 static gboolean patterns_link_cb (GtkLabel *label, gchar *uri,
YGtkPkgSearchEntry *pThis)
183 { YGPackageSelector::get()->showFilterWidget (uri);
return TRUE; }
185 static bool any_pattern_contains (
const char *name)
187 if (strstr (name,
" "))
return false;
191 WholeWordMatch (
const char *word)
192 : word (word), len (strlen (word)) {}
195 std::string name (sel.name());
196 const char *i = name.c_str();
197 while ((i = strcasestr (i, word))) {
198 bool starts = (i == word) || (i[-1] !=
' ');
199 bool ends = (i[len+1] ==
'\0') || (i[len+1] !=
' ');
206 private:
const char *word;
int len;
210 query.addCriteria (
new WholeWordMatch (name));
212 return query.hasNext();
215 GtkWidget *YGtkPkgSearchEntry::createToolbox()
217 const gchar *text = gtk_entry_get_text (GTK_ENTRY (impl->entry));
218 int item = gtk_combo_box_get_active (GTK_COMBO_BOX (impl->combo));
222 if (any_pattern_contains (text)) {
223 char *_text = g_strdup_printf (_(
"%sPatterns are available%s"
224 " that correspond to your search criteria."),
225 "<a href=\"patterns\">",
"</a>");
226 GtkWidget *label = gtk_label_new (_text);
228 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
229 gtk_misc_set_alignment (GTK_MISC (label), 0, .5);
230 g_signal_connect (G_OBJECT (label),
"activate-link",
231 G_CALLBACK (patterns_link_cb),
this);
232 GtkWidget *icon = gtk_image_new_from_stock (
233 GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_BUTTON);
234 GtkWidget *hbox = gtk_hbox_new (FALSE, 6);
235 gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, TRUE, 0);
236 gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
237 gtk_widget_show_all (hbox);
242 GtkWidget *label = gtk_label_new (
243 _(
"Search by file name only reliable for installed packages."));
244 gtk_misc_set_alignment (GTK_MISC (label), 0, .5);
245 GtkWidget *icon = gtk_image_new_from_stock (
246 GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON);
247 GtkWidget *hbox = gtk_hbox_new (FALSE, 6);
248 gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, TRUE, 0);
249 gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
250 gtk_widget_show_all (hbox);
257 void YGtkPkgSearchEntry::setText (Ypp::PoolQuery::StringAttribute attrb,
const std::string &text)
261 case Ypp::PoolQuery::NAME:
case Ypp::PoolQuery::SUMMARY:
break;
262 case Ypp::PoolQuery::DESCRIPTION: index = 1;
break;
263 case Ypp::PoolQuery::FILELIST: index = 2;
break;
264 case Ypp::PoolQuery::PROVIDES: index = 3;
break;
265 case Ypp::PoolQuery::REQUIRES: index = 4;
break;
268 g_signal_handlers_block_by_func (impl->entry, (gpointer) entry_changed_cb,
this);
269 g_signal_handlers_block_by_func (impl->combo, (gpointer) combo_changed_cb,
this);
270 gtk_combo_box_set_active (GTK_COMBO_BOX (impl->combo), index);
271 gtk_entry_set_text (GTK_ENTRY (impl->entry), text.c_str());
272 entry_icons_sync (impl->entry);
273 g_signal_handlers_unblock_by_func (impl->entry, (gpointer) entry_changed_cb,
this);
274 g_signal_handlers_unblock_by_func (impl->combo, (gpointer) combo_changed_cb,
this);
277 void YGtkPkgSearchEntry::setActivateWidget (GtkWidget *widget)
279 g_signal_connect (G_OBJECT (impl->entry),
"activate",
280 G_CALLBACK (activate_cb), widget);
283 Ypp::PoolQuery::StringAttribute YGtkPkgSearchEntry::getAttribute()
285 int item = gtk_combo_box_get_active (GTK_COMBO_BOX (impl->combo));
287 case 0:
return Ypp::PoolQuery::NAME;
break;
288 case 1:
return Ypp::PoolQuery::DESCRIPTION;
break;
289 case 2:
return Ypp::PoolQuery::FILELIST;
break;
290 case 3:
return Ypp::PoolQuery::PROVIDES;
break;
291 case 4:
return Ypp::PoolQuery::REQUIRES;
break;
293 return (Ypp::PoolQuery::StringAttribute) 0;
296 std::list <std::string> YGtkPkgSearchEntry::getText()
298 std::list <std::string> keywords;
299 const char *text = gtk_entry_get_text (GTK_ENTRY (impl->entry));
300 const gchar delimiter[2] = {
' ',
'\0' };
301 gchar **_keywords = g_strsplit (text, delimiter, -1);
302 for (gchar **i = _keywords; *i; i++)
304 keywords.push_back (*i);
305 g_strfreev (_keywords);
309 std::string YGtkPkgSearchEntry::getTextStr()
310 {
return gtk_entry_get_text (GTK_ENTRY (impl->entry)); }