[regexxer] Completion of all entries (files, regex, substitution) with the last 10 used.
- From: Fabien Parent <fparent src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [regexxer] Completion of all entries (files, regex, substitution) with the last 10 used.
- Date: Thu, 24 Sep 2009 18:41:45 +0000 (UTC)
commit 1e61b5acbca8c229b862cbda10d7ee2eccf05fe5
Author: Fabien Parent <parent f gmail com>
Date: Thu Sep 24 20:40:03 2009 +0200
Completion of all entries (files, regex, substitution) with the last 10 used.
Makefile.am | 2 +
src/completionstack.cc | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
src/completionstack.h | 76 ++++++++++++++++++++++++++++++++++
src/globalstrings.h | 3 +
src/mainwindow.cc | 79 +++++++++++++++++++++++++++--------
src/mainwindow.h | 18 +++++++-
ui/mainwindow.ui | 51 ++++++++++------------
ui/regexxer.schemas.in | 55 ++++++++++++++++++++++++-
8 files changed, 341 insertions(+), 50 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index a291242..c420083 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,6 +31,8 @@ SUBDIRS = po
bin_PROGRAMS = src/regexxer
src_regexxer_SOURCES = \
+ src/completionstack.cc \
+ src/completionstack.h \
src/controller.cc \
src/controller.h \
src/filebuffer.cc \
diff --git a/src/completionstack.cc b/src/completionstack.cc
new file mode 100644
index 0000000..1735948
--- /dev/null
+++ b/src/completionstack.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2009 Fabien Parent <parent f gmail com>
+ *
+ * This file is part of regexxer.
+ *
+ * regexxer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * regexxer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with regexxer; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "completionstack.h"
+
+#include <gtkmm/liststore.h>
+
+namespace Regexxer
+{
+
+CompletionStack::CompletionStack(const std::list<Glib::ustring>& stack) :
+ infinite_stack_(true),
+ stack_size_(0),
+ completion_column_model_(),
+ completion_model_(Gtk::ListStore::create(completion_column_model_))
+{
+ push(stack);
+}
+
+CompletionStack::CompletionStack(unsigned int stack_size, const std::list<Glib::ustring>& stack) :
+ infinite_stack_(false),
+ stack_size_(stack_size),
+ completion_column_model_(),
+ completion_model_(Gtk::ListStore::create(completion_column_model_))
+{
+ push(stack);
+}
+
+void CompletionStack::push(const std::list<Glib::ustring> values)
+{
+ for (std::list<Glib::ustring>::const_reverse_iterator item = values.rbegin();
+ item != values.rend(); item++)
+ {
+ push(*item);
+ }
+}
+
+void CompletionStack::push(const Glib::ustring value)
+{
+ if (value.empty())
+ return;
+
+ Gtk::ListStore::Children children = completion_model_->children();
+ for (Gtk::ListStore::Children::iterator i = children.begin(); i != children.end(); i++)
+ {
+ if (i->get_value(completion_column_model_.value_) == value)
+ {
+ completion_model_->move(i, children.begin());
+ return;
+ }
+ }
+
+ Gtk::TreeModel::Row row = *(completion_model_->prepend());
+ row[completion_column_model_.value_] = value;
+
+ if (!infinite_stack_ && children.size() > stack_size_)
+ {
+ Gtk::ListStore::Children::iterator last_element = --(children.end());
+ completion_model_->erase(last_element);
+ }
+}
+
+std::list<Glib::ustring> CompletionStack::get_stack()
+{
+ std::list<Glib::ustring> return_stack;
+ Gtk::ListStore::Children children = completion_model_->children();
+ for (Gtk::ListStore::Children::iterator i = children.begin(); i != children.end(); i++)
+ {
+ return_stack.push_back(i->get_value(completion_column_model_.value_));
+ }
+
+ return return_stack;
+}
+
+Glib::RefPtr<Gtk::ListStore> CompletionStack::get_completion_model()
+{
+ return completion_model_;
+}
+
+Gtk::TreeModelColumn<Glib::ustring> CompletionStack::get_completion_column()
+{
+ return completion_column_model_.value_;
+}
+
+CompletionStack::~CompletionStack()
+{
+
+}
+
+} // namespace Regexxer
diff --git a/src/completionstack.h b/src/completionstack.h
new file mode 100644
index 0000000..aa4cd8d
--- /dev/null
+++ b/src/completionstack.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009 Fabien Parent <parent f gmail com>
+ *
+ * This file is part of regexxer.
+ *
+ * regexxer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * regexxer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with regexxer; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef REGEXXER_COMPLETIONSTACK_H_INCLUDED
+#define REGEXXER_COMPLETIONSTACK_H_INCLUDED
+
+#include <gtkmm/treemodel.h>
+
+#include <list>
+
+namespace Gtk
+{
+class ListStore;
+}
+
+
+namespace Regexxer
+{
+
+class CompletionStack
+{
+public:
+ CompletionStack(const std::list<Glib::ustring>& stack = std::list<Glib::ustring>());
+ CompletionStack(unsigned int stack_size, const std::list<Glib::ustring>& stack = std::list<Glib::ustring>());
+ virtual ~CompletionStack();
+
+ void push(const Glib::ustring value);
+ void push(const std::list<Glib::ustring> values);
+
+ Glib::RefPtr<Gtk::ListStore> get_completion_model();
+ Gtk::TreeModelColumn<Glib::ustring> get_completion_column();
+
+ std::list<Glib::ustring> get_stack();
+
+protected:
+ CompletionStack(const CompletionStack&);
+ CompletionStack operator=(const CompletionStack&);
+
+private:
+ class CompletionColumnModel : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ CompletionColumnModel()
+ {
+ add(value_);
+ }
+
+ Gtk::TreeModelColumn<Glib::ustring> value_;
+ };
+
+ bool infinite_stack_;
+ unsigned int stack_size_;
+ CompletionColumnModel completion_column_model_;
+ Glib::RefPtr<Gtk::ListStore> completion_model_;
+};
+
+} // namespace Regexxer
+
+#endif /* REGEXXER_COMPLETIONSTACK_H_INCLUDED */
diff --git a/src/globalstrings.h b/src/globalstrings.h
index 4a4c467..8cf336d 100644
--- a/src/globalstrings.h
+++ b/src/globalstrings.h
@@ -38,6 +38,9 @@ const char *const conf_key_match_color = "/apps/regexxer/match_color";
const char *const conf_key_current_match_color = "/apps/regexxer/current_match_color";
const char *const conf_key_toolbar_style = "/apps/regexxer/toolbar_style";
const char *const conf_key_fallback_encoding = "/apps/regexxer/fallback_encoding";
+const char *const conf_key_substitution_patterns = "/apps/regexxer/substitution_patterns";
+const char *const conf_key_regex_patterns = "/apps/regexxer/regex_patterns";
+const char *const conf_key_files_patterns = "/apps/regexxer/files_patterns";
const char *const ui_mainwindow_filename = REGEXXER_PKGDATADIR G_DIR_SEPARATOR_S
"mainwindow.ui";
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index b404452..7927084 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
@@ -183,10 +183,16 @@ MainWindow::MainWindow()
table_file_ (0),
button_folder_ (0),
combo_entry_pattern_ (Gtk::manage(new Gtk::ComboBoxEntryText())),
+ combo_entry_pattern_completion_stack_(10, Gnome::Conf::Client::get_default_client()->get_string_list(conf_key_files_patterns)),
+ combo_entry_pattern_completion_ (Gtk::EntryCompletion::create()),
button_recursive_ (0),
button_hidden_ (0),
entry_regex_ (0),
+ entry_regex_completion_stack_(10, Gnome::Conf::Client::get_default_client()->get_string_list(conf_key_regex_patterns)),
+ entry_regex_completion_ (Gtk::EntryCompletion::create()),
entry_substitution_ (0),
+ entry_substitution_completion_stack_(10, Gnome::Conf::Client::get_default_client()->get_string_list(conf_key_substitution_patterns)),
+ entry_substitution_completion_ (Gtk::EntryCompletion::create()),
button_multiple_ (0),
button_caseless_ (0),
filetree_ (Gtk::manage(new FileTree())),
@@ -201,7 +207,10 @@ MainWindow::MainWindow()
undo_stack_ (new UndoStack())
{
load_xml();
-
+
+ entry_regex_ = comboboxentry_regex_->get_entry();
+ entry_substitution_ = comboboxentry_substitution_->get_entry();
+
textview_->set_buffer(FileBuffer::create());
window_->set_title(PACKAGE_NAME);
@@ -234,19 +243,35 @@ void MainWindow::initialize(const InitState& init)
const bool folder_exists = button_folder_->set_current_folder(folder);
combo_entry_pattern_->get_entry()->set_text((init.pattern.empty()) ? Glib::ustring(1, '*') : init.pattern);
- entry_regex_ ->set_text(init.regex);
+ combo_entry_pattern_->set_model(combo_entry_pattern_completion_stack_.get_completion_model());
+ combo_entry_pattern_->set_text_column(combo_entry_pattern_completion_stack_.get_completion_column());
+ combo_entry_pattern_->get_entry()->set_completion(combo_entry_pattern_completion_);
+
+ entry_regex_->set_text(init.regex);
+ entry_regex_->set_completion(entry_regex_completion_);
entry_substitution_->set_text(init.substitution);
+ entry_substitution_->set_completion(entry_substitution_completion_);
+
+ comboboxentry_regex_->set_model(entry_regex_completion_stack_.get_completion_model());
+ comboboxentry_regex_->set_text_column(entry_regex_completion_stack_.get_completion_column());
+ comboboxentry_substitution_->set_model(entry_substitution_completion_stack_.get_completion_model());
+ comboboxentry_substitution_->set_text_column(entry_substitution_completion_stack_.get_completion_column());
+
+ combo_entry_pattern_completion_->set_model(combo_entry_pattern_completion_stack_.get_completion_model());
+ combo_entry_pattern_completion_->set_text_column(combo_entry_pattern_completion_stack_.get_completion_column());
+ combo_entry_pattern_completion_->set_inline_completion(true);
+ combo_entry_pattern_completion_->set_popup_completion(false);
+
+ entry_regex_completion_->set_model(entry_regex_completion_stack_.get_completion_model());
+ entry_regex_completion_->set_text_column(entry_regex_completion_stack_.get_completion_column());
+ entry_regex_completion_->set_inline_completion(true);
+ entry_regex_completion_->set_popup_completion(false);
+
- combo_entry_pattern_->append_text("*.[ch]");
- combo_entry_pattern_->append_text("*.{c,cc,cpp,cxx,c++,C,h,hh,hpp,hxx,h++}");
- combo_entry_pattern_->append_text("*.{ccg,hg}");
- combo_entry_pattern_->append_text("*.idl");
- combo_entry_pattern_->append_text("*.{java,jsp}");
- combo_entry_pattern_->append_text("*.{pl,pm,cgi}");
- combo_entry_pattern_->append_text("*.py");
- combo_entry_pattern_->append_text("*.php[0-9]?");
- combo_entry_pattern_->append_text("*.{html,htm,shtml,js,wml}");
- combo_entry_pattern_->append_text("*.{xml,xsl,css,dtd,xsd}");
+ entry_substitution_completion_->set_model(entry_substitution_completion_stack_.get_completion_model());
+ entry_substitution_completion_->set_text_column(entry_substitution_completion_stack_.get_completion_column());
+ entry_substitution_completion_->set_inline_completion(true);
+ entry_substitution_completion_->set_popup_completion(false);
button_recursive_->set_active(!init.no_recursive);
button_hidden_ ->set_active(init.hidden);
@@ -282,8 +307,8 @@ void MainWindow::load_xml()
xml->get_widget("button_folder", button_folder_);
xml->get_widget("button_recursive", button_recursive_);
xml->get_widget("button_hidden", button_hidden_);
- xml->get_widget("entry_regex", entry_regex_);
- xml->get_widget("entry_substitution", entry_substitution_);
+ xml->get_widget("comboboxentry_regex", comboboxentry_regex_);
+ xml->get_widget("comboboxentry_substitution", comboboxentry_substitution_);
xml->get_widget("button_multiple", button_multiple_);
xml->get_widget("button_caseless", button_caseless_);
xml->get_widget("scrollwin_textview", scrollwin_textview_);
@@ -505,6 +530,10 @@ void MainWindow::on_find_files()
if (dialog.run() != Gtk::RESPONSE_OK)
return;
}
+
+ const Glib::ustring files_regex = combo_entry_pattern_->get_entry()->get_text();
+ combo_entry_pattern_completion_stack_.push(files_regex);
+ Gnome::Conf::Client::get_default_client()->set_string_list(conf_key_files_patterns, combo_entry_pattern_completion_stack_.get_stack());
std::string folder = button_folder_->get_filename();
@@ -519,7 +548,7 @@ void MainWindow::on_find_files()
try
{
- Pcre::Pattern pattern (Util::shell_pattern_to_regex(combo_entry_pattern_->get_entry()->get_text()), Pcre::DOTALL);
+ Pcre::Pattern pattern (Util::shell_pattern_to_regex(files_regex), Pcre::DOTALL);
filetree_->find_files(folder, pattern,
button_recursive_->get_active(),
@@ -548,7 +577,10 @@ void MainWindow::on_exec_search()
const Glib::ustring regex = entry_regex_->get_text();
const bool caseless = button_caseless_->get_active();
const bool multiple = button_multiple_->get_active();
-
+
+ entry_regex_completion_stack_.push(regex);
+ Gnome::Conf::Client::get_default_client()->set_string_list(conf_key_regex_patterns, entry_regex_completion_stack_.get_stack());
+
try
{
Pcre::Pattern pattern (regex, (caseless) ? Pcre::CASELESS : Pcre::CompileOptions(0));
@@ -733,7 +765,10 @@ void MainWindow::on_replace()
{
if (const FileBufferPtr buffer = FileBufferPtr::cast_static(textview_->get_buffer()))
{
- buffer->replace_current_match(entry_substitution_->get_text());
+ const Glib::ustring substitution = entry_substitution_->get_text();
+ entry_substitution_completion_stack_.push(substitution);
+ Gnome::Conf::Client::get_default_client()->set_string_list(conf_key_substitution_patterns, entry_substitution_completion_stack_.get_stack());
+ buffer->replace_current_match(substitution);
on_go_next(true);
}
}
@@ -742,7 +777,10 @@ void MainWindow::on_replace_file()
{
if (const FileBufferPtr buffer = FileBufferPtr::cast_static(textview_->get_buffer()))
{
- buffer->replace_all_matches(entry_substitution_->get_text());
+ const Glib::ustring substitution = entry_substitution_->get_text();
+ entry_substitution_completion_stack_.push(substitution);
+ Gnome::Conf::Client::get_default_client()->set_string_list(conf_key_substitution_patterns, entry_substitution_completion_stack_.get_stack());
+ buffer->replace_all_matches(substitution);
statusline_->set_match_index(0);
}
}
@@ -751,7 +789,10 @@ void MainWindow::on_replace_all()
{
BusyAction busy (*this);
- filetree_->replace_all_matches(entry_substitution_->get_text());
+ const Glib::ustring substitution = entry_substitution_->get_text();
+ entry_substitution_completion_stack_.push(substitution);
+ Gnome::Conf::Client::get_default_client()->set_string_list(conf_key_substitution_patterns, entry_substitution_completion_stack_.get_stack());
+ filetree_->replace_all_matches(substitution);
statusline_->set_match_index(0);
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index a915e86..2deafa3 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -24,6 +24,7 @@
#include "controller.h"
#include "filebuffer.h"
#include "sharedptr.h"
+#include "completionstack.h"
#include <sigc++/sigc++.h>
#include <glibmm/refptr.h>
@@ -41,10 +42,11 @@ class Entry;
class FileChooser;
class Toolbar;
class Window;
-class ComboBoxEntryText;
+class ComboBoxEntry;
class VBox;
class ScrolledWindow;
class Table;
+class EntryCompletion;
}
namespace gtksourceview
@@ -100,12 +102,24 @@ private:
Gtk::Table* table_file_;
Gtk::FileChooser* button_folder_;
- Gtk::ComboBoxEntryText* combo_entry_pattern_;
+
+ Gtk::ComboBoxEntry* combo_entry_pattern_;
+ CompletionStack combo_entry_pattern_completion_stack_;
+ Glib::RefPtr<Gtk::EntryCompletion> combo_entry_pattern_completion_;
+
Gtk::CheckButton* button_recursive_;
Gtk::CheckButton* button_hidden_;
+ Gtk::ComboBoxEntry* comboboxentry_regex_;
Gtk::Entry* entry_regex_;
+ CompletionStack entry_regex_completion_stack_;
+ Glib::RefPtr<Gtk::EntryCompletion> entry_regex_completion_;
+
+ Gtk::ComboBoxEntry* comboboxentry_substitution_;
Gtk::Entry* entry_substitution_;
+ CompletionStack entry_substitution_completion_stack_;
+ Glib::RefPtr<Gtk::EntryCompletion> entry_substitution_completion_;
+
Gtk::CheckButton* button_multiple_;
Gtk::CheckButton* button_caseless_;
diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui
index b8470db..cf3b8b2 100644
--- a/ui/mainwindow.ui
+++ b/ui/mainwindow.ui
@@ -551,7 +551,6 @@
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Search:</property>
- <property name="mnemonic_widget">entry_regex</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
@@ -563,7 +562,6 @@
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Replace:</property>
- <property name="mnemonic_widget">entry_substitution</property>
</object>
<packing>
<property name="top_attach">1</property>
@@ -573,32 +571,6 @@
</packing>
</child>
<child>
- <object class="GtkEntry" id="entry_regex">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text" translatable="yes">A regular expression in Perl syntax</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry_substitution">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text" translatable="yes">The new string to substitute. As in Perl, you can refer to parts of the match using $1, $2, etc. or even $+, $&, $` and $'. The operators \l, \u, \L, \U and \E are supported as well.</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
<object class="GtkHBox" id="hbox_options">
<property name="visible">True</property>
<property name="spacing">6</property>
@@ -659,6 +631,29 @@
<property name="y_options"></property>
</packing>
</child>
+ <child>
+ <object class="GtkComboBoxEntry" id="comboboxentry_regex">
+ <property name="visible">True</property>
+ <property name="tooltip_text" translatable="yes">A regular expression in Perl syntax</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxEntry" id="comboboxentry_substitution">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
diff --git a/ui/regexxer.schemas.in b/ui/regexxer.schemas.in
index 93638cc..a68d93e 100644
--- a/ui/regexxer.schemas.in
+++ b/ui/regexxer.schemas.in
@@ -1,7 +1,60 @@
<?xml version="1.0"?>
<gconfschemafile>
<schemalist>
-
+ <schema>
+ <key>/schemas/apps/regexxer/files_patterns</key>
+ <applyto>/apps/regexxer/files_patterns</applyto>
+ <owner>regexxer</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default_value>
+ <value>
+ <list type="string">
+ </list>
+ </value>
+ </default_value>
+ <locale name="C">
+ <short>Regex Patterns</short>
+ <long>List of last pattern used for the file's regex entry.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/regexxer/regex_patterns</key>
+ <applyto>/apps/regexxer/regex_patterns</applyto>
+ <owner>regexxer</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default_value>
+ <value>
+ <list type="string">
+ </list>
+ </value>
+ </default_value>
+ <locale name="C">
+ <short>Regex Patterns</short>
+ <long>List of last pattern used for the regex entry.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/regexxer/substitution_patterns</key>
+ <applyto>/apps/regexxer/substitution_patterns</applyto>
+ <owner>regexxer</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default_value>
+ <value>
+ <list type="string">
+ </list>
+ </value>
+ </default_value>
+ <locale name="C">
+ <short>Regex Patterns</short>
+ <long>List of last pattern used for the substitution entry.</long>
+ </locale>
+ </schema>
+
<schema>
<key>/schemas/apps/regexxer/textview_font</key>
<applyto>/apps/regexxer/textview_font</applyto>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]