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),
" <menu action='MenuFile'>"
" <menuitem action='FileQuit'/>"
" </menu>"
+ " <menu action='MenuEdit'>"
+ " <menuitem action='EditCopy'/>"
+ " </menu>"
" <menu action='MenuView'>"
" <menuitem action='ViewRefresh'/>"
" <menuitem action='ViewStop'/>"
" <popup name='MenuPopup'>"
" <menuitem action='ViewRefresh'/>"
" <menuitem action='ViewStop'/>"
+ " <menuitem action='EditCopy'/>"
" <separator/>"
" <menuitem action='ViewMenubar'/>"
" </popup>"
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;
}
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();
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;
void on_action_file_open();
+ virtual void on_action_edit_copy();
virtual void on_action_view_refresh();
virtual void on_action_view_stop();
private:
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 */
namespace text_view {
class DrawingSet;
class LayoutSet;
+ class GetSelectedSet;
}
*/
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.
#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"
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;
#define TEXT_LINE_HXX
#include <boost/ptr_container/ptr_vector.hpp>
+#include <glibmm/ustring.h>
namespace dialektos {
namespace text_view {
class DrawingSet;
class LayoutSet;
+ class GetSelectedSet;
}
namespace text_element {
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_; }
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
#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 {
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&) {}
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*);
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 {
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: