22 #include <libgtkcrnmm_config.h>
34 #ifndef CRN_USING_GTKMM3
35 # define get_content_area get_vbox
38 using namespace GtkCRN;
48 #ifdef CRN_USING_GTKMM3
49 views_actions(Gio::SimpleActionGroup::create()),
51 views_actions(Gtk::ActionGroup::create(
"views")),
54 view_frame(
_(
"Views")),
55 show_thumbnails(
true),
58 #ifdef CRN_USING_GTKMM3
59 tree_actions(Gio::SimpleActionGroup::create()),
61 tree_actions(Gtk::ActionGroup::create(
"tree")),
63 treecol1(uint8_t(0), 0, 0),
64 treecol2(uint8_t(255), 255, 255),
65 treetextcol(uint8_t(0), 0, 0),
66 selcol1(uint8_t(0), 127, 0),
67 selcol2(uint8_t(0), 255, 0),
68 show_subblock_labels(
true),
70 tree_frame(
_(
"Blocks"))
76 #ifdef CRN_USING_GTKMM3
83 views_actions->add_action(
"document-views-select-all", sigc::mem_fun(
this, &
Document::select_all));
86 views_actions->add_action(
"document-views-select-odd", sigc::mem_fun(
this, &
Document::select_odd));
89 # ifdef CRN_USING_HARU
90 views_actions->add_action(
"document-views-export-pdf", sigc::mem_fun(
this, &Document::export_pdf));
93 views_actions->add(Gtk::Action::create(
"document-views-menu",
_(
"_Views"),
_(
"Views")));
94 views_actions->add(Gtk::Action::create(
"document-views-add", Gtk::StockID(
"gtk-crn-add-view"),
_(
"_Add Views"),
_(
"Add Views")), sigc::mem_fun(
this, &
Document::append_views_dialog));
95 views_actions->add(Gtk::Action::create(
"document-views-refresh", Gtk::Stock::REFRESH,
_(
"_Refresh Views"),
_(
"Refresh Views")), sigc::mem_fun(
this, &
Document::refresh_views));
96 views_actions->add(Gtk::Action::create(
"document-views-select-first", Gtk::Stock::GOTO_FIRST,
_(
"Select _First View"),
_(
"Select First View")), sigc::mem_fun(
this, &
Document::select_first));
97 views_actions->add(Gtk::Action::create(
"document-views-select-previous", Gtk::Stock::GO_BACK,
_(
"Select _Previous View"),
_(
"Select Previous View")), sigc::mem_fun(
this, &
Document::select_previous));
98 views_actions->add(Gtk::Action::create(
"document-views-select-next", Gtk::Stock::GO_FORWARD,
_(
"Select _Next View"),
_(
"Select Next View")), sigc::mem_fun(
this, &
Document::select_next));
99 views_actions->add(Gtk::Action::create(
"document-views-select-last", Gtk::Stock::GOTO_LAST,
_(
"Select _Last View"),
_(
"Select Last View")), sigc::mem_fun(
this, &
Document::select_last));
100 views_actions->add(Gtk::Action::create(
"document-views-select-all", Gtk::Stock::SELECT_ALL,
_(
"Select _All Views"),
_(
"Select All Views")), sigc::mem_fun(
this, &
Document::select_all));
101 views_actions->add(Gtk::Action::create(
"document-views-select-none", Gtk::Stock::CLEAR,
_(
"_Deselect Views"),
_(
"Deselect Views")), sigc::mem_fun(
this, &
Document::deselect_all));
102 views_actions->add(Gtk::Action::create(
"document-views-select-even", Gtk::StockID(
"gtk-crn-even"),
_(
"Select _Even Views"),
_(
"Select _Even Views")), sigc::mem_fun(
this, &
Document::select_even));
103 views_actions->add(Gtk::Action::create(
"document-views-select-odd", Gtk::StockID(
"gtk-crn-odd"),
_(
"Select _Odd Views"),
_(
"Select _Odd Views")), sigc::mem_fun(
this, &
Document::select_odd));
104 views_actions->add(Gtk::Action::create(
"document-views-invert-selection", Gtk::StockID(
"gtk-crn-invert"),
_(
"_Invert View Selection"),
_(
"Invert View Selection")), sigc::mem_fun(
this, &
Document::invert_selection));
105 views_actions->add(Gtk::Action::create(
"document-views-remove", Gtk::StockID(
"gtk-crn-delete-view"),
_(
"_Remove View Selection"),
_(
"Remove View Selection")), sigc::mem_fun(
this, &
Document::delete_selection));
106 # ifdef CRN_USING_HARU
107 views_actions->add(Gtk::Action::create(
"document-views-export-pdf", Gtk::Stock::CONVERT,
_(
"_Export PDF"),
_(
"Export PDF")), sigc::mem_fun(
this, &Document::export_pdf));
112 #ifdef CRN_USING_GTKMM3
113 tree_actions->add_action(
"document-blocks-add", sigc::mem_fun(
this, &Document::add_subblock));
114 tree_actions->add_action(
"document-blocks-remove", sigc::mem_fun(
this, &Document::rem_subblock));
115 tree_actions->add_action_bool(
"document-blocks-show", sigc::mem_fun(
this, &Document::show_hide_subblocks_on_image));
116 tree_actions->add_action(
"document-blocks-configure", sigc::mem_fun(
this, &Document::configure_subblocks));
118 tree_actions->add(Gtk::Action::create(
"document-blocks-add", Gtk::StockID(
"gtk-crn-add-block"),
_(
"_Add Subblock"),
_(
"Add Subblock")), sigc::mem_fun(
this, &Document::add_subblock));
119 tree_actions->add(Gtk::Action::create(
"document-blocks-remove", Gtk::StockID(
"gtk-crn-delete-block"),
_(
"_Remove Subblock"),
_(
"Remove Subblock")), sigc::mem_fun(
this, &Document::rem_subblock));
120 tree_actions->add(Gtk::ToggleAction::create(
"document-blocks-show", Gtk::Stock::FIND,
_(
"_Show/Hide Subblocks"),
_(
"Show/Hide Subblocks"),
true), sigc::mem_fun(
this, &Document::show_hide_subblocks_on_image));
121 tree_actions->add(Gtk::Action::create(
"document-blocks-configure", Gtk::Stock::PROPERTIES,
_(
"Subblocks _Settings"),
_(
"Subblocks Settings")), sigc::mem_fun(
this, &Document::configure_subblocks));
131 pack1(vpan, Gtk::FILL);
134 view_frame.set_shadow_type(Gtk::SHADOW_NONE);
135 view_frame.add(view_box);
138 view_box.
set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
139 droppedin_handle = view_box.
signal_droppedin().connect(sigc::mem_fun(
this, &Document::droppedin));
140 view_box.
signal_moved().connect(sigc::mem_fun(
this, &Document::moved));
142 view_box.signal_key_release_event().connect(sigc::mem_fun(
this, &Document::boxkeyevents));
143 view_box.set_size_request(120, 120);
144 vpan.pack1(view_frame, Gtk::FILL);
150 tree_frame.set_shadow_type(Gtk::SHADOW_NONE);
151 tree_frame.add(tree_box);
153 tree_box.set_homogeneous(
false);
155 #ifdef CRN_USING_GTKMM3
157 auto builder = Gtk::Builder::create_from_string(
159 " <object class='GtkToolButton' id='dbadd'>"
160 " <attribute name='label' translatable='yes'>_Add subblock</attribute>"
161 " <attribute name='action'>document-blocks-add</attribute>"
163 " <object class='GtkToolButton' id='dbrem'>"
164 " <attribute name='label' translatable='yes'>_Remove subblock</attribute>"
165 " <attribute name='action'>document-blocks-remove</attribute>"
167 " <object class='GtkToolButton' id='dbshow'>"
168 " <attribute name='label' translatable='yes'>_Show/Hide Subblocks</attribute>"
169 " <attribute name='action'>document-blocks-show</attribute>"
171 " <object class='GtkToolButton' id='dbconf'>"
172 " <attribute name='label' translatable='yes'>Subblocks _Settings</attribute>"
173 " <attribute name='action'>document-blocks-configure</attribute>"
178 builder->get_widget(
"dbadd", ti);
179 tree_buttons.append(*Gtk::manage(ti));
180 builder->get_widget(
"dbrem", ti);
181 tree_buttons.append(*Gtk::manage(ti));
182 builder->get_widget(
"dbshow", ti);
183 tree_buttons.append(*Gtk::manage(ti));
184 builder->get_widget(
"dbconf", ti);
185 tree_buttons.append(*Gtk::manage(ti));
187 tree_buttons.append(*Gtk::manage(tree_actions->get_action(
"document-blocks-add")->create_tool_item()));
188 tree_buttons.append(*Gtk::manage(tree_actions->get_action(
"document-blocks-remove")->create_tool_item()));
189 tree_buttons.append(*Gtk::manage(tree_actions->get_action(
"document-blocks-show")->create_tool_item()));
190 tree_buttons.append(*Gtk::manage(tree_actions->get_action(
"document-blocks-configure")->create_tool_item()));
193 tree_box.pack_start(tree_buttons,
false,
true, 0);
195 block_tree_store = Gtk::TreeStore::create(block_columns);
196 block_tree_view.set_model(block_tree_store);
197 block_tree_view.show();
198 block_tree_view.append_column(
_(
"Block name"), block_columns.name);
199 block_tree_view.append_column(
_(
"Coordinates"), block_columns.coords);
200 block_tree_view.get_selection()->signal_changed().connect(sigc::mem_fun(
this, &Document::subblock_selection_changed));
201 tree_sw.add(block_tree_view);
203 tree_box.pack_start(tree_sw,
true,
true, 0);
204 vpan.pack2(tree_frame, Gtk::FILL);
210 pack2(image_box, Gtk::EXPAND | Gtk::FILL);
212 image_box.pack_start(left_box,
false,
true, 0);
223 image_box.pack_start(img,
true,
true, 0);
225 image_box.pack_start(right_box,
false,
true, 0);
227 set_sensitive(
false);
259 set_sensitive(
false);
268 Document::View::View(
const crn::String &
id, crn::SDocument doc):
273 thumb.set(doc->GetThumbnailFilename(
id).CStr());
280 pack_start(thumb, FALSE,
TRUE, 0);
291 pack_start(index, FALSE,
TRUE, 0);
295 lab.set_text(doc->GetViewFilename(
id).CStr());
299 lab.set_text(
_(
"Inexistent view"));
302 lab.set_ellipsize(Pango::ELLIPSIZE_START);
303 pack_start(lab, FALSE,
TRUE, 0);
312 for (
size_t tmp = 0; tmp < crndoc->GetNbViews(); ++tmp)
316 crndoc->GetThumbnailFilename(tmp);
320 App::show_message(
_(
"The document was never saved. It is impossible to generate thumbnails."), Gtk::MESSAGE_WARNING);
333 g_snprintf(message, 1024,
_(
"%i error(s) occurred during the generation of the thumbnails. Some images may be deffective."), nb_errors);
353 if (crndoc->GetNbViews() == 0)
360 pwin.
run(sigc::bind(sigc::mem_fun(
this, &Document::create_view_cache), prog));
362 bool reselectlast =
false;
364 for (
size_t tmp = 0; tmp < crndoc->GetNbViews(); ++tmp)
371 views.push_back(std::make_shared<View>(vid, crndoc));
372 views.back()->show();
373 view_box.
pack_start(*views.back(),
false,
true, 0);
376 for (
size_t tmp = 0; tmp < sel.size(); ++tmp)
383 view_box.
set_selected(crndoc->GetViewIndex(sel[tmp]),
true, reselectlast || (tmp != (sel.size() - 1)));
392 view_box.
set_selected(crndoc->GetViewIndex(lastsel),
true,
false);
398 std::vector<Gtk::Widget*> selection(view_box.
get_selection());
399 std::vector<crn::String> selid;
400 for (Gtk::Widget *w : selection)
402 View *v =
dynamic_cast<View*
>(w);
403 selid.push_back(v->get_view_id());
413 return v->get_view_id();
424 size_t index = crndoc->GetViewIndex(view_id);
434 std::vector<crn::StringUTF8> files(data.
Split(
"\r\n"));
442 crndoc->InsertView(p, pos);
453 void Document::moved(std::vector<size_t> to, std::vector<size_t> from)
455 crndoc->ReorderViewsTo(to);
456 for (std::shared_ptr<View> v : views)
458 v->set_index(crndoc->GetViewIndex(v->get_view_id()));
466 void Document::on_view_selection_changed(Gtk::Widget *last_selected_widget,
const std::vector<Gtk::Widget*> selection)
472 if (last_selected_widget !=
nullptr)
474 View *v =
dynamic_cast<View*
>(last_selected_widget);
477 lastselid = v->get_view_id();
478 current_block = crndoc->GetView(v->get_view_id());
479 load_tree(v->get_view_id());
481 selection_changed.emit(lastselid, selid);
489 current_block =
nullptr;
494 selection_changed.emit(lastselid, selid);
501 bool Document::boxkeyevents(GdkEventKey *ev)
503 #ifdef CRN_USING_GTKMM3
504 if (ev->keyval == GDK_KEY_Delete)
506 if (ev->keyval == GDK_Delete)
517 for (std::shared_ptr<View> v : views)
519 v->set_show_thumbnail(s);
526 for (std::shared_ptr<View> v : views)
528 v->set_show_label(s);
535 for (std::shared_ptr<View> v : views)
537 v->set_show_index(s);
545 gboolean Document::tsreloadimage(DVI *data)
547 data->doc->reload_image(data->id);
554 const std::vector<Gtk::Widget*> sel(view_box.
get_selection());
557 if (!may_delete_selection.empty())
560 if (!may_delete_selection.emit(selid))
566 for (Gtk::Widget *w : sel)
568 View *v =
dynamic_cast<View*
>(w);
573 crndoc->RemoveView(v->get_view_id());
589 if (fname.IsNotEmpty())
590 crndoc->AddView(fname);
597 Gtk::FileChooserDialog dial((Gtk::Window&)(*get_ancestor(GTK_TYPE_WINDOW)),
_(
"Please select views to add"), Gtk::FILE_CHOOSER_ACTION_OPEN);
598 dial.set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
599 #ifdef CRN_USING_GTKMM3
600 auto ff = Gtk::FileFilter::create();
601 ff->add_pixbuf_formats();
604 ff.add_pixbuf_formats();
607 dial.set_select_multiple(
true);
608 #ifdef CRN_USING_GTKMM3
609 dial.add_button(
_(
"_Cancel"), Gtk::RESPONSE_CANCEL);
610 dial.add_button(
_(
"_Add"), Gtk::RESPONSE_ACCEPT);
612 dial.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
613 dial.add_button(Gtk::Stock::ADD, Gtk::RESPONSE_ACCEPT);
614 std::vector<int> altbut;
615 altbut.push_back(Gtk::RESPONSE_ACCEPT);
616 altbut.push_back(Gtk::RESPONSE_CANCEL);
617 dial.set_alternative_button_order_from_array(altbut);
619 dial.set_default_response(Gtk::RESPONSE_ACCEPT);
621 int resp = dial.run();
623 if (resp == Gtk::RESPONSE_ACCEPT)
625 #ifdef CRN_USING_GTKMM3
626 const auto uris = dial.get_uris();
627 auto fnames = std::vector<crn::Path>{};
628 for (
const auto &uri : uris)
629 fnames.push_back(uri.c_str());
631 std::vector<crn::Path> fnames(dial.get_uris());
687 void Document::clear_tree()
689 block_tree_store->clear();
690 img.
set_pixbuf(Glib::RefPtr<Gdk::Pixbuf>(
nullptr));
696 void Document::load_tree(
const crn::String &view_id)
701 crn::SBlock b(crndoc->GetView(view_id));
704 Gtk::TreeModel::iterator it(block_tree_store->append());
705 it->set_value(block_columns.name, Glib::ustring(b->GetName().CStr()));
706 it->set_value(block_columns.block, b);
707 it->set_value(block_columns.is_tree,
false);
708 it->set_value(block_columns.coords, Glib::ustring(b->GetAbsoluteBBox().ToString().CStr()));
709 tree_add_children(it, b);
710 block_tree_view.expand_row(Gtk::TreePath(it),
false);
711 block_tree_view.get_selection()->select(it);
723 void Document::tree_add_children(Gtk::TreeModel::iterator &it, crn::SBlock b)
725 std::vector<crn::String> trees(b->GetTreeNames());
728 Gtk::TreeModel::iterator bit(block_tree_store->append(it->children()));
729 bit->set_value(block_columns.name, Glib::ustring(tname.CStr()));
730 bit->set_value(block_columns.block, b);
731 bit->set_value(block_columns.is_tree,
true);
732 for (crn::SObject sbo : b->GetTree(tname))
734 crn::SBlock sb(std::static_pointer_cast<crn::Block>(sbo));
735 Gtk::TreeModel::iterator sit(block_tree_store->append(bit->children()));
736 sit->set_value(block_columns.name, Glib::ustring(sb->GetName().CStr()));
737 sit->set_value(block_columns.block, sb);
738 sit->set_value(block_columns.is_tree,
false);
739 sit->set_value(block_columns.coords, Glib::ustring(sb->GetAbsoluteBBox().ToString().CStr()));
740 tree_add_children(sit, sb);
746 void Document::subblock_selection_changed()
749 if (viewid.IsNotEmpty() && block_tree_view.get_selection()->count_selected_rows())
754 Gtk::TreeIter it(block_tree_view.get_selection()->get_selected());
756 blocksel = it->get_value(block_columns.block);
760 crn::Rect clip(blocksel->GetAbsoluteBBox());
761 Glib::RefPtr<Gdk::Pixbuf> pb2(Gdk::Pixbuf::create_subpixbuf(pb, clip.GetLeft(), clip.GetTop(), clip.GetWidth(), clip.GetHeight()));
766 set_enable_action(tree_actions,
"document-blocks-remove", it != block_tree_store->children()[0]);
770 img.
set_pixbuf(Glib::RefPtr<Gdk::Pixbuf>(
nullptr));
780 show_hide_subblocks_on_image();
784 void Document::add_subblock()
790 if (block_tree_view.get_selection()->count_selected_rows())
792 Gtk::TreeIter it(block_tree_view.get_selection()->get_selected());
793 b = it->get_value(block_columns.block);
794 if (it->get_value(block_columns.is_tree))
795 autoselect = it->get_value(block_columns.name).c_str();
802 Gtk::Dialog dial(
_(
"Add a subblock"), (Gtk::Window&)(*get_ancestor(GTK_TYPE_WINDOW)),
true);
803 dial.set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
804 #ifdef CRN_USING_GTKMM3
805 dial.add_button(
_(
"_Cancel"), Gtk::RESPONSE_CANCEL);
806 dial.add_button(
_(
"_OK"), Gtk::RESPONSE_ACCEPT);
808 dial.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
809 dial.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
810 std::vector<int> altbut;
811 altbut.push_back(Gtk::RESPONSE_ACCEPT);
812 altbut.push_back(Gtk::RESPONSE_CANCEL);
813 dial.set_alternative_button_order_from_array(altbut);
815 dial.set_default_response(Gtk::RESPONSE_ACCEPT);
816 Gtk::Label lab1(
_(
"Subblock tree"));
817 Gtk::Label lab2(
_(
"New subblock's name"));
818 #ifdef CRN_USING_GTKMM3
820 tab.attach(lab1, 0, 0, 1, 1);
821 tab.attach(lab2, 0, 1, 1, 1);
823 Gtk::Table tab(2, 2);
824 tab.attach(lab1, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
825 tab.attach(lab2, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
827 #ifdef CRN_USING_GTKMM3
828 Gtk::ComboBoxText combo(
true);
830 Gtk::ComboBoxEntryText combo;
832 std::vector<crn::String> trees(b->GetTreeNames());
835 #ifdef CRN_USING_GTKMM3
836 combo.append(tname.CStr());
838 combo.append_text(tname.CStr());
841 combo.get_entry()->set_text(autoselect.
CStr());
842 combo.get_entry()->set_activates_default(
true);
843 #ifdef CRN_USING_GTKMM3
844 tab.attach(combo, 1, 0, 1, 1);
846 tab.attach(combo, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
849 entname.set_text(
_(
"New subblock"));
850 entname.set_activates_default(
true);
851 #ifdef CRN_USING_GTKMM3
852 tab.attach(entname, 1, 1, 1, 1);
854 tab.attach(entname, 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
857 dial.get_content_area()->pack_start(tab,
true,
true, 0);
859 if (dial.run() == Gtk::RESPONSE_ACCEPT)
864 crn::SBlock nb(
nullptr);
867 nb = b->AddChildRelative(treename, bbox, entname.get_text().c_str());
871 App::show_message(
_(
"Cannot add such selection to the subblock tree."), Gtk::MESSAGE_WARNING);
876 if (block_tree_view.get_selection()->count_selected_rows())
878 it = block_tree_view.get_selection()->get_selected();
879 if (it->get_value(block_columns.is_tree))
885 it = block_tree_store->children()[0];
888 for (
const Gtk::TreeRow &row : it->children())
890 if (row.get_value(block_columns.is_tree) && (row.get_value(block_columns.name) == treename.CStr()))
893 newit = block_tree_store->append(row.children());
902 newit = block_tree_store->append(it->children());
903 newit->set_value(block_columns.name, Glib::ustring(treename.CStr()));
904 newit->set_value(block_columns.block, b);
905 newit->set_value(block_columns.is_tree,
true);
908 newit = block_tree_store->append(newit->children());
910 newit->set_value(block_columns.name, entname.get_text());
911 newit->set_value(block_columns.block, nb);
912 newit->set_value(block_columns.is_tree,
false);
913 newit->set_value(block_columns.coords, Glib::ustring(bbox.ToString().CStr()));
918 void Document::rem_subblock()
920 if (block_tree_view.get_selection()->count_selected_rows())
922 Gtk::TreeIter it(block_tree_view.get_selection()->get_selected());
923 if (it->get_value(block_columns.is_tree))
925 crn::SBlock b(it->get_value(block_columns.block));
926 b->RemoveTree(it->get_value(block_columns.name).c_str());
927 block_tree_store->erase(it);
931 crn::SBlock b(it->get_value(block_columns.block));
935 Gtk::TreeIter pit(it->parent());
938 pb->RemoveChild(pit->get_value(block_columns.name).c_str(), b);
940 block_tree_store->erase(it);
941 block_tree_view.get_selection()->select(pit);
948 void Document::configure_subblocks()
951 Gtk::Dialog dial(
_(
"Configure subblocks display"), (Gtk::Window&)(*get_ancestor(GTK_TYPE_WINDOW)),
true);
952 dial.set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
953 #ifdef CRN_USING_GTKMM3
954 dial.add_button(
_(
"_Cancel"), Gtk::RESPONSE_CANCEL);
955 dial.add_button(
_(
"_OK"), Gtk::RESPONSE_ACCEPT);
957 dial.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
958 dial.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
959 std::vector<int> altbut;
960 altbut.push_back(Gtk::RESPONSE_ACCEPT);
961 altbut.push_back(Gtk::RESPONSE_CANCEL);
962 dial.set_alternative_button_order_from_array(altbut);
964 dial.set_default_response(Gtk::RESPONSE_ACCEPT);
966 Gtk::Label lab1(
_(
"Frame color"));
967 Gtk::Label lab2(
_(
"Fill color"));
968 Gtk::CheckButton show_labels_cb(
_(
"Show subblock _labels"));
969 show_labels_cb.set_active(show_subblock_labels);
970 Gtk::Label lab3(
_(
"Label color"));
971 #ifdef CRN_USING_GTKMM3
973 tab.attach(lab1, 0, 0, 1, 1);
975 color.set_rgba_u(gushort(treecol1.
r * 256), gushort(treecol1.
g * 256), gushort(treecol1.
b * 255));
976 Gtk::ColorButton cb1(color);
977 tab.attach(cb1, 1, 0, 1, 1);
979 tab.attach(lab2, 0, 1, 1, 1);
980 color.set_rgba_u(gushort(treecol2.
r * 256), gushort(treecol2.
g * 256), gushort(treecol2.
b * 255));
981 Gtk::ColorButton cb2(color);
982 tab.attach(cb2, 1, 1, 1, 1);
984 tab.attach(show_labels_cb, 0, 2, 2, 1);
986 color.set_rgba_u(gushort(treetextcol.
r * 256), gushort(treetextcol.
g * 256), gushort(treetextcol.
b * 255));
987 Gtk::ColorButton cbt(color);
988 tab.attach(cbt, 1, 3, 1, 1);
989 tab.attach(lab3, 0, 3, 1, 1);
991 Gtk::Table tab(4, 2);
992 tab.attach(lab1, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
995 color.set_rgb(gushort(treecol1.
r * 256), gushort(treecol1.
g * 256), gushort(treecol1.
b * 255));
996 Gtk::ColorButton cb1(color);
997 tab.attach(cb1, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
999 tab.attach(lab2, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
1000 color.set_rgb(gushort(treecol2.
r * 256), gushort(treecol2.
g * 256), gushort(treecol2.
b * 255));
1001 Gtk::ColorButton cb2(color);
1002 tab.attach(cb2, 1, 2, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
1004 tab.attach(show_labels_cb, 0, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK);
1006 color.set_rgb(gushort(treetextcol.
r * 256), gushort(treetextcol.
g * 256), gushort(treetextcol.
b * 255));
1007 Gtk::ColorButton cbt(color);
1008 tab.attach(cbt, 1, 2, 3, 4, Gtk::SHRINK, Gtk::SHRINK);
1009 tab.attach(lab3, 0, 1, 3, 4, Gtk::SHRINK, Gtk::SHRINK);
1012 dial.get_content_area()->pack_start(tab,
true,
true, 0);
1014 if (dial.run() == Gtk::RESPONSE_ACCEPT)
1017 #ifdef CRN_USING_GTKMM3
1018 color = cb1.get_rgba();
1020 color = cb1.get_color();
1023 #ifdef CRN_USING_GTKMM3
1024 color = cb1.get_rgba();
1026 color = cb2.get_color();
1029 #ifdef CRN_USING_GTKMM3
1030 color = cb1.get_rgba();
1032 color = cbt.get_color();
1042 const crn::String Document::subblock_list_name(U
"GtkCRN::Document::Current_subblocks");
1046 for (std::shared_ptr<View> v : views)
1048 if (v->get_view_id() == view_id)
1050 v->set_thumbnail(crndoc->GetThumbnailFilename(view_id));
1063 img.
set_pixbuf(Glib::RefPtr<Gdk::Pixbuf>(
nullptr));
1072 DVI *data(
new DVI(
this, view_id));
1073 g_idle_add(GSourceFunc(Document::tsreloadimage), data);
1090 void Document::show_hide_subblocks_on_image()
1096 if (block_tree_view.get_selection()->count_selected_rows())
1098 Gtk::TreeIter it(block_tree_view.get_selection()->get_selected());
1099 if (it->get_value(block_columns.is_tree))
1101 crn::SBlock b(it->get_value(block_columns.block));
1102 crn::String name(it->get_value(block_columns.name).c_str());
1104 for (crn::SObject sbo : b->GetTree(name))
1106 crn::SBlock sb(std::static_pointer_cast<crn::Block>(sbo));
1107 img.
add_overlay_item(subblock_list_name, cnt++, sb->GetRelativeBBox(), sb->GetName().CStr());
1126 treetextcol = textcol;
1134 show_subblock_labels = s;
1141 #ifdef CRN_USING_HARU
1143 void Document::export_pdf()
1145 static std::shared_ptr<Gtk::FileChooserDialog> dial(
nullptr);
1146 #ifdef CRN_USING_GTKMM3
1147 static auto ff = Gtk::FileFilter::create();
1149 static Gtk::FileFilter ff;
1154 dial = std::make_shared<Gtk::FileChooserDialog>((Gtk::Window&)(*get_ancestor(GTK_TYPE_WINDOW)),
_(
"Export PDF"), Gtk::FILE_CHOOSER_ACTION_SAVE);
1155 dial->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
1156 #ifdef CRN_USING_GTKMM3
1157 ff->add_pattern(
"*.pdf");
1158 ff->add_pattern(
"*.Pdf");
1159 ff->add_pattern(
"*.PDF");
1161 ff.add_pattern(
"*.pdf");
1162 ff.add_pattern(
"*.Pdf");
1163 ff.add_pattern(
"*.PDF");
1165 dial->set_filter(ff);
1166 dial->set_select_multiple(
false);
1167 #ifdef CRN_USING_GTKMM3
1168 dial->add_button(
_(
"_Cancel"), Gtk::RESPONSE_CANCEL);
1169 dial->add_button(
_(
"_Save"), Gtk::RESPONSE_ACCEPT);
1171 dial->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1172 dial->add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1173 std::vector<int> altbut;
1174 altbut.push_back(Gtk::RESPONSE_ACCEPT);
1175 altbut.push_back(Gtk::RESPONSE_CANCEL);
1176 dial->set_alternative_button_order_from_array(altbut);
1178 dial->set_default_response(Gtk::RESPONSE_ACCEPT);
1180 dial->get_content_area()->pack_start(attr,
false,
true, 0);
1183 int resp = dial->run();
1185 if (resp == Gtk::RESPONSE_ACCEPT)
1188 ProgressWindow pwin(
_(
"Export PDF"), (Gtk::Window*)get_ancestor(GTK_TYPE_WINDOW),
false);
1189 crn::Progress *prog = pwin.get_crn_progress(pwin.add_progress_bar(
_(
"Writing image")));
1191 pwin.set_terminate_on_exception(
false);
1192 pwin.run(sigc::hide_return(sigc::bind(sigc::mem_fun(crndoc.get(), &crn::Document::ExportPDF), fname, attr.
get_attributes(), prog)));
void set_show_indexes(bool s)
Shall the views show their index.
virtual ~Document() override
Destructor.
void set_selection(size_t index)
Sets the selection (one element)
void disable_action(const Glib::RefPtr< Gtk::ActionGroup > &grp, const Glib::ustring &action)
void set_selected(size_t index, bool selected=true, bool silent=false)
Adds or remove an element from the selection.
void select_next()
If selection size is 0, the select the first element, if selection size is 1, then select the next it...
void set_policy(Gtk::PolicyType hscrollbar_policy, Gtk::PolicyType vscrollbar_policy)
Sets the scrolling policy.
std::vector< crn::String > get_selected_views_ids()
Gets the selected views' ids.
void set_show_labels(bool s)
Shall the views show a label.
Glib::RefPtr< Gdk::Pixbuf > PixbufFromFile(const crn::Path &p)
Creates a Gdk::Pixbuf from a file.
Orientation
An enumeration of orientations.
Base class for a progress display.
void set_subblocks_colors(const crn::pixel::RGB8 &col1, const crn::pixel::RGB8 &col2, const crn::pixel::RGB8 &textcol)
Sets the colors of the subblocks on the image.
void select_first()
If selection size is <= 1, then select the first view, else move last_selected to the first selected ...
void select_even()
Selects odd elements (2nd, 4th…)
OverlayConfig & get_overlay_config(const crn::String &id)
Gets the configuration of an overlay.
crn::pixel::RGB8 CRNPixelRGBFromGdkColor(const Gdk::Color &color)
Creates a crn::PixelRGB from a Gdk::Color.
Gtk::Widget * get_last_selected() const
Returns the last widget that was selected.
Unintialized object error.
void invert_selection()
Inverts the view selection.
WBlock GetParent()
Gets a reference to the parent of the block.
std::vector< StringUTF8 > Split(const StringUTF8 &sep) const
Splits the string in multiple strings delimited by a set of separators.
const crn::Rect & get_selection_as_rect() const
Gets the mouse selection as a rectangle.
void select_all()
Selects all views.
void select_even()
Selects even views.
sigc::signal< void, int, crn::StringUTF8 > signal_droppedin()
Signals when something was dropped from another application. Connect to void on_droppedin(int positio...
void delete_selection()
Removes all selected views from the document.
bool is_toggle_action_active(const Glib::RefPtr< Gtk::ActionGroup > &grp, const Glib::ustring &action)
void select_odd()
Selects odd views.
static std::mutex & GetMutex(const Path &fname)
Gets the mutex associated to a file.
void Advance()
Progresses of one step.
A UTF32 character string class.
crn::Progress * get_crn_progress(size_t id)
Gets an existing progress bar.
void enable_action_group(const Glib::RefPtr< Gtk::ActionGroup > &grp)
void enable_action(const Glib::RefPtr< Gtk::ActionGroup > &grp, const Glib::ustring &action)
void append_views_dialog()
void clear_overlay(const crn::String &id)
Clears an overlay.
void thread_safe_reload_image(const crn::String &view_id)
Refreshes the thumbnail of a view and the Image if needed (thread safe)
void SetType(Type typ) noexcept
Sets the type of progress bar.
const char * CStr() const noexcept
Conversion to UTF8 cstring.
Splash window with progress bars.
crn::String get_selected_view_id()
Gets the displayed views's id.
void set_enable_action(const Glib::RefPtr< Gtk::ActionGroup > &grp, const Glib::ustring &action, bool enabled)
A convenience class for file paths.
void refresh_views()
Redraws the view list.
void select_odd()
Selects even elements (1st, 3rd…)
void set_document(const crn::SDocument &doc)
Sets the document to display.
void select_next()
If selection size is 0, the select the first element, if selection size is 1, then select the next vi...
OverlayConfig & get_selection_config()
Gets the mouse selection configuration.
void select_first()
If selection size is <= 1, then select the first item, else move last_selected to the first selected ...
void pack_start(Gtk::Widget &child, Gtk::PackOptions options=Gtk::PACK_EXPAND_WIDGET, guint padding=0)
Left/top side insert a widget to a box.
void append_views(const std::vector< crn::Path > &filenames)
Appends new views at the end of the document.
sigc::signal< void, std::vector< size_t >, std::vector< size_t > > signal_moved()
Signals when a widget was moved. Connect to void on_moved(moved_to, moved_from).
bool has_selection() const
Is there a mouse selection?
void select_last()
If selection size is <= 1, then select the last view, else move last_selected to the last selected el...
void clear()
Erase all elements.
void invert_selection()
Inverts the view selection.
void set_show_subblock_labels(bool s)
Shows or hides subblocks labels on the image.
std::vector< Gtk::Widget * > get_selection() const
Returns the list of selected widgets.
void add_overlay_item(const crn::String &overlay_id, const crn::String &item_id, const crn::Rect &r, const crn::StringUTF8 &label="")
Adds a rectangle to an overlay.
sigc::signal< void, Gtk::Widget *, const std::vector< Gtk::Widget * > > signal_selection_changed()
Signal when the selection has changed. Connect to void on_selection_changed(Gtk::Widget last_selected...
void select_last()
If selection size is <= 1, then select the last item, else move last_selected to the last selected el...
static const crn::String & selection_overlay()
Returns the name of the mouse selection overlay.
void reload_image(const crn::String &view_id)
Refreshes the thumbnail of a view and the Image if needed.
void set_show_thumbnails(bool s)
Shall the views show a thumbnail.
void run(sigc::slot< void > func)
Executes a processing.
static void show_message(const Glib::ustring &message, Gtk::MessageType mtype)
Displays a message.
MouseMode
State of the mouse activity.
void set_pixbuf(Glib::RefPtr< Gdk::Pixbuf > pb)
Sets the new image to display.
Configuration widget for crn::PDFAttributes.
void disable_action_group(const Glib::RefPtr< Gtk::ActionGroup > &grp)
void select_previous()
If selection size is 0, the select the first element, if selection size is 1, then select the previou...
Document(bool show_views=true, bool show_tree=true)
Constructor.
void deselect_all()
Selects all views.
A character string class.
void select_all()
Selects all elements.
sigc::signal< void, crn::String, crn::String, MouseMode > signal_overlay_changed()
Returns the signal associated to changes in selections. Binds to void on_overlay_changed(crn::String ...
void set_selected_view(const crn::String &view_id)
Sets the one selected view.
Gdk::Color ColorFromCRNPixel(const crn::pixel::RGB8 &p)
Creates a Gdk::Color from a crn::Pixel.
void deselect_all()
Deselects all elements.
void set_selection_colors(const crn::pixel::RGB8 &col1, const crn::pixel::RGB8 &col2)
Sets the colors of the user selection on the image.
bool IsNotEmpty() const noexcept
Checks if the string is not empty.
const crn::PDF::Attributes & get_attributes() const
Gets attributes.
size_t add_progress_bar(const crn::String &name, size_t maxcount=100)
Adds a progress bar to the window.
void set_homogeneous(bool homogeneous=true)
Sets the Gtk::Box:homogeneous property of box, controlling whether or not all children of box are giv...
void select_previous()
If selection size is 0, the select the first element, if selection size is 1, then select the previou...