3
#include <glib/gi18n.h>
4
#include <glibtop/procopenfiles.h>
28
virtual bool matches(const string &filename) const = 0;
36
template<typename OutputIterator>
37
void search(const ProcInfo &info, OutputIterator out) const
39
glibtop_open_files_entry *entries;
40
glibtop_proc_open_files buf;
42
entries = glibtop_get_proc_open_files(&buf, info.pid);
44
for (unsigned i = 0; i != buf.number; ++i) {
45
if (entries[i].type & GLIBTOP_FILE_TYPE_FILE) {
46
const string filename(entries[i].info.file.name);
47
if (this->matches(filename))
65
virtual bool matches(const string &filename) const
69
cp = g_utf8_strdown(this->pattern.c_str(), -1);
70
cf = g_utf8_strdown(filename.c_str(), -1);
74
return f.find(p) != string::npos;
77
return filename.find(this->pattern) != string::npos;
82
Lsof(const string &pattern, bool caseless)
83
: pattern(pattern), caseless(caseless)
94
virtual bool matches(const string &filename) const
96
return this->re.PartialMatch(filename);
101
Lsof(const string &pattern, bool caseless)
102
: re(pattern, pcrecpp::RE_Options().set_caseless(caseless).set_utf8(true))
114
PROCMAN_LSOF_COL_PIXBUF,
115
PROCMAN_LSOF_COL_PROCESS,
116
PROCMAN_LSOF_COL_PID,
117
PROCMAN_LSOF_COL_FILENAME,
129
bool case_insensitive;
134
procman_debug("New Lsof GUI %p", this);
140
procman_debug("Destroying Lsof GUI %p", this);
146
gtk_list_store_clear(this->model);
147
gtk_label_set_text(this->count, "");
153
this->clear_results();
154
gtk_entry_set_text(this->entry, "");
158
void update_count(unsigned count)
160
string s = static_cast<std::ostringstream&>(std::ostringstream() << count).str();
161
gtk_label_set_text(this->count, s.c_str());
165
string pattern() const
167
return gtk_entry_get_text(this->entry);
173
typedef std::set<string> MatchSet;
174
typedef MatchSet::const_iterator iterator;
176
this->clear_results();
178
Lsof lsof(this->pattern(), this->case_insensitive);
179
// lsof = new SimpleLsof(this->pattern(), this->case_insensitive);
182
for (GList *i = this->procdata->info; i; i = i->next) {
183
ProcInfo &info(*static_cast<ProcInfo*>(i->data));
186
lsof.search(info, std::inserter(matches, matches.begin()));
187
count += matches.size();
189
for (iterator it(matches.begin()), end(matches.end()); it != end; ++it) {
191
gtk_list_store_append(this->model, &file);
192
gtk_list_store_set(this->model, &file,
193
PROCMAN_LSOF_COL_PIXBUF, info.pixbuf,
194
PROCMAN_LSOF_COL_PROCESS, info.name,
195
PROCMAN_LSOF_COL_PID, info.pid,
196
PROCMAN_LSOF_COL_FILENAME, it->c_str(),
201
this->update_count(count);
205
static void search_button_clicked(GtkButton *, gpointer data)
207
static_cast<GUI*>(data)->search();
211
static void clear_button_clicked(GtkButton *, gpointer data)
213
static_cast<GUI*>(data)->clear();
217
static void close_button_clicked(GtkButton *, gpointer data)
219
GUI *gui = static_cast<GUI*>(data);
220
gtk_widget_destroy(GTK_WIDGET(gui->window));
225
static void case_button_toggled(GtkToggleButton *button, gpointer data)
227
bool state = gtk_toggle_button_get_active(button);
228
static_cast<GUI*>(data)->case_insensitive = state;
232
static gboolean window_delete_event(GtkWidget *, GdkEvent *, gpointer data)
234
delete static_cast<GUI*>(data);
244
void procman_lsof(ProcData *procdata)
246
GtkListStore *model = \
247
gtk_list_store_new(PROCMAN_LSOF_NCOLS,
248
GDK_TYPE_PIXBUF, // PROCMAN_LSOF_COL_PIXBUF
249
G_TYPE_STRING, // PROCMAN_LSOF_COL_PROCESS
250
G_TYPE_UINT, // PROCMAN_LSOF_COL_PID
251
G_TYPE_STRING // PROCMAN_LSOF_COL_FILENAME
254
GtkWidget *tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
255
g_object_unref(model);
256
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE);
259
GtkTreeViewColumn *column;
260
GtkCellRenderer *renderer;
264
column = gtk_tree_view_column_new();
266
renderer = gtk_cell_renderer_pixbuf_new();
267
gtk_tree_view_column_pack_start(column, renderer, FALSE);
268
gtk_tree_view_column_set_attributes(column, renderer,
269
"pixbuf", PROCMAN_LSOF_COL_PIXBUF,
272
renderer = gtk_cell_renderer_text_new();
273
gtk_tree_view_column_pack_start(column, renderer, FALSE);
274
gtk_tree_view_column_set_attributes(column, renderer,
275
"text", PROCMAN_LSOF_COL_PROCESS,
278
gtk_tree_view_column_set_title(column, _("Process"));
279
gtk_tree_view_column_set_sort_column_id(column, PROCMAN_LSOF_COL_PROCESS);
280
gtk_tree_view_column_set_resizable(column, TRUE);
281
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
282
gtk_tree_view_column_set_min_width(column, 10);
283
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
284
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), PROCMAN_LSOF_COL_PROCESS,
289
renderer = gtk_cell_renderer_text_new();
290
column = gtk_tree_view_column_new_with_attributes(_("PID"), renderer,
291
"text", PROCMAN_LSOF_COL_PID,
293
gtk_tree_view_column_set_sort_column_id(column, PROCMAN_LSOF_COL_PID);
294
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
295
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
299
renderer = gtk_cell_renderer_text_new();
300
column = gtk_tree_view_column_new_with_attributes(_("Filename"), renderer,
301
"text", PROCMAN_LSOF_COL_FILENAME,
303
gtk_tree_view_column_set_sort_column_id(column, PROCMAN_LSOF_COL_FILENAME);
304
gtk_tree_view_column_set_resizable(column, TRUE);
305
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
306
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
309
GtkWidget *dialog; /* = gtk_dialog_new_with_buttons(_("Search for Open Files"), NULL,
310
GTK_DIALOG_DESTROY_WITH_PARENT,
311
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
313
dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
314
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(procdata->app));
315
gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
316
// gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
317
gtk_window_set_title(GTK_WINDOW(dialog), _("Search for Open Files"));
319
// g_signal_connect(G_OBJECT(dialog), "response",
320
// G_CALLBACK(close_dialog), NULL);
321
gtk_window_set_resizable(GTK_WINDOW(dialog), TRUE);
322
gtk_window_set_default_size(GTK_WINDOW(dialog), 575, 400);
323
// gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
324
gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
325
GtkWidget *mainbox = gtk_vbox_new(FALSE, 12);
326
gtk_container_add(GTK_CONTAINER(dialog), mainbox);
327
gtk_box_set_spacing(GTK_BOX(mainbox), 6);
330
// Label, entry and search button
332
GtkWidget *hbox1 = gtk_hbox_new(FALSE, 12);
333
gtk_box_pack_start(GTK_BOX(mainbox), hbox1, FALSE, FALSE, 0);
335
GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_DIALOG);
336
gtk_box_pack_start(GTK_BOX(hbox1), image, FALSE, FALSE, 0);
339
GtkWidget *vbox2 = gtk_vbox_new(FALSE, 12);
340
gtk_box_pack_start(GTK_BOX(hbox1), vbox2, TRUE, TRUE, 0);
343
GtkWidget *hbox = gtk_hbox_new(FALSE, 12);
344
gtk_box_pack_start(GTK_BOX(vbox2), hbox, TRUE, TRUE, 0);
345
GtkWidget *label = gtk_label_new_with_mnemonic(_("_Name contains:"));
346
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
347
GtkWidget *entry = gtk_entry_new();
348
gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
349
GtkWidget *search_button = gtk_button_new_from_stock(GTK_STOCK_FIND);
350
gtk_box_pack_start(GTK_BOX(hbox), search_button, FALSE, FALSE, 0);
351
GtkWidget *clear_button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
352
gtk_box_pack_start(GTK_BOX(hbox), clear_button, FALSE, FALSE, 0);
354
// g_object_set(G_OBJECT(dialog), "activates_default", TRUE, NULL);
355
// gtk_window_set_default(GTK_WINDOW(dialog), GTK_WIDGET(search_button));
358
GtkWidget *case_button = gtk_check_button_new_with_mnemonic(_("Case insensitive matching"));
359
GtkWidget *hbox3 = gtk_hbox_new(FALSE, 12);
360
gtk_box_pack_start(GTK_BOX(hbox3), case_button, FALSE, FALSE, 0);
361
gtk_box_pack_start(GTK_BOX(vbox2), hbox3, FALSE, FALSE, 0);
364
GtkWidget *results_box = gtk_hbox_new(FALSE, 12);
365
gtk_box_pack_start(GTK_BOX(mainbox), results_box, FALSE, FALSE, 0);
366
GtkWidget *results_label = gtk_label_new_with_mnemonic(_("S_earch results:"));
367
gtk_box_pack_start(GTK_BOX(results_box), results_label, FALSE, FALSE, 0);
368
GtkWidget *count_label = gtk_label_new(NULL);
369
gtk_box_pack_end(GTK_BOX(results_box), count_label, FALSE, FALSE, 0);
375
GtkWidget *scrolled = gtk_scrolled_window_new(NULL, NULL);
376
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
377
GTK_POLICY_AUTOMATIC,
378
GTK_POLICY_AUTOMATIC);
379
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled),
381
gtk_container_add(GTK_CONTAINER(scrolled), tree);
382
gtk_box_pack_start(GTK_BOX(mainbox), scrolled, TRUE, TRUE, 0);
384
GtkWidget *bottom_box = gtk_hbox_new(FALSE, 12);
385
GtkWidget *close_button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
386
gtk_box_pack_start(GTK_BOX(mainbox), bottom_box, FALSE, FALSE, 0);
387
gtk_box_pack_end(GTK_BOX(bottom_box), close_button, FALSE, FALSE, 0);
390
GUI *gui = new GUI; // wil be deleted by the close button or delete-event
391
gui->procdata = procdata;
393
gui->window = GTK_WINDOW(dialog);
394
gui->entry = GTK_ENTRY(entry);
395
gui->count = GTK_LABEL(count_label);
397
g_signal_connect(G_OBJECT(clear_button), "clicked",
398
G_CALLBACK(GUI::clear_button_clicked), gui);
399
g_signal_connect(G_OBJECT(search_button), "clicked",
400
G_CALLBACK(GUI::search_button_clicked), gui);
401
g_signal_connect(G_OBJECT(close_button), "clicked",
402
G_CALLBACK(GUI::close_button_clicked), gui);
403
g_signal_connect(G_OBJECT(case_button), "toggled",
404
G_CALLBACK(GUI::case_button_toggled), gui);
405
g_signal_connect(G_OBJECT(dialog), "delete-event",
406
G_CALLBACK(GUI::window_delete_event), gui);
409
gtk_widget_show_all(dialog);