From 19ca801d0d7ac5f1b8e8cb3ef0b872c2cd80e01d Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Wed, 30 Mar 2016 02:08:48 +0200 Subject: Fix for bug #1395435 (Inkscape crashes on load CDR select sheet) and bug #1441437 (crashes when load multi page visio and select page 2 or more) Also clean up code to create dialog a bit and make dialog resizable. Fixed bugs: - https://launchpad.net/bugs/1395435 - https://launchpad.net/bugs/1441437 (bzr r14751) --- src/extension/internal/cdr-input.cpp | 171 +++++++++++++++++------------------ 1 file changed, 82 insertions(+), 89 deletions(-) (limited to 'src/extension/internal/cdr-input.cpp') diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index f4789a08f..a26af2078 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -41,28 +41,18 @@ #endif #include -#include -#include -#include -#include +#include #include "extension/system.h" #include "extension/input.h" -#include "document.h" +#include "document.h" #include "document-private.h" -#include "document-undo.h" #include "inkscape.h" #include "ui/dialog-events.h" -#include -#include "ui/widget/spinbutton.h" -#include "ui/widget/frame.h" #include -#include - -#include "svg-view.h" #include "svg-view-widget.h" #include "util/units.h" @@ -82,108 +72,99 @@ public: void getImportSettings(Inkscape::XML::Node *prefs); private: - void _setPreviewPage(unsigned page); + void _setPreviewPage(); // Signal handlers -#if !WITH_GTKMM_3_0 - bool _onExposePreview(GdkEventExpose *event); -#endif - void _onPageNumberChanged(); + void _onSpinButtonPress(GdkEventButton* button_event); + void _onSpinButtonRelease(GdkEventButton* button_event); + class Gtk::VBox * vbox1; + class Gtk::Widget * _previewArea; class Gtk::Button * cancelbutton; class Gtk::Button * okbutton; class Gtk::Label * _labelSelect; - class Inkscape::UI::Widget::SpinButton * _pageNumberSpin; class Gtk::Label * _labelTotalPages; - class Gtk::VBox * vbox1; - class Gtk::VBox * vbox2; - class Gtk::Widget * _previewArea; + class Gtk::SpinButton * _pageNumberSpin; - const std::vector &_vec; // Document to be imported - unsigned _current_page; // Current selected page - int _preview_width, _preview_height; // Size of the preview area + const std::vector &_vec; // Document to be imported + unsigned _current_page; // Current selected page + bool _spinning; // whether SpinButton is pressed (i.e. we're "spinning") }; CdrImportDialog::CdrImportDialog(const std::vector &vec) - : _vec(vec), _current_page(1) + : _vec(vec), _current_page(1), _spinning(false) { int num_pages = _vec.size(); if ( num_pages <= 1 ) return; - cancelbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))); - okbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))); - _labelSelect = Gtk::manage(new class Gtk::Label(_("Select page:"))); - // Page number + // Dialog settings + this->set_title(_("Page Selector")); + this->set_modal(true); + sp_transientize(GTK_WIDGET(this->gobj())); //Make transient + this->property_window_position().set_value(Gtk::WIN_POS_NONE); + this->set_resizable(true); + this->property_destroy_with_parent().set_value(false); + + // Preview area + _previewArea = Gtk::manage(new class Gtk::VBox()); + vbox1 = Gtk::manage(new class Gtk::VBox()); + vbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 0); #if WITH_GTKMM_3_0 - Glib::RefPtr _pageNumberSpin_adj = Gtk::Adjustment::create(1, 1, _vec.size(), 1, 10, 0); - _pageNumberSpin = Gtk::manage(new Inkscape::UI::Widget::SpinButton(_pageNumberSpin_adj, 1, 1)); + this->get_content_area()->pack_start(*vbox1); #else - Gtk::Adjustment *_pageNumberSpin_adj = Gtk::manage( - new class Gtk::Adjustment(1, 1, _vec.size(), 1, 10, 0)); - _pageNumberSpin = Gtk::manage(new class Inkscape::UI::Widget::SpinButton(*_pageNumberSpin_adj, 1, 1)); + this->get_vbox()->pack_start(*vbox1); #endif - _labelTotalPages = Gtk::manage(new class Gtk::Label()); - gchar *label_text = g_strdup_printf(_("out of %i"), num_pages); - _labelTotalPages->set_label(label_text); - g_free(label_text); - vbox1 = Gtk::manage(new class Gtk::VBox(false, 4)); - SPDocument *doc = SPDocument::createNewDocFromMem(_vec[0].cstr(), strlen(_vec[0].cstr()), 0); - _previewArea = Glib::wrap(sp_svg_view_widget_new(doc)); - - vbox2 = Gtk::manage(new class Gtk::VBox(false, 4)); - cancelbutton->set_can_focus(); - cancelbutton->set_can_default(); - cancelbutton->set_relief(Gtk::RELIEF_NORMAL); - okbutton->set_can_focus(); - okbutton->set_can_default(); - okbutton->set_relief(Gtk::RELIEF_NORMAL); - this->get_action_area()->property_layout_style().set_value(Gtk::BUTTONBOX_END); + // CONTROLS + + // Buttons + cancelbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))); + okbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))); + + // Labels + _labelSelect = Gtk::manage(new class Gtk::Label(_("Select page:"))); + _labelTotalPages = Gtk::manage(new class Gtk::Label()); _labelSelect->set_line_wrap(false); _labelSelect->set_use_markup(false); _labelSelect->set_selectable(false); - _pageNumberSpin->set_can_focus(); - _pageNumberSpin->set_update_policy(Gtk::UPDATE_ALWAYS); - _pageNumberSpin->set_numeric(true); - _pageNumberSpin->set_digits(0); - _pageNumberSpin->set_wrap(false); _labelTotalPages->set_line_wrap(false); _labelTotalPages->set_use_markup(false); _labelTotalPages->set_selectable(false); - vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); + gchar *label_text = g_strdup_printf(_("out of %i"), num_pages); + _labelTotalPages->set_label(label_text); + g_free(label_text); + + // Adjustment + spinner #if WITH_GTKMM_3_0 - this->get_content_area()->set_homogeneous(false); - this->get_content_area()->set_spacing(0); - this->get_content_area()->pack_start(*vbox2); + Glib::RefPtr _pageNumberSpin_adj = Gtk::Adjustment::create(1, 1, _vec.size(), 1, 10, 0); + _pageNumberSpin = Gtk::manage(new Gtk::SpinButton(_pageNumberSpin_adj, 1, 0)); #else - this->get_vbox()->set_homogeneous(false); - this->get_vbox()->set_spacing(0); - this->get_vbox()->pack_start(*vbox2); + Gtk::Adjustment *_pageNumberSpin_adj = Gtk::manage(new class Gtk::Adjustment(1, 1, _vec.size(), 1, 10, 0)); + _pageNumberSpin = Gtk::manage(new Gtk::SpinButton(*_pageNumberSpin_adj, 1, 0)); #endif - this->set_title(_("Page Selector")); - this->set_modal(true); - sp_transientize(GTK_WIDGET(this->gobj())); //Make transient - this->property_window_position().set_value(Gtk::WIN_POS_NONE); - this->set_resizable(true); - this->property_destroy_with_parent().set_value(false); + _pageNumberSpin->set_can_focus(); + _pageNumberSpin->set_update_policy(Gtk::UPDATE_ALWAYS); + _pageNumberSpin->set_numeric(true); + _pageNumberSpin->set_wrap(false); + + this->get_action_area()->property_layout_style().set_value(Gtk::BUTTONBOX_END); this->get_action_area()->add(*_labelSelect); - this->add_action_widget(*_pageNumberSpin, -7); + this->add_action_widget(*_pageNumberSpin, Gtk::RESPONSE_ACCEPT); this->get_action_area()->add(*_labelTotalPages); - this->add_action_widget(*cancelbutton, -6); - this->add_action_widget(*okbutton, -5); - cancelbutton->show(); - okbutton->show(); - _labelSelect->show(); - _pageNumberSpin->show(); - _labelTotalPages->show(); - vbox1->show(); - _previewArea->show(); - vbox2->show(); + this->add_action_widget(*cancelbutton, Gtk::RESPONSE_CANCEL); + this->add_action_widget(*okbutton, Gtk::RESPONSE_OK); + + // Show all widgets in dialog + this->show_all(); // Connect signals - _pageNumberSpin_adj->signal_value_changed().connect(sigc::mem_fun(*this, &CdrImportDialog::_onPageNumberChanged)); + _pageNumberSpin->signal_value_changed().connect(sigc::mem_fun(*this, &CdrImportDialog::_onPageNumberChanged)); + _pageNumberSpin->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &CdrImportDialog::_onSpinButtonPress)); + _pageNumberSpin->signal_button_release_event().connect_notify(sigc::mem_fun(*this, &CdrImportDialog::_onSpinButtonRelease)); + + _setPreviewPage(); } CdrImportDialog::~CdrImportDialog() {} @@ -193,7 +174,7 @@ bool CdrImportDialog::showDialog() show(); gint b = run(); hide(); - if ( b == Gtk::RESPONSE_OK ) { + if (b == Gtk::RESPONSE_OK || b == Gtk::RESPONSE_ACCEPT) { return TRUE; } else { return FALSE; @@ -209,22 +190,34 @@ void CdrImportDialog::_onPageNumberChanged() { unsigned page = static_cast(_pageNumberSpin->get_value_as_int()); _current_page = CLAMP(page, 1U, _vec.size()); - _setPreviewPage(_current_page); + _setPreviewPage(); +} + +void CdrImportDialog::_onSpinButtonPress(GdkEventButton* /*button_event*/) +{ + _spinning = true; +} + +void CdrImportDialog::_onSpinButtonRelease(GdkEventButton* /*button_event*/) +{ + _spinning = false; + _setPreviewPage(); } /** * \brief Renders the given page's thumbnail */ -void CdrImportDialog::_setPreviewPage(unsigned page) +void CdrImportDialog::_setPreviewPage() { - SPDocument *doc = SPDocument::createNewDocFromMem(_vec[page-1].cstr(), strlen(_vec[page-1].cstr()), 0); + if (_spinning) { + return; + } + + SPDocument *doc = SPDocument::createNewDocFromMem(_vec[_current_page-1].cstr(), strlen(_vec[_current_page-1].cstr()), 0); Gtk::Widget * tmpPreviewArea = Glib::wrap(sp_svg_view_widget_new(doc)); std::swap(_previewArea, tmpPreviewArea); - if (tmpPreviewArea) { - _previewArea->set_size_request( tmpPreviewArea->get_width(), tmpPreviewArea->get_height() ); - delete tmpPreviewArea; - } - vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); + delete tmpPreviewArea; + vbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 0); _previewArea->show_now(); } -- cgit v1.2.3