12#include <cairomm/surface.h>
13#include <giomm/liststore.h>
14#include <glibmm/markup.h>
15#include <glibmm/refptr.h>
16#include <gtkmm/expression.h>
17#include <gtkmm/gridview.h>
19#include <glib/gi18n.h>
20#include <gdkmm/pixbuf.h>
21#include <gtkmm/builder.h>
22#include <gtkmm/iconview.h>
23#include <gtkmm/liststore.h>
24#include <gtkmm/numericsorter.h>
25#include <gtkmm/scrolledwindow.h>
26#include <gtkmm/treemodel.h>
27#include <gtkmm/sortlistmodel.h>
28#include <gtkmm/singleselection.h>
30#include <glibmm/miscutils.h>
31#include <gtkmm/filterlistmodel.h>
48struct TemplateList::TemplateItem :
public Glib::Object {
51 Glib::ustring tooltip;
52 Glib::RefPtr<Gdk::Texture> icon;
55 Glib::ustring category;
57 static Glib::RefPtr<TemplateItem>
create(
const Glib::ustring& name,
const Glib::ustring& label,
const Glib::ustring& tooltip,
58 Glib::RefPtr<Gdk::Texture> icon, Glib::ustring key,
int priority,
const Glib::ustring& category) {
60 auto item = Glib::make_refptr_for_instance<TemplateItem>(
new TemplateItem());
63 item->tooltip = tooltip;
66 item->priority = priority;
67 item->category = category;
71 TemplateItem() =
default;
90 set_vhomogeneous(
false);
92 property_visible_child_name().signal_changed().connect([
this]() {
96 std::map<std::string, Glib::RefPtr<Gio::ListStore<TemplateItem>>> stores;
101 Glib::RefPtr<Gio::ListStore<TemplateItem>> all;
102 if (add_page ==
All) {
107 for (
auto tmod : extensions) {
108 for (
auto preset : tmod->get_presets(
mode)) {
109 auto const &cat = preset->get_category();
110 if (add_page ==
Custom && cat !=
"Custom")
continue;
112 if (
auto it = stores.lower_bound(cat);
113 it == stores.end() || it->first != cat)
118 it->second->remove_all();
120 g_error(
"Error building templates %s\n", error.what());
126 auto const filepath = Glib::build_filename(
"icons",
"custom.svg");
129 auto templ = TemplateItem::create(
130 Glib::Markup::escape_text(_(
"<new template>")),
131 "",
"", icon,
"-new-template-", -1, cat
133 stores[cat]->append(templ);
137 auto&
name = preset->get_name();
138 auto& desc = preset->get_description();
139 auto&
label = preset->get_label();
140 auto tooltip = _(desc.empty() ?
name.c_str() : desc.c_str());
141 auto trans_label =
label.empty() ?
"" : _(
label.c_str());
144 auto templ = TemplateItem::create(
145 Glib::Markup::escape_text(
name),
146 Glib::Markup::escape_text(trans_label),
147 Glib::Markup::escape_text(tooltip),
148 icon, preset->get_key(), group + preset->get_sort_priority(),
151 stores[cat]->append(templ);
160 if (allow_unselect) {
172 static std::map<std::string, Cairo::RefPtr<Cairo::ImageSurface>>
cache;
176 if (
cache.contains(path)) {
195 auto& container = get_widget<Gtk::ScrolledWindow>(
builder,
"container");
196 auto& icons = get_widget<Gtk::GridView> (
builder,
"iconview");
199 auto sorter = Gtk::NumericSorter<int>::create(Gtk::ClosureExpression<int>::create([
this](
auto&
item){
200 auto ptr = std::dynamic_pointer_cast<TemplateItem>(
item);
201 return ptr ? ptr->priority : 0;
203 auto sorted_model = Gtk::SortListModel::create(
store, sorter);
205 _filter = Gtk::BoolFilter::create({});
207 auto filtered_model = Gtk::FilterListModel::create(sorted_model,
_filter);
208 auto selection_model = Gtk::SingleSelection::create(filtered_model);
209 if (allow_unselect) {
210 selection_model->set_can_unselect();
211 selection_model->set_autoselect(
false);
214 auto tmpl = std::dynamic_pointer_cast<TemplateItem>(ptr);
215 if (!tmpl)
return {};
217 auto label = tmpl->label.empty() ? tmpl->name :
218 tmpl->name +
"<small><span line_height='0.5'>\n\n</span><span alpha='60%'>" + tmpl->label +
"</span></small>";
219 return { .label_markup =
label, .image = tmpl->icon, .tooltip = tmpl->tooltip };
221 icons.set_max_columns(30);
222 icons.set_tab_behavior(Gtk::ListTabBehavior::ITEM);
223 icons.set_factory(factory->get_factory());
224 icons.set_model(selection_model);
227 add(container,
label, g_dpgettext2(
nullptr,
"TemplateCategory",
label.c_str()));
230 selection_model->signal_selection_changed().connect([
this](
auto pos,
auto count){
233 icons.signal_activate().connect([
this](
auto pos){
237 _factory.emplace_back(std::move(factory));
251 return item->key ==
"-new-template-";
257 if (
auto iconview =
get_iconview(current_page ? current_page : get_visible_child())) {
258 auto sel = std::dynamic_pointer_cast<Gtk::SingleSelection>(iconview->get_model());
259 auto ptr = sel->get_selected_item();
260 if (
auto item = std::dynamic_pointer_cast<TemplateList::TemplateItem>(ptr)) {
285 if (
auto doc = preset->new_from_template()) {
287 return app->document_add(std::move(doc));
294 return app->document_new();
299 set_visible_child(
name);
305 auto ptr = std::dynamic_pointer_cast<TemplateItem>(
item);
306 if (!ptr)
return false;
308 const auto& templ = *ptr;
310 if (search.empty())
return true;
313 return templ.label.lowercase().find(search) != Glib::ustring::npos ||
314 templ.name.lowercase().find(search) != Glib::ustring::npos;
325 if (
auto iconview =
get_iconview(get_visible_child())) {
326 iconview->grab_focus();
333 search = search.lowercase();
334 auto expression = Gtk::ClosureExpression<bool>::create([
this, search](
auto&
item){
return is_item_visible(
item, search); });
336 _filter->set_expression(expression);
345 for (
auto const widget :
UI::get_children(current_page ? *current_page : *
this)) {
347 auto sel = std::dynamic_pointer_cast<Gtk::SingleSelection>(iconview->get_model());
358 if (!widget)
return nullptr;
366 return dynamic_cast<Gtk::GridView *
>(widget);
static InkscapeApplication * instance()
Singleton instance.
TemplateList & get_template_list(TemplateList &ou_list)
Create a list of all the Template extensions.
std::list< Template * > TemplateList
static std::shared_ptr< TemplatePreset > get_any_preset(const std::string &key)
Return the template preset based on the key from any template class (static method).
static std::unique_ptr< IconViewItemFactory > create(std::function< ItemData(Glib::RefPtr< Glib::ObjectBase > &)> get_item)
Cairo::RefPtr< Cairo::ImageSurface > render_surface(double scale)
Typed SVG document implementation.
char const * label() const
Gets the author-visible label property for the object or a default if no label is defined.
DB db
This is the actual database object.
std::string get_filename(Type type, char const *filename, bool localized, bool silent)
std::vector< Gtk::Widget * > get_children(Gtk::Widget &widget)
Get a vector of the widgetʼs children, from get_first_child() through each get_next_sibling().
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
Inkscape::IO::Resource - simple resource API.
Glib::RefPtr< Gtk::Builder > builder
Glib::RefPtr< Gdk::Texture > to_texture(Cairo::RefPtr< Cairo::Surface > const &surface)
Convert an image surface in ARGB32 format to a texture.