summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Rice <glennricster@gmail.com>2012-12-18 13:05:10 -0600
committerGlenn Rice <glennricster@gmail.com>2012-12-18 13:05:10 -0600
commit31864b2ab9009f380a2068a432da294fd87186a2 (patch)
tree7c9aa713f7dbf4c751e1f78785e6465d68cacbbd
parentcc3092f2baf482434d79c79bfd359a6c386fabca (diff)
Add rendering of found text to the find demo.
-rw-r--r--examples/demo/find.cc156
-rw-r--r--examples/demo/find.h26
2 files changed, 171 insertions, 11 deletions
diff --git a/examples/demo/find.cc b/examples/demo/find.cc
index 02ee356..bd63baa 100644
--- a/examples/demo/find.cc
+++ b/examples/demo/find.cc
@@ -20,6 +20,7 @@
#include <glibmm/main.h>
#include <glibmm/timer.h>
+#include <gdkmm/general.h>
#include <iomanip>
namespace PGD
@@ -28,9 +29,15 @@ namespace PGD
Find::Find(const Glib::RefPtr<Poppler::Document>& document) :
Gtk::Box(Gtk::ORIENTATION_VERTICAL, 12),
m_Document(document),
- m_PageIndex(0),
+ m_PageIndex(0), m_SelectedPage(-1),
+ m_Options(Poppler::FIND_DEFAULT),
m_HBoxTop(Gtk::ORIENTATION_HORIZONTAL, 6),
- m_FindButton("Find")
+ m_HBoxOptions(Gtk::ORIENTATION_HORIZONTAL, 6),
+ m_FindButton("Find"),
+ m_CaseSensitiveCButton("Case sensitive"),
+ m_BackwardsCButton("Backwards"),
+ m_WholeWordsCButton("Whole words only"),
+ m_HPaned(Gtk::ORIENTATION_HORIZONTAL)
{
m_NPages = document->get_n_pages();
@@ -45,12 +52,22 @@ Find::Find(const Glib::RefPtr<Poppler::Document>& document) :
m_HBoxTop.pack_start(m_ProgressBar, true, true);
m_HBoxTop.pack_end(m_FindButton, false, false);
- m_ScrolledWin.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ m_CaseSensitiveCButton.signal_toggled().connect(sigc::mem_fun(*this, &Find::case_sensitive_toggled));
+ m_BackwardsCButton.signal_toggled().connect(sigc::mem_fun(*this, &Find::backwards_toggled));
+ m_WholeWordsCButton.signal_toggled().connect(sigc::mem_fun(*this, &Find::whole_words_toggled));
+
+ m_HBoxOptions.pack_start(m_CaseSensitiveCButton, false, false);
+ m_HBoxOptions.pack_start(m_BackwardsCButton, false, false);
+ m_HBoxOptions.pack_start(m_WholeWordsCButton, false, false);
+
+ m_MatchScrolledWin.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
m_MatchStore = Gtk::TreeStore::create(m_StoreColumns);
m_TreeView.set_model(m_MatchStore);
m_TreeView.set_rules_hint();
- m_TreeView.get_selection()->set_mode(Gtk::SELECTION_NONE);
+ Glib::RefPtr<Gtk::TreeSelection> selection = m_TreeView.get_selection();
+ selection->set_mode(Gtk::SELECTION_SINGLE);
+ selection->signal_changed().connect(sigc::mem_fun(*this, &Find::selection_changed));
m_TreeView.append_column("Matches", m_StoreColumns.m_Matches);
int column_num = m_TreeView.append_column_numeric("X1", m_StoreColumns.m_X1, "%.2f");
@@ -66,18 +83,34 @@ Find::Find(const Glib::RefPtr<Poppler::Document>& document) :
m_TreeView.get_column(column_num - 1)->add_attribute(
m_TreeView.get_column_cell_renderer(column_num - 1)->property_visible(), m_StoreColumns.m_Visible);
- m_ScrolledWin.add(m_TreeView);
+ m_MatchScrolledWin.add(m_TreeView);
+
+ m_DrawingArea.signal_draw().connect(sigc::mem_fun(*this, &Find::drawing_area_draw));
+ m_DAScrolledWin.add(m_DrawingArea);
+
+ m_HPaned.add1(m_MatchScrolledWin);
+ m_HPaned.add2(m_DAScrolledWin);
+ m_HPaned.set_position(300);
pack_start(m_HBoxTop, false, true, 6);
- pack_start(m_ScrolledWin, true, true);
+ pack_start(m_HBoxOptions, false, false);
+ pack_start(m_HPaned, true, true);
show_all();
}
+void Find::queue_redraw()
+{
+ m_Surface.clear();
+ m_DrawingArea.queue_draw();
+}
+
void Find::find_button_clicked()
{
m_MatchStore->clear();
m_PageIndex = 0;
+ m_SelectedPage = -1;
+ queue_redraw();
update_progress(m_NPages, m_PageIndex);
if (m_FindIdle.connected()) m_FindIdle.disconnect();
@@ -101,7 +134,7 @@ bool Find::find_text()
if (!page) return ++m_PageIndex < m_NPages;
Glib::Timer timer;
- std::vector<Poppler::Rectangle> matches = page->find_text(m_TextEntry.get_text());
+ std::vector<Poppler::Rectangle> matches = page->find_text_with_options(m_TextEntry.get_text(), m_Options);
timer.stop();
if (matches.size())
@@ -109,6 +142,11 @@ bool Find::find_text()
Gtk::TreeRow row = *(m_MatchStore->append());
row[m_StoreColumns.m_Matches] = Glib::ustring::format(matches.size(), " matches found on page ", m_PageIndex + 1,
" in ", std::fixed, std::setprecision(4), timer.elapsed(), " seconds");
+ row[m_StoreColumns.m_Visible] = false;
+ row[m_StoreColumns.m_PageColumn] = m_PageIndex;
+
+ double width, height;
+ page->get_size(width, height);
int n_match = 0;
for (std::vector<Poppler::Rectangle>::iterator match = matches.begin();
@@ -121,6 +159,13 @@ bool Find::find_text()
match_row[m_StoreColumns.m_X2] = match->get_x2();
match_row[m_StoreColumns.m_Y2] = match->get_y2();
match_row[m_StoreColumns.m_Visible] = true;
+ match_row[m_StoreColumns.m_PageColumn] = m_PageIndex;
+
+ double tmp = match->get_y1();
+ match->set_y1(height - match->get_y2());
+ match->set_y2(height - tmp);
+
+ match_row[m_StoreColumns.m_Rect] = *match;
}
}
@@ -128,4 +173,101 @@ bool Find::find_text()
return m_PageIndex < m_NPages;
}
+bool Find::drawing_area_draw(const Cairo::RefPtr<Cairo::Context>& cr)
+{
+ if (m_SelectedPage == -1) return false;
+
+ if (!m_Surface)
+ {
+ Glib::RefPtr<Poppler::Page> page = m_Document->get_page(m_SelectedPage);
+ if (!page) return false;
+
+ double width, height;
+ page->get_size(width, height);
+ m_DrawingArea.set_size_request(width, height);
+
+ m_Surface = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, width, height);
+ Cairo::RefPtr<Cairo::Context> cr_tmp = Cairo::Context::create(m_Surface);
+
+ cr_tmp->save();
+ cr_tmp->set_source_rgb(1.0, 1.0, 1.0);
+ cr_tmp->rectangle(0.0, 0.0, width, height);
+ cr_tmp->fill();
+ cr_tmp->restore();
+
+ cr_tmp->save();
+ page->render(cr_tmp);
+ cr_tmp->restore();
+
+ if (!m_Surface) return false;
+ }
+
+ cr->set_source(m_Surface, 0, 0);
+ cr->paint();
+
+ if (m_SelectedMatch.get_width() > 0 && m_SelectedMatch.get_height() > 0)
+ {
+ cr->set_source_rgb(1.0, 1.0, 0.0);
+ // TODO: The following operator should be Cairo::OPERATOR_MULTIPLY but that is not in cairomm yet.
+ cr->set_operator((Cairo::Operator)CAIRO_OPERATOR_MULTIPLY);
+ Gdk::Cairo::add_rectangle_to_path(cr, m_SelectedMatch);
+ cr->fill();
+ }
+
+ return true;
+}
+
+void Find::selection_changed()
+{
+ Gtk::TreeIter iter = m_TreeView.get_selection()->get_selected();
+ if (iter)
+ {
+ if ((*iter)[m_StoreColumns.m_Visible])
+ {
+ Poppler::Rectangle rect = (*iter)[m_StoreColumns.m_Rect];
+ m_SelectedMatch.set_x(rect.get_x1());
+ m_SelectedMatch.set_y(rect.get_y1());
+ m_SelectedMatch.set_width(rect.get_x2() - rect.get_x1());
+ m_SelectedMatch.set_height(rect.get_y2() - rect.get_y1());
+ }
+ else
+ {
+ m_SelectedMatch.set_width(0);
+ m_SelectedMatch.set_height(0);
+ }
+
+ if (m_SelectedPage != (*iter)[m_StoreColumns.m_PageColumn])
+ {
+ m_SelectedPage = (*iter)[m_StoreColumns.m_PageColumn];
+ queue_redraw();
+ }
+ else
+ m_DrawingArea.queue_draw();
+ }
+}
+
+void Find::case_sensitive_toggled()
+{
+ if (m_CaseSensitiveCButton.get_active())
+ m_Options |= Poppler::FIND_CASE_SENSITIVE;
+ else
+ m_Options &= ~Poppler::FIND_CASE_SENSITIVE;
+}
+
+void Find::backwards_toggled()
+{
+ if (m_BackwardsCButton.get_active())
+ m_Options |= Poppler::FIND_BACKWARDS;
+ else
+ m_Options &= ~Poppler::FIND_BACKWARDS;
+}
+
+void Find::whole_words_toggled()
+{
+ if (m_WholeWordsCButton.get_active())
+ m_Options |= Poppler::FIND_WHOLE_WORDS_ONLY;
+ else
+ m_Options &= ~Poppler::FIND_WHOLE_WORDS_ONLY;
+}
+
}
diff --git a/examples/demo/find.h b/examples/demo/find.h
index 5047227..fc80b39 100644
--- a/examples/demo/find.h
+++ b/examples/demo/find.h
@@ -21,9 +21,12 @@
#include <poppler-glibmm/document.h>
#include <gtkmm/box.h>
+#include <gtkmm/paned.h>
#include <gtkmm/progressbar.h>
#include <gtkmm/button.h>
+#include <gtkmm/checkbutton.h>
#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/drawingarea.h>
#include <gtkmm/treeview.h>
#include <gtkmm/treestore.h>
@@ -40,15 +43,25 @@ class Find : public Gtk::Box
void set_button_sensitivity();
void update_progress(int n_pages, int scanned);
bool find_text();
+ bool drawing_area_draw(const Cairo::RefPtr<Cairo::Context>& cr);
+ void queue_redraw();
+ void selection_changed();
+ void case_sensitive_toggled();
+ void backwards_toggled();
+ void whole_words_toggled();
const Glib::RefPtr<Poppler::Document> m_Document;
int m_NPages;
- int m_PageIndex;
+ int m_PageIndex, m_SelectedPage;
+ Poppler::FindFlags m_Options;
+ Gdk::Rectangle m_SelectedMatch;
+ Cairo::RefPtr<Cairo::ImageSurface> m_Surface;
class ModelColumns : public Gtk::TreeModel::ColumnRecord
{
public:
- ModelColumns() { add(m_Matches); add(m_X1); add(m_Y1); add(m_X2); add(m_Y2); add(m_Visible); }
+ ModelColumns() { add(m_Matches); add(m_X1); add(m_Y1); add(m_X2); add(m_Y2);
+ add(m_Visible); add(m_PageColumn); add(m_Rect); }
Gtk::TreeModelColumn<Glib::ustring> m_Matches;
Gtk::TreeModelColumn<double> m_X1;
@@ -56,13 +69,18 @@ class Find : public Gtk::Box
Gtk::TreeModelColumn<double> m_X2;
Gtk::TreeModelColumn<double> m_Y2;
Gtk::TreeModelColumn<bool> m_Visible;
+ Gtk::TreeModelColumn<int> m_PageColumn;
+ Gtk::TreeModelColumn<Poppler::Rectangle> m_Rect;
};
- Gtk::Box m_HBoxTop;
+ Gtk::Box m_HBoxTop, m_HBoxOptions;
Gtk::ProgressBar m_ProgressBar;
Gtk::Entry m_TextEntry;
Gtk::Button m_FindButton;
- Gtk::ScrolledWindow m_ScrolledWin;
+ Gtk::CheckButton m_CaseSensitiveCButton, m_BackwardsCButton, m_WholeWordsCButton;
+ Gtk::ScrolledWindow m_MatchScrolledWin, m_DAScrolledWin;
+ Gtk::Paned m_HPaned;
+ Gtk::DrawingArea m_DrawingArea;
Gtk::TreeView m_TreeView;
ModelColumns m_StoreColumns;
Glib::RefPtr<Gtk::TreeStore> m_MatchStore;