OSDN Git Service

Add menuitem 'copy'.
authorAiwota Programmer <aiwotaprog@tetteke.tk>
Fri, 3 Jul 2009 02:08:03 +0000 (11:08 +0900)
committerAiwota Programmer <aiwotaprog@tetteke.tk>
Fri, 3 Jul 2009 02:08:03 +0000 (11:08 +0900)
13 files changed:
src/application_framework.cxx
src/application_framework.hxx
src/board_window.cxx
src/board_window.hxx
src/text_element_plain.cxx
src/text_element_plain.hxx
src/text_line.cxx
src/text_line.hxx
src/text_view_drawing_set.hxx
src/text_view_pointer_trackable.cxx
src/text_view_pointer_trackable.hxx
src/thread_window.cxx
src/thread_window.hxx

index efded30..305aae0 100644 (file)
@@ -65,6 +65,11 @@ void ApplicationFrameWork::build_menubar() {
   action_group_->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT),
       sigc::mem_fun(*this, &ApplicationFrameWork::on_action_file_quit));
 
+  // Edit menu
+  action_group_->add(Gtk::Action::create("MenuEdit", "_Edit"));
+  action_group_->add(Gtk::Action::create("EditCopy", Gtk::Stock::COPY),
+      sigc::mem_fun(*this, &ApplicationFrameWork::on_action_edit_copy));
+
   // View menu
   action_group_->add(Gtk::Action::create("MenuView", "_View"));
   action_group_->add(Gtk::Action::create("ViewRefresh", Gtk::Stock::REFRESH),
@@ -92,6 +97,9 @@ void ApplicationFrameWork::build_menubar() {
     "    <menu action='MenuFile'>"
     "      <menuitem action='FileQuit'/>"
     "    </menu>"
+    "    <menu action='MenuEdit'>"
+    "      <menuitem action='EditCopy'/>"
+    "    </menu>"
     "    <menu action='MenuView'>"
     "      <menuitem action='ViewRefresh'/>"
     "      <menuitem action='ViewStop'/>"
@@ -111,6 +119,7 @@ void ApplicationFrameWork::build_menubar() {
     "  <popup name='MenuPopup'>"
     "    <menuitem action='ViewRefresh'/>"
     "    <menuitem action='ViewStop'/>"
+    "    <menuitem action='EditCopy'/>"
     "    <separator/>"
     "    <menuitem action='ViewMenubar'/>"
     "  </popup>"
@@ -137,6 +146,10 @@ void ApplicationFrameWork::on_action_file_quit() {
   Gtk::Main::quit();
 }
 
+void ApplicationFrameWork::on_action_edit_copy() {
+  std::cout << "edit copy activated" << std::endl;
+}
+
 void ApplicationFrameWork::on_action_view_refresh() {
   std::cout << "view refresh activated" << std::endl;
 }
index 4d24a8e..73c0b58 100644 (file)
@@ -43,6 +43,7 @@ public:
 protected:
   void build_menubar();
   virtual void on_action_file_quit();
+  virtual void on_action_edit_copy();
   virtual void on_action_view_refresh();
   virtual void on_action_view_stop();
   virtual void on_action_view_menubar();
index 6a7a2ac..fe8de9d 100644 (file)
@@ -292,6 +292,26 @@ void BoardWindow::on_action_file_open() {
   std::cout << "file open activated" << std::endl;
 }
 
+void BoardWindow::on_action_edit_copy() {
+  Glib::RefPtr<const Gtk::TreeSelection> selection =
+    tree_view_.get_selection();
+
+  std::vector<Gtk::TreeModel::Path> paths = selection->get_selected_rows();
+  if (paths.empty()) return;
+
+  std::string selected;
+  BOOST_FOREACH(Gtk::TreeModel::Path path, paths) {
+    Gtk::TreeRow row = *(tree_model_->get_iter(path));
+    std::string id;
+    row.get_value(boost::mpl::find<model_column::List,
+        model_column::ID>::type::pos::value, id);
+    if (id.empty()) continue;
+    if (!selected.empty()) selected += "\n";
+    selected += bbs_->get_another_thread_uri(id);
+  }
+  Gtk::Clipboard::get()->set_text(selected);
+}
+
 void BoardWindow::on_action_view_refresh() {
   if (http_getter_) return;
 
index 6be2fcc..5b29b4e 100644 (file)
@@ -55,6 +55,7 @@ protected:
 
   void on_action_file_open();
 
+  virtual void on_action_edit_copy();
   virtual void on_action_view_refresh();
   virtual void on_action_view_stop();
 private:
index 70d0b3f..2f337d9 100644 (file)
@@ -68,6 +68,15 @@ void Plain::trim_right() {
   boost::trim_right_if(str_, _1 == ' ');
 }
 
+Glib::ustring Plain::get_selected_text(
+    const text_view::GetSelectedSet& set) const {
+  size_t start_index = 0;
+  size_t end_index = 0;
+  get_selection_start_end_index(set.start_element, set.start_index,
+      set.end_element, set.end_index, start_index, end_index);
+  return str_.substr(start_index, end_index-start_index);
+}
+
 void Plain::layout(text_view::LayoutSet& set) {
 
   /* caching for drawing */
index c212d67..3f40a88 100644 (file)
@@ -37,6 +37,7 @@ namespace dialektos {
 namespace text_view {
   class DrawingSet;
   class LayoutSet;
+  class GetSelectedSet;
 }
 
 
@@ -92,6 +93,12 @@ public:
    */
   Glib::ustring get_text() const { return str_; }
 
+  /*! @brief return selected string
+   *
+   * @return selected text
+   */
+  Glib::ustring get_selected_text(const text_view::GetSelectedSet& set) const;
+
   /*! @brief return left-top position of this element.
    *
    * @return pair of x and y, y position is on the adjustment.
index 3b0ccc4..2d2c553 100644 (file)
@@ -21,6 +21,8 @@
 #include "text_line.hxx"
 
 #include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <algorithm>
 #include "text_view_drawing_set.hxx"
 #include "text_element_plain.hxx"
 
@@ -55,6 +57,21 @@ bool TextLine::empty() const {
   return element_list_.empty();
 }
 
+bool TextLine::includes(const text_element::Plain& right) const {
+  using namespace boost::lambda;
+  return std::find_if(element_list_.begin(), element_list_.end(),
+      &_1 == &right) != element_list_.end();
+}
+
+Glib::ustring TextLine::get_selected_text(
+    const text_view::GetSelectedSet& set) const {
+  Glib::ustring selected;
+  BOOST_FOREACH(const text_element::Plain& element, element_list_) {
+    selected += element.get_selected_text(set);
+  }
+  return selected;
+}
+
 void TextLine::layout(text_view::LayoutSet& set) {
   width_ = set.x_end - set.x_start;
   y_ = set.y;
index 0a923bf..1ea9636 100644 (file)
@@ -22,6 +22,7 @@
 #define TEXT_LINE_HXX
 
 #include <boost/ptr_container/ptr_vector.hpp>
+#include <glibmm/ustring.h>
 
 
 namespace dialektos {
@@ -30,6 +31,7 @@ namespace dialektos {
 namespace text_view {
   class DrawingSet;
   class LayoutSet;
+  class GetSelectedSet;
 }
 
 namespace text_element {
@@ -45,6 +47,8 @@ public:
   void add_element(text_element::Plain* element);
   void trim_right();
   bool empty() const;
+  bool includes(const text_element::Plain&) const;
+  Glib::ustring get_selected_text(const text_view::GetSelectedSet& set) const;
   void layout(text_view::LayoutSet&);
   void draw(text_view::DrawingSet&) const;
   double get_height() const { return height_; }
index df45cf2..c4ec3b4 100644 (file)
@@ -59,6 +59,13 @@ struct DrawingSet {
   int end_index;
 };
 
+struct GetSelectedSet {
+  const text_element::Plain* start_element;
+  int start_index;
+  const text_element::Plain* end_element;
+  int end_index;
+};
+
 
 } // namespace text_view
 
index c1658b2..4226153 100644 (file)
 
 #include <gdkmm/cursor.h>
 #include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <functional>
 #include <typeinfo>
 #include "text_element_plain.hxx"
 #include "text_element_anchor.hxx"
 #include "text_element_id.hxx"
 #include "text_element_res_num.hxx"
+#include "text_view_drawing_set.hxx"
+#include "text_line.hxx"
 
 
 namespace dialektos {
@@ -46,6 +51,48 @@ PointerTrackable::PointerTrackable(): Layoutable(),
 
 PointerTrackable::~PointerTrackable() {}
 
+Glib::ustring PointerTrackable::get_selected_text() const {
+  if (!pressed_element_ || !hovered_element_) return "";
+
+  GetSelectedSet set;
+  set.start_element = pressed_element_;
+  set.start_index = pressed_index_;
+  set.end_element = hovered_element_;
+  set.end_index = hovered_index_;
+
+  std::pair<gdouble, gdouble> pressed_xy = pressed_element_->get_xy();
+  std::pair<gdouble, gdouble> hovered_xy = hovered_element_->get_xy();
+
+  if ((pressed_element_ == hovered_element_
+      && pressed_index_ > hovered_index_) ||
+      (pressed_xy.second == hovered_xy.second
+          && pressed_xy.first > hovered_xy.first) ||
+          (pressed_xy.second > hovered_xy.second)) {
+    std::swap(set.start_element, set.end_element);
+    std::swap(set.start_index, set.end_index);
+  }
+
+  LineListType::const_iterator it_start = std::find_if(
+      line_list_.begin(), line_list_.end(),
+      boost::bind(&TextLine::includes, _1, boost::ref(*set.start_element)));
+  if (it_start == line_list_.end()) return "";
+
+  LineListType::const_iterator it_end = std::find_if(
+      line_list_.begin(), line_list_.end(),
+      boost::bind(&TextLine::includes, _1, boost::ref(*set.end_element)));
+  if (it_end == line_list_.end()) return "";
+  ++it_end;
+
+  Glib::ustring selected;
+  for (LineListType::const_iterator it = it_start;;) {
+    selected += it->get_selected_text(set);
+    ++it;
+    if (it == it_end) break;
+    selected += "\n";
+  }
+  return selected;
+}
+
 void PointerTrackable::on_anchor_click_event(const text_element::Anchor&) {}
 void PointerTrackable::on_anchor_hovered_event(const text_element::Anchor&) {}
 
index 3c1c7cf..5ac0449 100644 (file)
@@ -38,6 +38,7 @@ class PointerTrackable: public Layoutable {
 public:
   PointerTrackable();
   virtual ~PointerTrackable();
+  Glib::ustring get_selected_text() const;
 protected:
   virtual bool on_button_press_event(GdkEventButton*);
   virtual bool on_button_release_event(GdkEventButton*);
index deb493a..bda9d3d 100644 (file)
@@ -151,6 +151,11 @@ void ThreadWindow::on_action_view_stop() {
   if (http_getter_) http_getter_->cancel();
 }
 
+void ThreadWindow::on_action_edit_copy() {
+  const Glib::ustring selected = text_view_->get_selected_text();
+  Gtk::Clipboard::get()->set_text(selected);
+}
+
 void ThreadWindow::on_action_file_delete() {
   const boost::filesystem::path dat(bbs_->get_thread_file_path());
   try {
index bde62a7..e503f2c 100644 (file)
@@ -50,6 +50,7 @@ protected:
 
   virtual void on_action_view_refresh();
   virtual void on_action_view_stop();
+  virtual void on_action_edit_copy();
   void on_action_file_delete();
   void on_action_file_board();
 private: