=== modified file 'src/document.cpp' --- src/document.cpp 2012-07-28 12:15:34 +0000 +++ src/document.cpp 2012-08-01 08:13:30 +0000 @@ -221,6 +221,9 @@ SPDefs *SPDocument::getDefs() { + if (!root) { + return NULL; + } return root->defs; } === modified file 'src/helper/stock-items.cpp' --- src/helper/stock-items.cpp 2012-02-29 01:16:51 +0000 +++ src/helper/stock-items.cpp 2012-08-01 08:03:39 +0000 @@ -198,7 +198,9 @@ SPDesktop *desktop = inkscape_active_desktop(); SPDocument *doc = sp_desktop_document(desktop); SPDefs *defs = doc->getDefs(); - + if (!defs) { + return NULL; + } SPObject *object = NULL; if (!strcmp(base, "marker")) { for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) === modified file 'src/widgets/stroke-marker-selector.cpp' --- src/widgets/stroke-marker-selector.cpp 2012-05-18 01:15:12 +0000 +++ src/widgets/stroke-marker-selector.cpp 2012-08-01 08:17:19 +0000 @@ -46,8 +46,7 @@ MarkerComboBox::MarkerComboBox(gchar const *id) : Gtk::ComboBox(), combo_id(id), - updating(false), - is_history(false) + updating(false) { marker_store = Gtk::ListStore::create(marker_columns); @@ -66,6 +65,8 @@ desktop = inkscape_active_desktop(); doc = sp_desktop_document(desktop); + modified_connection = doc->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&MarkerComboBox::handleDefsModified), this))) ); + init_combo(); show(); @@ -74,6 +75,24 @@ MarkerComboBox::~MarkerComboBox() { delete combo_id; delete sandbox; + + if (doc) { + modified_connection.disconnect(); + } +} + +void +MarkerComboBox::handleDefsModified(MarkerComboBox *self) +{ + self->refreshHistory(); +} + +void +MarkerComboBox::refreshHistory() +{ + const char *active = get_active()->get_value(marker_columns.marker); + sp_marker_list_from_doc(doc, true); + set_selected(active); } /** @@ -82,12 +101,22 @@ void MarkerComboBox::init_combo() { - updating = false; + if (updating) + return; + + const gchar *active = NULL; + if (get_active()) { + active = get_active()->get_value(marker_columns.marker); + } if (!doc) { Gtk::TreeModel::Row row = *(marker_store->append()); row[marker_columns.label] = _("No document selected"); + row[marker_columns.marker] = g_strdup("None"); row[marker_columns.image] = NULL; + row[marker_columns.stock] = false; + row[marker_columns.history] = false; + row[marker_columns.separator] = false; set_sensitive(false); set_current(NULL); return; @@ -95,11 +124,17 @@ static SPDocument *markers_doc = NULL; - // add "None" - Gtk::TreeModel::Row row = *(marker_store->append()); - row[marker_columns.label] = _("None"); - row[marker_columns.marker] = g_strdup("none"); - row[marker_columns.image] = NULL; + // add separator + Gtk::TreeModel::Row row_sep = *(marker_store->append()); + row_sep[marker_columns.label] = "Separator"; + row_sep[marker_columns.marker] = g_strdup("None"); + row_sep[marker_columns.image] = NULL; + row_sep[marker_columns.stock] = false; + row_sep[marker_columns.history] = false; + row_sep[marker_columns.separator] = true; + + // load markers from the current doc + sp_marker_list_from_doc(doc, true); // find and load markers.svg if (markers_doc == NULL) { @@ -110,27 +145,17 @@ g_free(markers_source); } - // suck in from current doc - is_history = true; - sp_marker_list_from_doc(doc); - is_history = false; - - // add separator - Gtk::TreeModel::Row row_sep = *(marker_store->append()); - row_sep[marker_columns.label] = "Separator"; - row_sep[marker_columns.isseparator] = true; - row_sep[marker_columns.image] = NULL; - - // suck in from markers.svg + // load markers from markers.svg if (markers_doc) { doc->ensureUpToDate(); - sp_marker_list_from_doc(markers_doc); + sp_marker_list_from_doc(markers_doc, false); } set_sensitive(true); /* Set history */ - set_current(NULL); + set_selected(active); + } /** @@ -178,7 +203,7 @@ gchar const *marker = ""; if (strcmp(markid, "none")) { - bool stockid = get_active()->get_value(marker_columns.isstock); + bool stockid = get_active()->get_value(marker_columns.stock); gchar *markurn; if (stockid) @@ -208,7 +233,7 @@ } -void MarkerComboBox::set_selected(const gchar *name) { +void MarkerComboBox::set_selected(const gchar *name, gboolean retry/*=true*/) { if (!name) { set_active(0); @@ -221,42 +246,23 @@ if (row[marker_columns.marker] && !strcmp(row[marker_columns.marker], name)) { set_active(iter); - if (strcmp(name, "none")) - set_history(row); return; } } -} - -void MarkerComboBox::set_history(Gtk::TreeModel::Row match_row) { - - if (!match_row) { - return; - } - - for(Gtk::TreeIter iter = marker_store->children().begin(); - iter != marker_store->children().end(); ++iter) { - Gtk::TreeModel::Row row = (*iter); - if (row[marker_columns.history] && - !strcmp(row[marker_columns.marker], match_row[marker_columns.marker])) { - return; - } - } - - // Add a new row to the history - Gtk::TreeModel::Row row = *(marker_store->insert_after(marker_store->children().begin())); - row[marker_columns.marker] = g_strdup(match_row.get_value(marker_columns.marker)); - row[marker_columns.label] = match_row.get_value(marker_columns.label); - row[marker_columns.isstock] = match_row.get_value(marker_columns.isstock); - row[marker_columns.image] = match_row.get_value(marker_columns.image); - row[marker_columns.history] = true; -} + + // Didn't find it in the list, try refreshing from the doc + if (retry) { + sp_marker_list_from_doc(doc, true); + set_selected(name, false); + } +} + /** * Pick up all markers from source, except those that are in * current_doc (if non-NULL), and add items to the combo. */ -void MarkerComboBox::sp_marker_list_from_doc(SPDocument *source) +void MarkerComboBox::sp_marker_list_from_doc(SPDocument *source, gboolean history) { GSList *ml = get_marker_list(source); GSList *clean_ml = NULL; @@ -268,10 +274,14 @@ // Add to the list of markers we really do wish to show clean_ml = g_slist_prepend (clean_ml, ml->data); } - add_markers(clean_ml, source); + + remove_markers(history); // Seem to need to remove 2x + remove_markers(history); + add_markers(clean_ml, source, history); g_slist_free (ml); g_slist_free (clean_ml); + } /** @@ -285,6 +295,10 @@ GSList *ml = NULL; SPDefs *defs = source->getDefs(); + if (!defs) { + return NULL; + } + for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) { if (SP_IS_MARKER(child)) { @@ -295,31 +309,76 @@ } /** - * Adds previews of markers in marker_list to the combo - */ -void MarkerComboBox::add_markers (GSList *marker_list, SPDocument *source) + * Remove history or non-history markers from the combo + */ +void MarkerComboBox::remove_markers (gboolean history) +{ + // Having the model set causes assertions when erasing rows, temporarily disconnect + unset_model(); + for(Gtk::TreeIter iter = marker_store->children().begin(); + iter != marker_store->children().end(); ++iter) { + Gtk::TreeModel::Row row = (*iter); + if (row[marker_columns.history] == history && row[marker_columns.separator] == false) { + marker_store->erase(iter); + iter = marker_store->children().begin(); + } + } + + set_model(marker_store); +} + +/** + * Adds markers in marker_list to the combo + */ +void MarkerComboBox::add_markers (GSList *marker_list, SPDocument *source, gboolean history) { // Do this here, outside of loop, to speed up preview generation: Inkscape::Drawing drawing; unsigned const visionkey = SPItem::display_key_new(1); drawing.setRoot(sandbox->getRoot()->invoke_show(drawing, visionkey, SP_ITEM_SHOW_DISPLAY)); + // Find the separator, + Gtk::TreeIter sep_iter; + for(Gtk::TreeIter iter = marker_store->children().begin(); + iter != marker_store->children().end(); ++iter) { + Gtk::TreeModel::Row row = (*iter); + if (row[marker_columns.separator]) { + sep_iter = iter; + } + } + + if (history) { + // add "None" + Gtk::TreeModel::Row row = *(marker_store->prepend()); + row[marker_columns.label] = _("None"); + row[marker_columns.stock] = false; + row[marker_columns.marker] = g_strdup("None"); + row[marker_columns.image] = NULL; + row[marker_columns.history] = true; + row[marker_columns.separator] = false; + } for (; marker_list != NULL; marker_list = marker_list->next) { Inkscape::XML::Node *repr = reinterpret_cast(marker_list->data)->getRepr(); - bool isstock = (repr->attribute("inkscape:stockid")); gchar const *markid = repr->attribute("id"); // generate preview Gtk::Image *prv = create_marker_image (22, markid, source, drawing, visionkey); prv->show(); - Gtk::TreeModel::Row row = *(marker_store->append()); + // Add history before separator, others after + Gtk::TreeModel::Row row; + if (history) + row = *(marker_store->insert(sep_iter)); + else + row = *(marker_store->append()); + row[marker_columns.label] = gr_ellipsize_text(markid, 20); + row[marker_columns.stock] = !history; row[marker_columns.marker] = g_strdup(markid); - row[marker_columns.isstock] = isstock; row[marker_columns.image] = prv; - row[marker_columns.history] = is_history; + row[marker_columns.history] = history; + row[marker_columns.separator] = false; } @@ -414,7 +473,7 @@ gboolean MarkerComboBox::separator_cb (GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) { gboolean sep = FALSE; - gtk_tree_model_get(model, iter, 5, &sep, -1); + gtk_tree_model_get(model, iter, 4, &sep, -1); return sep; } === modified file 'src/widgets/stroke-marker-selector.h' --- src/widgets/stroke-marker-selector.h 2012-03-14 00:14:07 +0000 +++ src/widgets/stroke-marker-selector.h 2012-08-01 08:17:11 +0000 @@ -38,7 +38,7 @@ void set_current(SPObject *marker); void set_active_history(); - void set_selected(const gchar *name); + void set_selected(const gchar *name, gboolean retry=true); const gchar *get_active_marker_uri(); bool update() { return updating; }; gchar const *get_id() { return combo_id; }; @@ -48,7 +48,6 @@ Glib::RefPtr marker_store; gchar const *combo_id; bool updating; - bool is_history; SPDesktop *desktop; SPDocument *doc; SPDocument *sandbox; @@ -60,22 +59,23 @@ public: Gtk::TreeModelColumn label; Gtk::TreeModelColumn marker; // ustring doesnt work here on windows due to unicode - Gtk::TreeModelColumn isstock; + Gtk::TreeModelColumn stock; Gtk::TreeModelColumn image; - Gtk::TreeModelColumn history; - Gtk::TreeModelColumn isseparator; + Gtk::TreeModelColumn history; + Gtk::TreeModelColumn separator; MarkerColumns() { - add(label); add(marker); add(isstock); add(image); add(history); add(isseparator); + add(label); add(stock); add(marker); add(history); add(separator); add(image); } }; MarkerColumns marker_columns; void init_combo(); void set_history(Gtk::TreeModel::Row match_row); - void sp_marker_list_from_doc(SPDocument *source); + void sp_marker_list_from_doc(SPDocument *source, gboolean history); GSList *get_marker_list (SPDocument *source); - void add_markers (GSList *marker_list, SPDocument *source); + void add_markers (GSList *marker_list, SPDocument *source, gboolean history); + void remove_markers (gboolean history); SPDocument *ink_markers_preview_doc (); Gtk::Image * create_marker_image(unsigned psize, gchar const *mname, SPDocument *source, Inkscape::Drawing &drawing, unsigned /*visionkey*/); @@ -87,7 +87,10 @@ void prepareImageRenderer( Gtk::TreeModel::const_iterator const &row ); static gboolean separator_cb (GtkTreeModel *model, GtkTreeIter *iter, gpointer data); + static void handleDefsModified(MarkerComboBox *self); + void refreshHistory(); + sigc::connection modified_connection; }; #endif // SEEN_SP_MARKER_SELECTOR_NEW_H