diff options
| author | Ted Gould <ted@gould.cx> | 2012-11-25 19:41:24 +0000 |
|---|---|---|
| committer | Ted Gould <ted@gould.cx> | 2012-11-25 19:41:24 +0000 |
| commit | 18be0e5e3ab74823043e19dd6ea46c4b6b130e86 (patch) | |
| tree | a62925ec4473c1a21e1c99d1415f4cccab59b432 /src/ui | |
| parent | Getting all the filter headers (diff) | |
| parent | Fix for 1036059 : Keyboard shortcut editor (diff) | |
| download | inkscape-18be0e5e3ab74823043e19dd6ea46c4b6b130e86.tar.gz inkscape-18be0e5e3ab74823043e19dd6ea46c4b6b130e86.zip | |
Update to current trunk
(bzr r11804.1.8)
Diffstat (limited to 'src/ui')
42 files changed, 895 insertions, 186 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index ec7782302..8fd8eb4e3 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -60,6 +60,7 @@ set(ui_SRC dialog/print-colors-preview-dialog.cpp dialog/print.cpp dialog/scriptdialog.cpp + dialog/symbols.cpp dialog/xml-tree.cpp # dialog/session-player.cpp dialog/spellcheck.cpp @@ -174,6 +175,7 @@ set(ui_SRC dialog/spellcheck.h dialog/svg-fonts-dialog.h dialog/swatches.h + dialog/symbols.h dialog/text-edit.h dialog/tile.h dialog/tracedialog.h diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 4b0f773b5..cd1ce1471 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -1314,7 +1314,6 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem } } return master; - break; } case SMALLEST: @@ -1331,7 +1330,6 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem } } return master; - break; } default: diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h index 969703807..c9165a83e 100644 --- a/src/ui/dialog/align-and-distribute.h +++ b/src/ui/dialog/align-and-distribute.h @@ -213,7 +213,7 @@ private : SPDesktop *desktop = _dialog.getDesktop(); if (!desktop) return; - ActionAlign::do_action(desktop, _index); + do_action(desktop, _index); } static void do_action(SPDesktop *desktop, int index); diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 47ec03b30..f51470826 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1326,8 +1326,8 @@ void CloneTiler::on_picker_color_changed(guint rgba) void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) { - GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles"); - GtkWidget *status = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "status"); + GtkWidget *buttons = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles")); + GtkWidget *status = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "status")); if (selection->isEmpty()) { gtk_widget_set_sensitive (buttons, FALSE); @@ -2204,7 +2204,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) desktop->setWaitingCursor(); // set statusbar text - GtkWidget *status = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "status"); + GtkWidget *status = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "status")); gtk_label_set_markup (GTK_LABEL(status), _("<small>Creating tiled clones...</small>")); gtk_widget_queue_draw(GTK_WIDGET(status)); gdk_window_process_all_updates(); @@ -2870,10 +2870,10 @@ void CloneTiler::clonetiler_pick_switched(GtkToggleButton */*tb*/, gpointer data } -void CloneTiler::clonetiler_switch_to_create(GtkToggleButton */*tb*/, GtkWidget *dlg) +void CloneTiler::clonetiler_switch_to_create(GtkToggleButton * /*tb*/, GtkWidget *dlg) { - GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols"); - GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight"); + GtkWidget *rowscols = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "rowscols")); + GtkWidget *widthheight = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "widthheight")); if (rowscols) { gtk_widget_set_sensitive (rowscols, TRUE); @@ -2887,10 +2887,10 @@ void CloneTiler::clonetiler_switch_to_create(GtkToggleButton */*tb*/, GtkWidget } -void CloneTiler::clonetiler_switch_to_fill(GtkToggleButton */*tb*/, GtkWidget *dlg) +void CloneTiler::clonetiler_switch_to_fill(GtkToggleButton * /*tb*/, GtkWidget *dlg) { - GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols"); - GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight"); + GtkWidget *rowscols = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "rowscols")); + GtkWidget *widthheight = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "widthheight")); if (rowscols) { gtk_widget_set_sensitive (rowscols, FALSE); @@ -2929,7 +2929,7 @@ void CloneTiler::clonetiler_fill_height_changed(GtkAdjustment *adj, GtkWidget *u void CloneTiler::clonetiler_do_pick_toggled(GtkToggleButton *tb, GtkWidget *dlg) { - GtkWidget *vvb = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "dotrace"); + GtkWidget *vvb = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "dotrace")); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool(prefs_path + "dotrace", gtk_toggle_button_get_active (tb)); diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 969aac7ab..e370a0342 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -35,6 +35,7 @@ #include "xml/node.h" #include "xml/repr.h" #include "verbs.h" +#include "widgets/gradient-vector.h" #include "color.h" // for SP_RGBA32_U_COMPOSE @@ -143,7 +144,7 @@ static void dieDieDie( GObject *obj, gpointer user_data ) g_message("die die die %p %p", obj, user_data ); } -static bool getBlock( std::string& dst, guchar ch, std::string const str ) +static bool getBlock( std::string& dst, guchar ch, std::string const & str ) { bool good = false; std::string::size_type pos = str.find(ch); @@ -355,6 +356,23 @@ void ColorItem::setGradient(SPGradient *grad) _grad = grad; // TODO regen and push to listeners } + + setName( gr_prepare_label(_grad) ); +} + +void ColorItem::setName(const Glib::ustring name) +{ + //def.descr = name; + + for ( std::vector<Gtk::Widget*>::iterator it = _previews.begin(); it != _previews.end(); ++it ) { + Gtk::Widget* widget = *it; + if ( IS_EEK_PREVIEW(widget->gobj()) ) { + gtk_widget_set_tooltip_text(GTK_WIDGET(widget->gobj()), name.c_str()); + } + else if ( GTK_IS_LABEL(widget->gobj()) ) { + gtk_label_set_text(GTK_LABEL(widget->gobj()), name.c_str()); + } + } } void ColorItem::setPattern(cairo_pattern_t *pattern) @@ -366,6 +384,7 @@ void ColorItem::setPattern(cairo_pattern_t *pattern) cairo_pattern_destroy(_pattern); } _pattern = pattern; + _updatePreviews(); } diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h index f54586192..3a0b33193 100644 --- a/src/ui/dialog/color-item.h +++ b/src/ui/dialog/color-item.h @@ -60,6 +60,7 @@ public: void setGradient(SPGradient *grad); SPGradient * getGradient() const { return _grad; } void setPattern(cairo_pattern_t *pattern); + void setName(const Glib::ustring name); void setState( bool fill, bool stroke ); bool isFill() { return _isFill; } diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 7bd1b81c0..e681147aa 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -150,6 +150,7 @@ DocumentProperties::DocumentProperties() _notebook.append_page(_page_metadata1, _("Metadata")); _notebook.append_page(_page_metadata2, _("License")); + _wr.setUpdating (true); build_page(); build_guides(); build_gridspage(); @@ -159,6 +160,7 @@ DocumentProperties::DocumentProperties() #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) build_scripting(); build_metadata(); + _wr.setUpdating (false); _grids_button_new.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onNewGrid)); _grids_button_remove.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onRemoveGrid)); @@ -201,41 +203,36 @@ DocumentProperties::~DocumentProperties() * widget in columns 2-3; (non-0, 0) means label in columns 1-3; and * (non-0, non-0) means two widgets in columns 2 and 3. */ -inline void attach_all(Gtk::Table &table, Gtk::Widget *const arr[], unsigned const n, int start = 0) +inline void attach_all(Gtk::Table &table, Gtk::Widget *const arr[], unsigned const n, int start = 0, int docum_prop_flag = 0) { - for (unsigned i = 0, r = start; i < n; i += 2) - { - if (arr[i] && arr[i+1]) - { - table.attach(*arr[i], 1, 2, r, r+1, - Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); - table.attach(*arr[i+1], 2, 3, r, r+1, - Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); - } - else - { + for (unsigned i = 0, r = start; i < n; i += 2) { + if (arr[i] && arr[i+1]) { + table.attach(*arr[i], 1, 2, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); + table.attach(*arr[i+1], 2, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); + } else { if (arr[i+1]) { Gtk::AttachOptions yoptions = (Gtk::AttachOptions)0; if (dynamic_cast<Inkscape::UI::Widget::PageSizer*>(arr[i+1])) { // only the PageSizer in Document Properties|Page should be stretched vertically yoptions = Gtk::FILL|Gtk::EXPAND; } - table.attach(*arr[i+1], 1, 3, r, r+1, - Gtk::FILL|Gtk::EXPAND, yoptions, 0,0); - } - else if (arr[i]) - { + if (docum_prop_flag) { + if( i==(n-4) || i==(n-6) ) { + table.attach(*arr[i+1], 1, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, yoptions, 20,0); + } else { + table.attach(*arr[i+1], 1, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, yoptions, 0,0); + } + } else { + table.attach(*arr[i+1], 1, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, yoptions, 0,0); + } + } else if (arr[i]) { Gtk::Label& label = reinterpret_cast<Gtk::Label&>(*arr[i]); label.set_alignment (0.0); - table.attach (label, 0, 3, r, r+1, - Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); - } - else - { + table.attach (label, 0, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); + } else { Gtk::HBox *space = manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); - table.attach (*space, 0, 1, r, r+1, - (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0); + table.attach (*space, 0, 1, r, r+1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0); } } ++r; @@ -273,7 +270,12 @@ void DocumentProperties::build_page() _rcp_bord._label, &_rcp_bord, }; - attach_all(_page_page.table(), widget_array, G_N_ELEMENTS(widget_array)); + std::list<Gtk::Widget*> _slaveList; + _slaveList.push_back(&_rcb_bord); + _slaveList.push_back(&_rcb_shad); + _rcb_canb.setSlaveWidgets(_slaveList); + + attach_all(_page_page.table(), widget_array, G_N_ELEMENTS(widget_array),0,1); } void DocumentProperties::build_guides() @@ -926,7 +928,7 @@ void DocumentProperties::removeExternalScript(){ while ( current ) { if (current->data && SP_IS_OBJECT(current->data)) { SPObject* obj = SP_OBJECT(current->data); - SPScript* script = (SPScript*) obj; + SPScript* script = SP_SCRIPT(obj); if (name == script->xlinkhref){ //XML Tree being used directly here while it shouldn't be. @@ -1083,7 +1085,7 @@ void DocumentProperties::populate_script_lists(){ if (current) _scripts_observer.set(SP_OBJECT(current->data)->parent); while ( current ) { SPObject* obj = SP_OBJECT(current->data); - SPScript* script = (SPScript*) obj; + SPScript* script = SP_SCRIPT(obj); if (script->xlinkhref) { Gtk::TreeModel::Row row = *(_ExternalScriptsListStore->append()); diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 62dd93126..f267c5ae9 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -296,7 +296,7 @@ Export::Export (void) : batch_box.pack_start(batch_export, false, false); hide_export.set_sensitive(true); - hide_export.set_active (true); + hide_export.set_active (prefs->getBool("/dialogs/export/hideexceptselected/value", false)); hide_box.pack_start(hide_export, false, false); @@ -328,6 +328,7 @@ Export::Export (void) : browse_button.signal_clicked().connect(sigc::mem_fun(*this, &Export::onBrowse)); batch_export.signal_clicked().connect(sigc::mem_fun(*this, &Export::onBatchClicked)); export_button.signal_clicked().connect(sigc::mem_fun(*this, &Export::onExport)); + hide_export.signal_clicked().connect(sigc::mem_fun(*this, &Export::onHideExceptSelected)); desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &Export::setTargetDesktop) ); deskTrack.connect(GTK_WIDGET(gobj())); @@ -547,7 +548,7 @@ void Export::updateCheckbuttons () batch_export.set_sensitive(false); } - hide_export.set_sensitive (num > 0 && current_key == SELECTION_SELECTION); + //hide_export.set_sensitive (num > 0); } inline void Export::findDefaultSelection() @@ -786,8 +787,6 @@ void Export::onAreaToggled () } } - hide_export.set_sensitive (key == SELECTION_SELECTION); - return; } // end of sp_export_area_toggled() @@ -919,6 +918,11 @@ Glib::ustring Export::absolutize_path_from_document_location (SPDocument *doc, c return path; } +void Export::onHideExceptSelected () +{ + prefs->setBool("/dialogs/export/hideexceptselected/value", hide_export.get_active()); +} + /// Called when export button is clicked void Export::onExport () { @@ -1256,6 +1260,14 @@ void Export::onBrowse () WCHAR* title_string = (WCHAR*)g_utf8_to_utf16(_("Select a filename for exporting"), -1, NULL, NULL, NULL); WCHAR* extension_string = (WCHAR*)g_utf8_to_utf16("*.png", -1, NULL, NULL, NULL); // Copy the selected file name, converting from UTF-8 to UTF-16 + std::string dirname = Glib::path_get_dirname(filename.raw()); + if ( !Glib::file_test(dirname, Glib::FILE_TEST_EXISTS) || + Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) || + dirname.empty() ) + { + Glib::ustring tmp; + filename = create_filepath_from_id(tmp, tmp); + } WCHAR _filename[_MAX_PATH + 1]; memset(_filename, 0, sizeof(_filename)); gunichar2* utf16_path_string = g_utf8_to_utf16(filename.c_str(), -1, NULL, NULL, NULL); @@ -1434,7 +1446,7 @@ void Export::areaXChange (Gtk::Adjustment *adj) return; } - if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) { + if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) { return; } @@ -1481,7 +1493,7 @@ void Export::areaYChange (Gtk::Adjustment *adj) return; } - if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) { + if (sp_unit_selector_update_test (SP_UNIT_SELECTOR(unit_selector->gobj()))) { return; } @@ -1636,7 +1648,7 @@ void Export::onBitmapWidthChange () return; } - if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) { + if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) { return; } @@ -1670,7 +1682,7 @@ void Export::onBitmapHeightChange () return; } - if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) { + if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) { return; } @@ -1730,7 +1742,7 @@ void Export::onExportXdpiChange() return; } - if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) { + if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) { return; } @@ -1832,7 +1844,7 @@ void Export::setValuePx(Glib::RefPtr<Gtk::Adjustment>& adj, double val) void Export::setValuePx( Gtk::Adjustment *adj, double val) #endif { - const SPUnit *unit = sp_unit_selector_get_unit ((SPUnitSelector *)unit_selector->gobj() ); + const SPUnit *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unit_selector->gobj()) ); setValue(adj, sp_pixels_get_units (val, *unit)); @@ -1882,7 +1894,7 @@ float Export::getValuePx( Gtk::Adjustment *adj ) #endif { float value = getValue( adj); - const SPUnit *unit = sp_unit_selector_get_unit ((SPUnitSelector *)unit_selector->gobj()); + const SPUnit *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unit_selector->gobj())); return sp_units_get_pixels (value, *unit); } // end of sp_export_value_get_px() diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index e899009a7..c8376cdcb 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -178,6 +178,11 @@ private: #endif /** + * Hide except selected callback + */ + void onHideExceptSelected (); + + /** * Area width value changed callback */ void onAreaWidthChange (); diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp index 47ba6c748..b3af6fc00 100644 --- a/src/ui/dialog/filedialog.cpp +++ b/src/ui/dialog/filedialog.cpp @@ -152,6 +152,9 @@ Glib::ustring FileSaveDialog::getDocTitle() void FileSaveDialog::appendExtension(Glib::ustring& path, Inkscape::Extension::Output* outputExtension) { + if (!outputExtension) + return; + try { bool appendExtension = true; Glib::ustring utf8Name = Glib::filename_to_utf8( path ); diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h index 6a3436aea..63cee6bdc 100644 --- a/src/ui/dialog/filedialog.h +++ b/src/ui/dialog/filedialog.h @@ -208,6 +208,8 @@ public: virtual Glib::ustring getCurrentDirectory() = 0; + virtual void addFileType(Glib::ustring name, Glib::ustring pattern) = 0; + protected: /** diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 1663eb0b6..90d9855ec 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -141,13 +141,12 @@ bool SVGPreview::setDocument(SPDocument *doc) //This should remove it from the box, and free resources if (viewerGtk) - gtk_widget_destroy(viewerGtk); - - viewerGtk = sp_svg_view_widget_new(doc); - GtkWidget *vbox = (GtkWidget *)gobj(); - gtk_box_pack_start(GTK_BOX(vbox), viewerGtk, TRUE, TRUE, 0); - gtk_widget_show(viewerGtk); + Gtk::Container::remove(*viewerGtk); + viewerGtk = Glib::wrap(sp_svg_view_widget_new(doc)); + Gtk::VBox *vbox = Glib::wrap(gobj()); + vbox->pack_start(*viewerGtk, TRUE, TRUE, 0); + viewerGtk->show(); return true; } @@ -1048,7 +1047,9 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk( Gtk::Window &parentWindow, fileTypeCheckbox.set_active(prefs->getBool("/dialogs/save_as/append_extension", true)); } - createFileTypeMenu(); + if (_dialogType != CUSTOM_TYPE) + createFileTypeMenu(); + fileTypeComboBox.set_size_request(200,40); fileTypeComboBox.signal_changed().connect( sigc::mem_fun(*this, &FileSaveDialogImplGtk::fileTypeChangedCallback) ); @@ -1175,7 +1176,24 @@ void FileSaveDialogImplGtk::fileTypeChangedCallback() updateNameAndExtension(); } +void FileSaveDialogImplGtk::addFileType(Glib::ustring name, Glib::ustring pattern) +{ + //#Let user choose + FileType guessType; + guessType.name = name; + guessType.pattern = pattern; + guessType.extension = NULL; + #if WITH_GTKMM_2_24 + fileTypeComboBox.append(guessType.name); + #else + fileTypeComboBox.append_text(guessType.name); + #endif + fileTypes.push_back(guessType); + + fileTypeComboBox.set_active(0); + fileTypeChangedCallback(); //call at least once to set the filter +} void FileSaveDialogImplGtk::createFileTypeMenu() { diff --git a/src/ui/dialog/filedialogimpl-gtkmm.h b/src/ui/dialog/filedialogimpl-gtkmm.h index 2c22e7367..7501b5e14 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.h +++ b/src/ui/dialog/filedialogimpl-gtkmm.h @@ -121,7 +121,7 @@ private: /** * The sp_svg_view widget */ - GtkWidget *viewerGtk; + Gtk::Widget *viewerGtk; /** * are we currently showing the "no preview" image? @@ -291,6 +291,7 @@ public: virtual void setSelectionType( Inkscape::Extension::Extension * key ); Glib::ustring getCurrentDirectory(); + void addFileType(Glib::ustring name, Glib::ustring pattern); private: //void change_title(const Glib::ustring& title); diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 5891f25ac..6425d9fee 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -188,7 +188,8 @@ FileOpenDialogImplWin32::FileOpenDialogImplWin32(Gtk::Window &parent, _mutex = NULL; - createFilterMenu(); + if (dialogType != CUSTOM_TYPE) + createFilterMenu(); } @@ -1748,6 +1749,72 @@ void FileSaveDialogImplWin32::createFilterMenu() _filter_index = 1; // A value of 1 selects the 1st filter - NOT the 2nd } + +void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring pattern) +{ + list<Filter> filter_list; + + knownExtensions.clear(); + + int extension_index = 0; + int filter_length = 1; + + ustring all_exe_files_filter = pattern; + Filter all_exe_files; + + const gchar *all_exe_files_filter_name = name.data(); + + // Calculate the amount of memory required + int filter_count = 1; + + + // Filter Executable Files + all_exe_files.name = g_utf8_to_utf16(all_exe_files_filter_name, + -1, NULL, &all_exe_files.name_length, NULL); + all_exe_files.filter = g_utf8_to_utf16(all_exe_files_filter.data(), + -1, NULL, &all_exe_files.filter_length, NULL); + all_exe_files.mod = NULL; + filter_list.push_front(all_exe_files); + + knownExtensions.insert( Glib::ustring(all_exe_files_filter).casefold() ); + + _extension_map = new Inkscape::Extension::Extension*[filter_count]; + + _filter = new wchar_t[filter_length]; + wchar_t *filterptr = _filter; + + for(list<Filter>::iterator filter_iterator = filter_list.begin(); + filter_iterator != filter_list.end(); ++filter_iterator) + { + const Filter &filter = *filter_iterator; + + wcsncpy(filterptr, (wchar_t*)filter.name, filter.name_length); + filterptr += filter.name_length; + g_free(filter.name); + + *(filterptr++) = L'\0'; + *(filterptr++) = L'*'; + + if(filter.filter != NULL) + { + wcsncpy(filterptr, (wchar_t*)filter.filter, filter.filter_length); + filterptr += filter.filter_length; + g_free(filter.filter); + } + + *(filterptr++) = L'\0'; + + // Associate this input extension with the file type name + _extension_map[extension_index++] = filter.mod; + } + *(filterptr++) = L'\0'; + + _filter_count = extension_index; + _filter_index = 1; // Select the 1st filter in the list + + +} + void FileSaveDialogImplWin32::GetSaveFileName_thread() { OPENFILENAMEEXW ofn; @@ -1814,7 +1881,7 @@ FileSaveDialogImplWin32::show() if(Glib::Thread::create(sigc::mem_fun(*this, &FileSaveDialogImplWin32::GetSaveFileName_thread), true)) g_main_loop_run(_main_loop); - if(_result) + if(_result && _extension) appendExtension(myFilename, (Inkscape::Extension::Output*)_extension); } @@ -1827,6 +1894,7 @@ void FileSaveDialogImplWin32::setSelectionType( Inkscape::Extension::Extension * } + UINT_PTR CALLBACK FileSaveDialogImplWin32::GetSaveFileName_hookproc( HWND hdlg, UINT uiMsg, WPARAM, LPARAM lParam) { diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index d016b0a24..15953f9d8 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -343,6 +343,8 @@ public: virtual void setSelectionType( Inkscape::Extension::Extension *key ); + virtual void addFileType(Glib::ustring name, Glib::ustring pattern); + private: /// A handle to the title label and edit box HWND _title_label; diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index c7efd3bf2..5ba4e7e39 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -22,6 +22,7 @@ #include "filter-chemistry.h" #include "inkscape.h" #include "selection.h" +#include "preferences.h" #include "style.h" #include "svg/css-ostringstream.h" #include "ui/icon-names.h" @@ -59,6 +60,8 @@ FillAndStroke::FillAndStroke() _notebook.append_page(_page_stroke_paint, _createPageTabLabel(_("Stroke _paint"), INKSCAPE_ICON("object-stroke"))); _notebook.append_page(_page_stroke_style, _createPageTabLabel(_("Stroke st_yle"), INKSCAPE_ICON("object-stroke-style"))); + _notebook.signal_switch_page().connect(sigc::mem_fun(this, &FillAndStroke::_onSwitchPage)); + _layoutPageFill(); _layoutPageStrokePaint(); _layoutPageStrokeStyle(); @@ -105,6 +108,23 @@ void FillAndStroke::setTargetDesktop(SPDesktop *desktop) } } +#if WITH_GTKMM_3_0 +void FillAndStroke::_onSwitchPage(Gtk::Widget * /*page*/, guint pagenum) +#else +void FillAndStroke::_onSwitchPage(GtkNotebookPage * /*page*/, guint pagenum) +#endif +{ + _savePagePref(pagenum); +} + +void +FillAndStroke::_savePagePref(guint page_num) +{ + // remember the current page + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/dialogs/fillstroke/page", page_num); +} + void FillAndStroke::_layoutPageFill() { @@ -133,6 +153,8 @@ FillAndStroke::showPageFill() { present(); _notebook.set_current_page(0); + _savePagePref(0); + } void @@ -140,6 +162,7 @@ FillAndStroke::showPageStrokePaint() { present(); _notebook.set_current_page(1); + _savePagePref(1); } void @@ -147,6 +170,8 @@ FillAndStroke::showPageStrokeStyle() { present(); _notebook.set_current_page(2); + _savePagePref(2); + } Gtk::HBox& diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h index 596205c58..255cea89a 100644 --- a/src/ui/dialog/fill-and-stroke.h +++ b/src/ui/dialog/fill-and-stroke.h @@ -60,6 +60,12 @@ protected: void _layoutPageFill(); void _layoutPageStrokePaint(); void _layoutPageStrokeStyle(); + void _savePagePref(guint page_num); +#if WITH_GTKMM_3_0 + void _onSwitchPage(Gtk::Widget *page, guint pagenum); +#else + void _onSwitchPage(GtkNotebookPage *page, guint pagenum); +#endif private: FillAndStroke(FillAndStroke const &d); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index a755cfccd..b00dd042f 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -62,6 +62,7 @@ #include "io/sys.h" #include <iostream> +#include "selection-chemistry.h" #include <gtkmm/checkbutton.h> #include <gtkmm/colorbutton.h> @@ -1193,6 +1194,17 @@ void FilterEffectsDialog::FilterModifier::setTargetDesktop(SPDesktop *desktop) } } +// When the document changes, update connection to resources +void FilterEffectsDialog::FilterModifier::on_document_replaced(SPDesktop *desktop, SPDocument *document) +{ + if (_resource_changed) { + _resource_changed.disconnect(); + } + _resource_changed = document->connectResourcesChanged("filter",sigc::mem_fun(*this, &FilterModifier::update_filters)); + + update_filters(); +} + // When the selection changes, show the active filter(s) in the dialog void FilterEffectsDialog::FilterModifier::on_change_selection() { @@ -1316,7 +1328,7 @@ void FilterEffectsDialog::FilterModifier::update_filters() for(const GSList *l = filters; l; l = l->next) { Gtk::TreeModel::Row row = *_model->append(); - SPFilter* f = (SPFilter*)l->data; + SPFilter* f = SP_FILTER(l->data); row[_columns.filter] = f; const gchar* lbl = f->label(); const gchar* id = f->getId(); @@ -1387,6 +1399,29 @@ void FilterEffectsDialog::FilterModifier::remove_filter() if(filter) { SPDocument* doc = filter->document; + // Delete all references to this filter + GSList *all = get_all_items(NULL, _desktop->currentRoot(), _desktop, false, false, true, NULL); + for (GSList *i = all; i != NULL; i = i->next) { + if (!SP_IS_ITEM(i->data)) { + continue; + } + SPItem *item = SP_ITEM(i->data); + if (!item->style) { + continue; + } + + const SPIFilter *ifilter = &(item->style->filter); + if (ifilter && ifilter->href) { + const SPObject *obj = ifilter->href->getObject(); + if (obj && obj == (SPObject *)filter) { + ::remove_filter(item, false); + } + } + } + if (all) { + g_slist_free(all); + } + //XML Tree being used directly here while it shouldn't be. sp_repr_unparent(filter->getRepr()); @@ -1443,7 +1478,7 @@ void FilterEffectsDialog::CellRendererConnection::get_size_vfunc( if(height) { // Scale the height depending on the number of inputs, unless it's // the first primitive, in which case there are no connections - SPFilterPrimitive* prim = (SPFilterPrimitive*)_primitive.get_value(); + SPFilterPrimitive* prim = SP_FILTER_PRIMITIVE(_primitive.get_value()); (*height) = size * input_count(prim); } } @@ -1525,11 +1560,10 @@ void FilterEffectsDialog::PrimitiveList::update() { SPFilter* f = _dialog._filter_modifier.get_selected_filter(); const SPFilterPrimitive* active_prim = get_selected(); - bool active_found = false; - _model->clear(); if(f) { + bool active_found = false; _dialog._primitive_box.set_sensitive(true); _dialog.update_filter_general_settings_view(); for(SPObject *prim_obj = f->children; diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h index acdeecb71..1652a314f 100644 --- a/src/ui/dialog/filter-effects-dialog.h +++ b/src/ui/dialog/filter-effects-dialog.h @@ -77,12 +77,8 @@ private: }; void setTargetDesktop(SPDesktop *desktop); - - void on_document_replaced(SPDesktop*, SPDocument*) - { - update_filters(); - } + void on_document_replaced(SPDesktop *desktop, SPDocument *document); void on_change_selection(); void on_modified_selection( guint flags ); diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index d449bad67..24588946e 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -207,7 +207,7 @@ GSList * FontSubstitution::getFontReplacedItems(SPDocument* doc, Glib::ustring * // Check if any document styles are not in the actual layout std::map<SPItem *, Glib::ustring>::const_iterator mapIter; - for (mapIter = mapFontStyles.begin(); mapIter != mapFontStyles.end(); mapIter++) { + for (mapIter = mapFontStyles.begin(); mapIter != mapFontStyles.end(); ++mapIter) { SPItem *item = mapIter->first; Glib::ustring fonts = mapIter->second; @@ -241,7 +241,7 @@ GSList * FontSubstitution::getFontReplacedItems(SPDocument* doc, Glib::ustring * } std::set<Glib::ustring>::const_iterator setIter; - for (setIter = setErrors.begin(); setIter != setErrors.end(); setIter++) { + for (setIter = setErrors.begin(); setIter != setErrors.end(); ++setIter) { Glib::ustring err = (*setIter); out->append(err + "\n"); g_warning("%s", err.c_str()); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 2731b6174..03366a0c3 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -47,7 +47,11 @@ #include "display/canvas-grid.h" #include "path-prefix.h" #include "io/resource.h" +#include "io/sys.h" #include "inkscape.h" +#include "shortcuts.h" +#include "document.h" + #ifdef HAVE_ASPELL # include <aspell.h> @@ -137,6 +141,7 @@ InkscapePreferences::InkscapePreferences() initPageRendering(); initPageSpellcheck(); + signalPresent().connect(sigc::mem_fun(*this, &InkscapePreferences::_presentPages)); //calculate the size request for this dialog @@ -741,6 +746,8 @@ void InkscapePreferences::initPageUI() _grids_axonom.add_line( false, _("Major grid line every:"), _grids_axonom_empspacing, "", "", false); this->AddPage(_page_grids, _("Grids"), iter_ui, PREFS_PAGE_UI_GRIDS); + + initKeyboardShortcuts(iter_ui); } #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) @@ -1405,6 +1412,316 @@ void InkscapePreferences::initPageBitmaps() this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); } +void InkscapePreferences::initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui) +{ + std::vector<Glib::ustring> fileNames; + std::vector<Glib::ustring> fileLabels; + + sp_shortcut_get_file_names(&fileLabels, &fileNames); + + _kb_filelist.init( "/options/kbshortcuts/shortcutfile", &fileLabels[0], &fileNames[0], fileLabels.size(), fileNames[0]); + + Glib::ustring tooltip(_("Select a file of predefined shortcuts to use. Any customized shortcuts you create will be added seperately to ")); + tooltip += Glib::ustring(IO::Resource::get_path(IO::Resource::USER, IO::Resource::KEYS, "default.xml")); + + _page_keyshortcuts.add_line( false, _("Shortcut file:"), _kb_filelist, "", tooltip.c_str(), false); + + _kb_search.init("/options/kbshortcuts/value", true); + _page_keyshortcuts.add_line( false, _("Search:"), _kb_search, "", "", true); + + _kb_store = Gtk::TreeStore::create( _kb_columns ); + _kb_store->set_sort_column (_kb_columns.id, Gtk::SORT_ASCENDING ); + + _kb_filter = Gtk::TreeModelFilter::create(_kb_store); + _kb_filter->set_visible_func (sigc::mem_fun(*this, &InkscapePreferences::onKBSearchFilter)); + + _kb_shortcut_renderer.property_editable() = true; + + _kb_tree.set_model(_kb_filter); + _kb_tree.append_column(_("Name"), _kb_columns.name); + _kb_tree.append_column(_("Shortcut"), _kb_shortcut_renderer); + _kb_tree.append_column(_("Description"), _kb_columns.description); + _kb_tree.append_column(_("ID"), _kb_columns.id); + + _kb_tree.set_expander_column(*_kb_tree.get_column(0)); + + _kb_tree.get_column(0)->set_resizable(true); + _kb_tree.get_column(0)->set_clickable(true); + _kb_tree.get_column(0)->set_fixed_width (200); + + _kb_tree.get_column(1)->set_resizable(true); + _kb_tree.get_column(1)->set_clickable(true); + _kb_tree.get_column(1)->set_fixed_width (150); + //_kb_tree.get_column(1)->add_attribute(_kb_shortcut_renderer.property_text(), _kb_columns.shortcut); + _kb_tree.get_column(1)->set_cell_data_func(_kb_shortcut_renderer, sigc::ptr_fun(InkscapePreferences::onKBShortcutRenderer)); + + _kb_tree.get_column(2)->set_resizable(true); + _kb_tree.get_column(2)->set_clickable(true); + + _kb_tree.get_column(3)->set_resizable(true); + _kb_tree.get_column(3)->set_clickable(true); + + _kb_shortcut_renderer.signal_accel_edited().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBTreeEdited) ); + _kb_shortcut_renderer.signal_accel_cleared().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBTreeCleared) ); + + Gtk::ScrolledWindow* scroller = new Gtk::ScrolledWindow(); + scroller->add(_kb_tree); + + int row = 3; + _page_keyshortcuts.attach(*scroller, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::EXPAND | Gtk::FILL); + row++; + + Gtk::HButtonBox *box_buttons = manage (new Gtk::HButtonBox); + box_buttons->set_layout(Gtk::BUTTONBOX_END); + box_buttons->set_spacing(4); + _page_keyshortcuts.attach(*box_buttons, 0, 3, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK); + + UI::Widget::Button *kb_reset = manage(new UI::Widget::Button(_("Reset"), _("Remove all your customized keyboard shortcuts, and revert to the shortcuts in the shortcut file listed above"))); + box_buttons->pack_start(*kb_reset, true, true, 6); + box_buttons->set_child_secondary(*kb_reset); + + UI::Widget::Button *kb_import = manage(new UI::Widget::Button(_("Import ..."), _("Import custom keyboard shortcuts from a file"))); + box_buttons->pack_end(*kb_import, true, true, 6); + + UI::Widget::Button *kb_export = manage(new UI::Widget::Button(_("Export ..."), _("Export custom keyboard shortcuts to a file"))); + box_buttons->pack_end(*kb_export, true, true, 6); + + kb_reset->signal_clicked().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBReset) ); + kb_import->signal_clicked().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBImport) ); + kb_export->signal_clicked().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBExport) ); + _kb_search.signal_key_release_event().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBSearchKeyEvent) ); + _kb_filelist.signal_changed().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBList) ); + _page_keyshortcuts.signal_realize().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBRealize) ); + + this->AddPage(_page_keyshortcuts, _("Keyboard Shortcuts"), iter_ui, PREFS_PAGE_UI_KEYBOARD_SHORTCUTS); + + _kb_shortcuts_loaded = false; + Gtk::TreeStore::iterator iter_group = _kb_store->append(); + (*iter_group)[_kb_columns.name] = "Loading ..."; + (*iter_group)[_kb_columns.shortcut] = ""; + (*iter_group)[_kb_columns.id] = ""; + (*iter_group)[_kb_columns.description] = ""; + (*iter_group)[_kb_columns.shortcutid] = 0; + (*iter_group)[_kb_columns.user_set] = 0; + +} + +void InkscapePreferences::onKBList() +{ + sp_shortcut_init(); + onKBListKeyboardShortcuts(); +} + +void InkscapePreferences::onKBReset() +{ + sp_shortcuts_delete_all_from_file(); + sp_shortcut_init(); + onKBListKeyboardShortcuts(); +} + +void InkscapePreferences::onKBImport() +{ + if (sp_shortcut_file_import()) { + onKBListKeyboardShortcuts(); + } +} + +void InkscapePreferences::onKBExport() +{ + sp_shortcut_file_export(); +} + +bool InkscapePreferences::onKBSearchKeyEvent(GdkEventKey *event) +{ + _kb_filter->refilter(); + return FALSE; +} + +void InkscapePreferences::onKBTreeCleared(const Glib::ustring& path) +{ + Gtk::TreeModel::iterator iter = _kb_filter->get_iter(path); + Glib::ustring id = (*iter)[_kb_columns.id]; + unsigned int const current_shortcut_id = (*iter)[_kb_columns.shortcutid]; + + // Remove current shortcut from file + sp_shortcut_delete_from_file(id.c_str(), current_shortcut_id); + + sp_shortcut_init(); + onKBListKeyboardShortcuts(); + +} + +void InkscapePreferences::onKBTreeEdited (const Glib::ustring& path, guint accel_key, Gdk::ModifierType accel_mods, guint hardware_keycode) +{ + Gtk::TreeModel::iterator iter = _kb_filter->get_iter(path); + + Glib::ustring id = (*iter)[_kb_columns.id]; + Glib::ustring current_shortcut = (*iter)[_kb_columns.shortcut]; + unsigned int const current_shortcut_id = (*iter)[_kb_columns.shortcutid]; + + Inkscape::Verb *const verb = Inkscape::Verb::getbyid(id.c_str()); + if (!verb) { + return; + } + + unsigned int const new_shortcut_id = sp_gdkmodifier_to_shortcut(accel_key, accel_mods, hardware_keycode); + if (new_shortcut_id) { + + // Delete current shortcut if it existed + sp_shortcut_delete_from_file(id.c_str(), current_shortcut_id); + // Delete any references to the new shortcut + sp_shortcut_delete_from_file(id.c_str(), new_shortcut_id); + // Add the new shortcut + sp_shortcut_add_to_file(id.c_str(), new_shortcut_id); + + sp_shortcut_init(); + onKBListKeyboardShortcuts(); + } +} + +bool InkscapePreferences::onKBSearchFilter(const Gtk::TreeModel::const_iterator& iter) +{ + Glib::ustring search = _kb_search.get_text().lowercase(); + if (search.empty()) { + return TRUE; + } + + Glib::ustring name = (*iter)[_kb_columns.name]; + Glib::ustring desc = (*iter)[_kb_columns.description]; + Glib::ustring shortcut = (*iter)[_kb_columns.shortcut]; + Glib::ustring id = (*iter)[_kb_columns.id]; + + if (id.empty()) { + return TRUE; // Keep all group nodes visible + } + + return (name.lowercase().find(search) != name.npos + || shortcut.lowercase().find(search) != name.npos + || desc.lowercase().find(search) != name.npos + || id.lowercase().find(search) != name.npos); +} + +void InkscapePreferences::onKBRealize() +{ + if (!_kb_shortcuts_loaded /*&& _current_page == &_page_keyshortcuts*/) { + _kb_shortcuts_loaded = true; + onKBListKeyboardShortcuts(); + } +} + +InkscapePreferences::ModelColumns &InkscapePreferences::onKBGetCols() +{ + static InkscapePreferences::ModelColumns cols; + return cols; +} + +void InkscapePreferences::onKBShortcutRenderer(Gtk::CellRenderer *renderer, Gtk::TreeIter const &iter) { + + Glib::ustring shortcut = (*iter)[onKBGetCols().shortcut]; + unsigned int user_set = (*iter)[onKBGetCols().user_set]; + Gtk::CellRendererAccel *accel = dynamic_cast<Gtk::CellRendererAccel *>(renderer); + if (user_set) { + accel->property_markup() = Glib::ustring("<span foreground=\"blue\"> " + shortcut + " </span>").c_str(); + } else { + accel->property_markup() = Glib::ustring("<span> " + shortcut + " </span>").c_str(); + } +} + +void InkscapePreferences::onKBListKeyboardShortcuts() +{ + // Save the current selection + Gtk::TreeStore::iterator iter = _kb_tree.get_selection()->get_selected(); + Glib::ustring selected_id = ""; + if (iter) { + selected_id = (*iter)[_kb_columns.id]; + } + + _kb_store->clear(); + + std::vector<Verb *>verbs = Inkscape::Verb::getList(); + + for (unsigned int i = 0; i < verbs.size(); i++) { + + Inkscape::Verb* verb = verbs[i]; + if (!verb) { + continue; + } + if (!verb->get_name()){ + continue; + } + + Gtk::TreeStore::Path path; + if (_kb_store->iter_is_valid(_kb_store->get_iter("0"))) { + path = _kb_store->get_path(_kb_store->get_iter("0")); + } + + // Find this group in the tree + Glib::ustring group = verb->get_group() ? verb->get_group() : "Misc"; + Gtk::TreeStore::iterator iter_group; + bool found = false; + while (path) { + iter_group = _kb_store->get_iter(path); + if (!_kb_store->iter_is_valid(iter_group)) { + break; + } + Glib::ustring name = (*iter_group)[_kb_columns.name]; + if ((*iter_group)[_kb_columns.name] == group) { + found = true; + break; + } + path.next(); + } + + if (!found) { + // Add the group if not there + iter_group = _kb_store->append(); + (*iter_group)[_kb_columns.name] = group; + (*iter_group)[_kb_columns.shortcut] = ""; + (*iter_group)[_kb_columns.id] = ""; + (*iter_group)[_kb_columns.description] = ""; + (*iter_group)[_kb_columns.shortcutid] = 0; + (*iter_group)[_kb_columns.user_set] = 0; + } + + // Remove the key accelerators from the verb name + Glib::ustring name = verb->get_name(); + std::string::size_type k = 0; + while((k=name.find('_',k))!=name.npos) { + name.erase(k, 1); + } + + // Get the shortcut label + unsigned int shortcut_id = sp_shortcut_get_primary(verb); + Glib::ustring shortcut_label = ""; + if (shortcut_id != GDK_KEY_VoidSymbol) { + gchar* str = sp_shortcut_get_label(shortcut_id); + if (str) { + shortcut_label = str; + g_free(str); + str = 0; + } + } + // Add the verb to the group + Gtk::TreeStore::iterator row = _kb_store->append(iter_group->children()); + (*row)[_kb_columns.name] = name; + (*row)[_kb_columns.shortcut] = shortcut_label; + (*row)[_kb_columns.description] = verb->get_short_tip() ? verb->get_short_tip() : ""; + (*row)[_kb_columns.shortcutid] = shortcut_id; + (*row)[_kb_columns.id] = verb->get_id(); + (*row)[_kb_columns.user_set] = sp_shortcut_is_user_set(verb); + + if (selected_id == verb->get_id()) { + Gtk::TreeStore::Path sel_path = _kb_filter->convert_child_path_to_path(_kb_store->get_path(row)); + _kb_tree.expand_to_path(sel_path); + _kb_tree.get_selection()->select(sel_path); + } + } + + if (selected_id.empty()) { + _kb_tree.expand_to_path(_kb_store->get_path(_kb_store->get_iter("0:1"))); + } + +} void InkscapePreferences::initPageSpellcheck() { @@ -1609,7 +1926,7 @@ bool InkscapePreferences::PresentPage(const Gtk::TreeModel::iterator& iter) _page_list.expand_row(_path_tools, false); if (desired_page >= PREFS_PAGE_TOOLS_SHAPES && desired_page <= PREFS_PAGE_TOOLS_SHAPES_SPIRAL) _page_list.expand_row(_path_shapes, false); - if (desired_page >= PREFS_PAGE_UI && desired_page <= PREFS_PAGE_UI_GRIDS) + if (desired_page >= PREFS_PAGE_UI && desired_page <= PREFS_PAGE_UI_KEYBOARD_SHORTCUTS) _page_list.expand_row(_path_ui, false); if (desired_page >= PREFS_PAGE_BEHAVIOR && desired_page <= PREFS_PAGE_BEHAVIOR_MASKS) _page_list.expand_row(_path_behavior, false); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index d60035515..690016556 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -18,15 +18,19 @@ #include <iostream> #include <vector> #include "ui/widget/preferences-widget.h" +#include "ui/widget/button.h" +#include <stddef.h> #include <gtkmm/colorbutton.h> #include <gtkmm/comboboxtext.h> #include <gtkmm/treestore.h> #include <gtkmm/treeview.h> #include <gtkmm/frame.h> #include <gtkmm/notebook.h> -#include <stddef.h> #include <gtkmm/textview.h> #include <gtkmm/scrolledwindow.h> +#include <gtkmm/liststore.h> +#include <gtkmm/treemodel.h> +#include <gtkmm/treemodelfilter.h> #include "ui/widget/panel.h" @@ -60,6 +64,7 @@ enum { PREFS_PAGE_UI, PREFS_PAGE_UI_WINDOWS, PREFS_PAGE_UI_GRIDS, + PREFS_PAGE_UI_KEYBOARD_SHORTCUTS, PREFS_PAGE_BEHAVIOR, PREFS_PAGE_BEHAVIOR_SELECTING, PREFS_PAGE_BEHAVIOR_TRANSFORMS, @@ -79,6 +84,7 @@ enum { PREFS_PAGE_BITMAPS, PREFS_PAGE_RENDERING, PREFS_PAGE_SPELLCHECK + }; namespace Inkscape { @@ -166,6 +172,8 @@ protected: UI::Widget::DialogPage _page_bitmaps; UI::Widget::DialogPage _page_spellcheck; + UI::Widget::DialogPage _page_keyshortcuts; + UI::Widget::PrefSpinButton _mouse_sens; UI::Widget::PrefSpinButton _mouse_thres; UI::Widget::PrefSlider _mouse_grabsize; @@ -337,12 +345,16 @@ protected: UI::Widget::PrefCheckButton _spell_ignorenumbers; UI::Widget::PrefCheckButton _spell_ignoreallcaps; + UI::Widget::PrefCombo _misc_overs_bitmap; UI::Widget::PrefEntryFileButtonHBox _misc_bitmap_editor; UI::Widget::PrefCheckButton _misc_bitmap_autoreload; UI::Widget::PrefSpinButton _bitmap_copy_res; UI::Widget::PrefCombo _bitmap_import; + UI::Widget::PrefEntry _kb_search; + UI::Widget::PrefCombo _kb_filelist; + UI::Widget::PrefCheckButton _save_use_current_dir; UI::Widget::PrefCheckButton _save_autosave_enable; UI::Widget::PrefSpinButton _save_autosave_interval; @@ -411,6 +423,37 @@ protected: UI::Widget::PrefEntry _importexport_ocal_username; UI::Widget::PrefEntry _importexport_ocal_password; + /* + * Keyboard shortcut members + */ + class ModelColumns: public Gtk::TreeModel::ColumnRecord { + public: + ModelColumns() { + add(name); + add(id); + add(shortcut); + add(description); + add(shortcutid); + add(user_set); + } + virtual ~ModelColumns() { + } + + Gtk::TreeModelColumn<Glib::ustring> name; + Gtk::TreeModelColumn<Glib::ustring> id; + Gtk::TreeModelColumn<Glib::ustring> shortcut; + Gtk::TreeModelColumn<Glib::ustring> description; + Gtk::TreeModelColumn<unsigned int> shortcutid; + Gtk::TreeModelColumn<unsigned int> user_set; + }; + ModelColumns _kb_columns; + static ModelColumns &onKBGetCols(); + Glib::RefPtr<Gtk::TreeStore> _kb_store; + Gtk::TreeView _kb_tree; + Gtk::CellRendererAccel _kb_shortcut_renderer; + Glib::RefPtr<Gtk::TreeModelFilter> _kb_filter; + gboolean _kb_shortcuts_loaded; + int _max_dialog_width; int _max_dialog_height; int _sb_width; @@ -441,9 +484,26 @@ protected: void initPageBitmaps(); void initPageSystem(); void initPageI18n(); // Do we still need it? + void initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui); void _presentPages(); + /* + * Functions for the Keyboard shortcut editor panel + */ + void onKBReset(); + void onKBImport(); + void onKBExport(); + void onKBList(); + void onKBRealize(); + void onKBListKeyboardShortcuts(); + void onKBTreeEdited (const Glib::ustring& path, guint accel_key, Gdk::ModifierType accel_mods, guint hardware_keycode); + void onKBTreeCleared(const Glib::ustring& path_string); + bool onKBSearchKeyEvent(GdkEventKey *event); + bool onKBSearchFilter(const Gtk::TreeModel::const_iterator& iter); + static void onKBShortcutRenderer(Gtk::CellRenderer *rndr, Gtk::TreeIter const &iter); + + private: InkscapePreferences(); InkscapePreferences(InkscapePreferences const &d); diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index 4f9edf774..245dac5e0 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -216,7 +216,7 @@ LayerPropertiesDialog::_setup_layers_controls() { if ( root ) { SPObject* target = _desktop->currentLayer(); _store->clear(); - _addLayer( document, (SPObject *)root, 0, target, 0 ); + _addLayer( document, SP_OBJECT(root), 0, target, 0 ); } _layout_table.remove(_layer_name_entry); diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index 55a2f19a5..ffdf27b62 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -558,7 +558,8 @@ bool LayersPanel::_handleKeyEvent(GdkEventKey *event) } return false; } -void LayersPanel::_handleButtonEvent(GdkEventButton* event) + +bool LayersPanel::_handleButtonEvent(GdkEventButton* event) { static unsigned doubleclick = 0; @@ -573,9 +574,27 @@ void LayersPanel::_handleButtonEvent(GdkEventButton* event) } } - if ( event->type == GDK_BUTTON_RELEASE && (event->button == 1) - && (event->state & GDK_SHIFT_MASK)) { - // Shift left click on the visible/lock columns toggles "solo" mode + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1) + && (event->state & GDK_MOD1_MASK)) { + // Alt left click on the visible/lock columns - eat this event to keep row selection + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast<int>(event->x); + int y = static_cast<int>(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (col == _tree.get_column(COL_VISIBLE-1) || + col == _tree.get_column(COL_LOCKED-1)) { + return true; + } + } + } + + // TODO - ImageToggler doesn't seem to handle Shift/Alt clicks - so we deal with them here. + if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1) + && (event->state & (GDK_SHIFT_MASK | GDK_MOD1_MASK))) { + Gtk::TreeModel::Path path; Gtk::TreeViewColumn* col = 0; int x = static_cast<int>(event->x); @@ -583,10 +602,27 @@ void LayersPanel::_handleButtonEvent(GdkEventButton* event) int x2 = 0; int y2 = 0; if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { - if (col == _tree.get_column(COL_VISIBLE-1)) { - _takeAction(BUTTON_SOLO); - } else if (col == _tree.get_column(COL_LOCKED-1)) { - _takeAction(BUTTON_LOCK_OTHERS); + if (event->state & GDK_SHIFT_MASK) { + // Shift left click on the visible/lock columns toggles "solo" mode + if (col == _tree.get_column(COL_VISIBLE - 1)) { + _takeAction(BUTTON_SOLO); + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + _takeAction(BUTTON_LOCK_OTHERS); + } + } else if (event->state & GDK_MOD1_MASK) { + // Alt+left click on the visible/lock columns toggles "solo" mode and preserves selection + Gtk::TreeModel::iterator iter = _store->get_iter(path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (col == _tree.get_column(COL_VISIBLE - 1)) { + _desktop->toggleLayerSolo( obj ); + DocumentUndo::maybeDone(_desktop->doc(), "layer:solo", SP_VERB_LAYER_SOLO, _("Toggle layer solo")); + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + _desktop->toggleLockOtherLayers( obj ); + DocumentUndo::maybeDone(_desktop->doc(), "layer:lockothers", SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); + } + } } } } @@ -612,6 +648,7 @@ void LayersPanel::_handleButtonEvent(GdkEventButton* event) } } + return false; } /* @@ -808,8 +845,8 @@ LayersPanel::LayersPanel() : _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &LayersPanel::_handleEdited) ); _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &LayersPanel::_handleEditingCancelled) ); - _tree.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent) ); - _tree.signal_button_release_event().connect_notify( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent) ); + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent), false ); _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &LayersPanel::_handleKeyEvent), false ); _scroller.add( _tree ); @@ -838,43 +875,34 @@ LayersPanel::LayersPanel() : SPDesktop* targetDesktop = getDesktop(); -#if !WITH_GTKMM_3_0 - // TODO: This has been removed from Gtkmm 3.0. Check that everything still - // looks OK! - _buttonsRow.set_child_min_width( 16 ); -#endif - - _buttonsRow.set_layout (Gtk::BUTTONBOX_END); - Gtk::Button* btn = manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, C_("Layers", "New") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_NEW) ); - _buttonsRow.add( *btn ); - _buttonsRow.set_child_secondary( *btn , true); - - btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_TOP, GTK_STOCK_GOTO_TOP, C_("Layers", "Top") ); - btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_TOP) ); - _watchingNonTop.push_back( btn ); - _buttonsRow.add( *btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_LAYER_RAISE, GTK_STOCK_GO_UP, C_("Layers", "Up") ); - btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_UP) ); - _watchingNonTop.push_back( btn ); - _buttonsRow.add( *btn ); - + _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_BOTTOM, GTK_STOCK_GOTO_BOTTOM, C_("Layers", "Bot") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_BOTTOM) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + btn = manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_LOWER, GTK_STOCK_GO_DOWN, C_("Layers", "Dn") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DOWN) ); _watchingNonBottom.push_back( btn ); - _buttonsRow.add( *btn ); - + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_BOTTOM, GTK_STOCK_GOTO_BOTTOM, C_("Layers", "Bot") ); - btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_BOTTOM) ); - _watchingNonBottom.push_back( btn ); - _buttonsRow.add( *btn ); + _styleButton( *btn, targetDesktop, SP_VERB_LAYER_RAISE, GTK_STOCK_GO_UP, C_("Layers", "Up") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_UP) ); + _watchingNonTop.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_TOP, GTK_STOCK_GOTO_TOP, C_("Layers", "Top") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_TOP) ); + _watchingNonTop.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); // btn = manage( new Gtk::Button("Dup") ); // btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) ); @@ -884,9 +912,10 @@ LayersPanel::LayersPanel() : _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("X") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DELETE) ); _watching.push_back( btn ); - _buttonsRow.add( *btn ); - _buttonsRow.set_child_secondary( *btn , true); - + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); diff --git a/src/ui/dialog/layers.h b/src/ui/dialog/layers.h index 12e5f7986..e9fd9ebc6 100644 --- a/src/ui/dialog/layers.h +++ b/src/ui/dialog/layers.h @@ -13,7 +13,6 @@ #define SEEN_LAYERS_PANEL_H #include <gtkmm/box.h> -#include <gtkmm/buttonbox.h> #include <gtkmm/treeview.h> #include <gtkmm/treestore.h> #include <gtkmm/scrolledwindow.h> @@ -65,7 +64,7 @@ private: void _preToggle( GdkEvent const *event ); void _toggled( Glib::ustring const& str, int targetCol ); - void _handleButtonEvent(GdkEventButton *event); + bool _handleButtonEvent(GdkEventButton *event); bool _handleKeyEvent(GdkEventKey *event); bool _handleDragDrop(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, guint time); void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); @@ -122,9 +121,13 @@ private: Gtk::CellRendererText *_text_renderer; Gtk::TreeView::Column *_name_column; #if WITH_GTKMM_3_0 - Gtk::ButtonBox _buttonsRow; + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; #else - Gtk::HButtonBox _buttonsRow; + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; #endif Gtk::ScrolledWindow _scroller; Gtk::Menu _popupMenu; diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp index f67c4db21..1ae9730d5 100644 --- a/src/ui/dialog/object-attributes.cpp +++ b/src/ui/dialog/object-attributes.cpp @@ -123,7 +123,7 @@ void ObjectAttributes::widget_setup (void) } blocked = true; - SPObject *obj = (SPObject*)item; //to get the selected item + SPObject *obj = SP_OBJECT(item); //to get the selected item GObjectClass *klass = G_OBJECT_GET_CLASS(obj); //to deduce the object's type GType type = G_TYPE_FROM_CLASS(klass); const SPAttrDesc *desc; diff --git a/src/ui/dialog/ocaldialogs.h b/src/ui/dialog/ocaldialogs.h index 0dc61abb3..1cdfa15bb 100644 --- a/src/ui/dialog/ocaldialogs.h +++ b/src/ui/dialog/ocaldialogs.h @@ -64,7 +64,7 @@ public: FileDialogBase(const Glib::ustring &title, Gtk::Window& /*parent*/) : Gtk::Window(Gtk::WINDOW_TOPLEVEL) { set_title(title); - sp_transientize((GtkWidget*) gobj()); + sp_transientize(GTK_WIDGET(gobj())); // Allow shrinking of window so labels wrap correctly set_resizable(true); diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index e940a3f55..2ab8cf121 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -138,7 +138,7 @@ static void draw_page( #endif bool ret = ctx->setSurfaceTarget (surface, true, &ctm); if (ret) { - ret = renderer.setupDocument (ctx, junk->_doc, TRUE, NULL); + ret = renderer.setupDocument (ctx, junk->_doc, TRUE, 0., NULL); if (ret) { renderer.renderItem(ctx, junk->_base); ret = ctx->finish(); diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index 0da28061e..0f2c53f99 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -219,8 +219,8 @@ void SpellCheck::setTargetDesktop(SPDesktop *desktop) void SpellCheck::clearRects() { for (GSList *it = _rects; it; it = it->next) { - sp_canvas_item_hide((SPCanvasItem*) it->data); - sp_canvas_item_destroy((SPCanvasItem*) it->data); + sp_canvas_item_hide(SP_CANVAS_ITEM(it->data)); + sp_canvas_item_destroy(SP_CANVAS_ITEM(it->data)); } g_slist_free(_rects); _rects = NULL; @@ -330,8 +330,8 @@ SpellCheck::nextText() _text = getText(_root); if (_text) { - _modified_connection = ((SPObject*) _text)->connectModified(sigc::mem_fun(*this, &SpellCheck::onObjModified)); - _release_connection = ((SPObject*) _text)->connectRelease(sigc::mem_fun(*this, &SpellCheck::onObjReleased)); + _modified_connection = (SP_OBJECT(_text))->connectModified(sigc::mem_fun(*this, &SpellCheck::onObjModified)); + _release_connection = (SP_OBJECT(_text))->connectRelease(sigc::mem_fun(*this, &SpellCheck::onObjReleased)); _layout = te_get_layout (_text); _begin_w = _layout->begin(); diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 16bb8222a..f296ad030 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -278,7 +278,7 @@ void SvgFontsDialog::update_fonts() _model->clear(); for(const GSList *l = fonts; l; l = l->next) { Gtk::TreeModel::Row row = *_model->append(); - SPFont* f = (SPFont*)l->data; + SPFont* f = SP_FONT(l->data); row[_columns.spfont] = f; row[_columns.svgfont] = new SvgFont(f); const gchar* lbl = f->label(); @@ -318,7 +318,7 @@ void SvgFontsDialog::update_global_settings_tab(){ SPObject* obj; for (obj=font->children; obj; obj=obj->next){ if (SP_IS_FONTFACE(obj)){ - _familyname_entry->set_text(((SPFontFace*) obj)->font_family); + _familyname_entry->set_text((SP_FONTFACE(obj))->font_family); } } } diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 82af60fc2..8cf48f827 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -123,6 +123,12 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : iconView->set_tooltip_column( 1 ); iconView->set_pixbuf_column( columns->symbol_image ); + std::vector< Gtk::TargetEntry > targets; + targets.push_back(Gtk::TargetEntry( "application/x-inkscape-paste")); + + iconView->enable_model_drag_source (targets, Gdk::BUTTON1_MASK, Gdk::ACTION_COPY); + iconView->signal_drag_data_get().connect(sigc::mem_fun(*this, &SymbolsDialog::iconDragDataGet)); + sigc::connection connIconChanged; connIconChanged = iconView->signal_selection_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::iconChanged)); @@ -228,6 +234,27 @@ void SymbolsDialog::rebuild() { draw_symbols( symbolDocument ); } +void SymbolsDialog::iconDragDataGet(const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& data, guint info, guint time) { + +#if WITH_GTKMM_3_0 + std::vector<Gtk::TreePath> iconArray = iconView->get_selected_items(); +#else + Gtk::IconView::ArrayHandle_TreePaths iconArray = iconView->get_selected_items(); +#endif + + if( iconArray.empty() ) { + //std::cout << " iconArray empty: huh? " << std::endl; + } else { + Gtk::TreeModel::Path const & path = *iconArray.begin(); + Gtk::ListStore::iterator row = store->get_iter(path); + Glib::ustring symbol_id = (*row)[getColumns()->symbol_id]; + + GdkAtom dataAtom = gdk_atom_intern( "application/x-inkscape-paste", FALSE ); + gtk_selection_data_set( data.gobj(), dataAtom, 9, (guchar*)symbol_id.c_str(), symbol_id.length() ); + } + +} + void SymbolsDialog::iconChanged() { #if WITH_GTKMM_3_0 std::vector<Gtk::TreePath> iconArray = iconView->get_selected_items(); @@ -418,6 +445,8 @@ void SymbolsDialog::draw_symbols( SPDocument* symbolDocument ) { (*row)[columns->symbol_image] = pixbuf; } } + + delete columns; } /* diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h index c2bb4448e..5486ff546 100644 --- a/src/ui/dialog/symbols.h +++ b/src/ui/dialog/symbols.h @@ -54,6 +54,7 @@ private: void rebuild(); void iconChanged(); + void iconDragDataGet(const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection_data, guint info, guint time); void get_symbols(); void draw_symbols( SPDocument* symbol_document ); diff --git a/src/ui/tool/node-tool.cpp b/src/ui/tool/node-tool.cpp index b532c8b65..7b6502ec3 100644 --- a/src/ui/tool/node-tool.cpp +++ b/src/ui/tool/node-tool.cpp @@ -197,6 +197,10 @@ void ink_node_tool_dispose(GObject *object) nt->enableGrDrag(false); + if (nt->flash_tempitem) { + nt->desktop->remove_temporary_canvasitem(nt->flash_tempitem); + } + nt->_selection_changed_connection.disconnect(); nt->_selection_modified_connection.disconnect(); nt->_mouseover_changed_connection.disconnect(); diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp index e5c542a7c..31fb3096c 100644 --- a/src/ui/widget/color-picker.cpp +++ b/src/ui/widget/color-picker.cpp @@ -55,7 +55,7 @@ void ColorPicker::setupDialog(const Glib::ustring &title) _colorSelectorDialog.hide(); _colorSelectorDialog.set_title (title); _colorSelectorDialog.set_border_width (4); - _colorSelector = (SPColorSelector*)sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK); + _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); _colorSelectorDialog.get_vbox()->pack_start ( *Glib::wrap(&_colorSelector->vbox), true, true, 0); diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp index c06f70185..fbb9c0e24 100644 --- a/src/ui/widget/layer-selector.cpp +++ b/src/ui/widget/layer-selector.cpp @@ -241,7 +241,11 @@ private: void LayerSelector::_layersChanged() { if (_desktop) { - _selectLayer(_desktop->currentLayer()); + /* + * This code fixes #166691 but causes issues #1066543 and #1080378. + * Comment out until solution found. + */ + //_selectLayer(_desktop->currentLayer()); } } diff --git a/src/ui/widget/licensor.cpp b/src/ui/widget/licensor.cpp index 7fff7d87f..8ecd36af2 100644 --- a/src/ui/widget/licensor.cpp +++ b/src/ui/widget/licensor.cpp @@ -44,7 +44,7 @@ const struct rdf_license_t _other_license = class LicenseItem : public Gtk::RadioButton { public: - LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr); + LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr, Gtk::RadioButtonGroup *group); protected: void on_toggled(); struct rdf_license_t const *_lic; @@ -52,13 +52,12 @@ protected: Registry &_wr; }; -LicenseItem::LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr) +LicenseItem::LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr, Gtk::RadioButtonGroup *group) : Gtk::RadioButton(_(license->name)), _lic(license), _eep(entity), _wr(wr) { - static Gtk::RadioButtonGroup group = get_group(); - static bool first = true; - if (first) first = false; - else set_group (group); + if (group) { + set_group (*group); + } } /// \pre it is assumed that the license URI entry is a Gtk::Entry @@ -97,18 +96,19 @@ void Licensor::init (Registry& wr) LicenseItem *i; wr.setUpdating (true); - i = manage (new LicenseItem (&_proprietary_license, _eentry, wr)); + i = manage (new LicenseItem (&_proprietary_license, _eentry, wr, NULL)); + Gtk::RadioButtonGroup group = i->get_group(); add (*i); LicenseItem *pd = i; for (struct rdf_license_t * license = rdf_licenses; license && license->name; license++) { - i = manage (new LicenseItem (license, _eentry, wr)); + i = manage (new LicenseItem (license, _eentry, wr, &group)); add(*i); } // add Other at the end before the URI field for the confused ppl. - LicenseItem *io = manage (new LicenseItem (&_other_license, _eentry, wr)); + LicenseItem *io = manage (new LicenseItem (&_other_license, _eentry, wr, &group)); add (*io); pd->set_active(); diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp index 90eb6a3fd..2ab72d6c7 100644 --- a/src/ui/widget/page-sizer.cpp +++ b/src/ui/widget/page-sizer.cpp @@ -245,12 +245,14 @@ PageSizer::PageSizer(Registry & _wr) _widgetRegistry(&_wr) { // set precision of scalar entry boxes + _wr.setUpdating (true); _dimensionWidth.setDigits(5); _dimensionHeight.setDigits(5); _marginTop.setDigits(5); _marginLeft.setDigits(5); _marginRight.setDigits(5); _marginBottom.setDigits(5); + _wr.setUpdating (false); //# Set up the Paper Size combo box _paperSizeListStore = Gtk::ListStore::create(_paperSizeListColumns); @@ -315,11 +317,13 @@ PageSizer::PageSizer(Registry & _wr) // Setting default custom unit to document unit SPDesktop *dt = SP_ACTIVE_DESKTOP; SPNamedView *nv = sp_desktop_namedview(dt); + _wr.setUpdating (true); if (nv->units) { _dimensionUnits.setUnit(nv->units); } else if (nv->doc_units) { _dimensionUnits.setUnit(nv->doc_units); } + _wr.setUpdating (false); //## Set up custom size frame _customFrame.set_label(_("Custom size")); diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index 07145f5f3..b793893c7 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -640,7 +640,7 @@ void PrefCombo::on_changed() if (this->get_visible()) //only take action if user changed value { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if(_values.size() > 0) + if(!_values.empty()) { prefs->setInt(_prefs_path, _values[this->get_active_row_number()]); } diff --git a/src/ui/widget/rotateable.cpp b/src/ui/widget/rotateable.cpp index 7be666843..1d91515e5 100644 --- a/src/ui/widget/rotateable.cpp +++ b/src/ui/widget/rotateable.cpp @@ -24,12 +24,15 @@ Rotateable::Rotateable(): { dragging = false; working = false; + scrolling = false; modifier = 0; current_axis = axis; signal_button_press_event().connect(sigc::mem_fun(*this, &Rotateable::on_click)); signal_motion_notify_event().connect(sigc::mem_fun(*this, &Rotateable::on_motion)); signal_button_release_event().connect(sigc::mem_fun(*this, &Rotateable::on_release)); + signal_scroll_event().connect(sigc::mem_fun(*this, &Rotateable::on_scroll)); + } bool Rotateable::on_click(GdkEventButton *event) { @@ -124,6 +127,34 @@ bool Rotateable::on_release(GdkEventButton *event) { return false; } +bool Rotateable::on_scroll(GdkEventScroll* event) +{ + double change = 0.0; + + if (event->direction == GDK_SCROLL_UP) { + change = 1.0; + } else if (event->direction == GDK_SCROLL_DOWN) { + change = -1.0; + } else { + return FALSE; + } + + drag_started_x = event->x; + drag_started_y = event->y; + modifier = get_single_modifier(modifier, event->state); + dragging = false; + working = false; + scrolling = true; + current_axis = axis; + + do_scroll(change, modifier); + + dragging = false; + working = false; + scrolling = false; + + return TRUE; +} Rotateable::~Rotateable() { } diff --git a/src/ui/widget/rotateable.h b/src/ui/widget/rotateable.h index 15e0bf71c..52fb5306c 100644 --- a/src/ui/widget/rotateable.h +++ b/src/ui/widget/rotateable.h @@ -31,10 +31,12 @@ public: bool on_click(GdkEventButton *event); bool on_motion(GdkEventMotion *event); bool on_release(GdkEventButton *event); + bool on_scroll(GdkEventScroll* event); double axis; double current_axis; double maxdecl; + bool scrolling; private: double drag_started_x; @@ -47,6 +49,7 @@ private: virtual void do_motion (double /*by*/, guint /*state*/) {} virtual void do_release (double /*by*/, guint /*state*/) {} + virtual void do_scroll (double /*by*/, guint /*state*/) {} }; } // namespace Widget diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index e5992958b..41d7c8be2 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -47,6 +47,7 @@ #include "pixmaps/cursor-adj-h.xpm" #include "pixmaps/cursor-adj-s.xpm" #include "pixmaps/cursor-adj-l.xpm" +#include "pixmaps/cursor-adj-a.xpm" #include "sp-cursor.h" #include "gradient-chemistry.h" @@ -299,7 +300,7 @@ SelectedStyle::SelectedStyle(bool /*layout*/) // List of units should match with Fill/Stroke dialog stroke style width list for (GSList *l = sp_unit_get_list(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); l != NULL; l = l->next) { - SPUnit const *u = (SPUnit*)l->data; + SPUnit const *u = static_cast<SPUnit*>(l->data); Gtk::RadioMenuItem *mi = Gtk::manage(new Gtk::RadioMenuItem(_sw_group)); mi->add(*(new Gtk::Label(u->abbr, 0.0, 0.5))); _unit_mis = g_slist_append(_unit_mis, mi); @@ -338,6 +339,7 @@ SelectedStyle::SelectedStyle(bool /*layout*/) _stroke_width_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click)); _stroke_width_place.signal_button_release_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click)); + _opacity_sb.signal_populate_popup().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_menu)); _opacity_sb.signal_value_changed().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_changed)); // Connect to key-press to ensure focus is consistent with other spin buttons when using the keys vs mouse-click @@ -449,7 +451,7 @@ SelectedStyle::setDesktop(SPDesktop *desktop) this ) )); - _sw_unit = (SPUnit *) sp_desktop_namedview(desktop)->doc_units; + _sw_unit = const_cast<SPUnit*>(sp_desktop_namedview(desktop)->doc_units); // Set the doc default unit active in the units list gint length = g_slist_length(_unit_mis); @@ -986,13 +988,13 @@ SelectedStyle::update() if (SP_IS_LINEARGRADIENT (server)) { SPGradient *vector = SP_GRADIENT(server)->getVector(); - sp_gradient_image_set_gradient ((SPGradientImage *) _gradient_preview_l[i], vector); + sp_gradient_image_set_gradient(SP_GRADIENT_IMAGE(_gradient_preview_l[i]), vector); place->add(_gradient_box_l[i]); place->set_tooltip_text(__lgradient[i]); _mode[i] = SS_LGRADIENT; } else if (SP_IS_RADIALGRADIENT (server)) { SPGradient *vector = SP_GRADIENT(server)->getVector(); - sp_gradient_image_set_gradient ((SPGradientImage *) _gradient_preview_r[i], vector); + sp_gradient_image_set_gradient(SP_GRADIENT_IMAGE(_gradient_preview_r[i]), vector); place->add(_gradient_box_r[i]); place->set_tooltip_text(__rgradient[i]); _mode[i] = SS_RGRADIENT; @@ -1008,7 +1010,7 @@ SelectedStyle::update() guint32 color = paint->value.color.toRGBA32( SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query->fill_opacity.value : query->stroke_opacity.value)); _lastselected[i] = _thisselected[i]; - _thisselected[i] = color | 0xff; // only color, opacity === 1 + _thisselected[i] = color; // include opacity ((Inkscape::UI::Widget::ColorPreview*)_color_preview[i])->setRgba32 (color); _color_preview[i]->show_all(); place->add(*_color_preview[i]); @@ -1211,39 +1213,43 @@ RotateableSwatch::~RotateableSwatch() { } double -RotateableSwatch::color_adjust(float *hsl, double by, guint32 cc, guint modifier) +RotateableSwatch::color_adjust(float *hsla, double by, guint32 cc, guint modifier) { - sp_color_rgb_to_hsl_floatv (hsl, SP_RGBA32_R_F(cc), SP_RGBA32_G_F(cc), SP_RGBA32_B_F(cc)); - + sp_color_rgb_to_hsl_floatv (hsla, SP_RGBA32_R_F(cc), SP_RGBA32_G_F(cc), SP_RGBA32_B_F(cc)); + hsla[3] = SP_RGBA32_A_F(cc); double diff = 0; if (modifier == 2) { // saturation - double old = hsl[1]; + double old = hsla[1]; if (by > 0) { - hsl[1] += by * (1 - hsl[1]); + hsla[1] += by * (1 - hsla[1]); } else { - hsl[1] += by * (hsl[1]); + hsla[1] += by * (hsla[1]); } - diff = hsl[1] - old; + diff = hsla[1] - old; } else if (modifier == 1) { // lightness - double old = hsl[2]; + double old = hsla[2]; if (by > 0) { - hsl[2] += by * (1 - hsl[2]); + hsla[2] += by * (1 - hsla[2]); } else { - hsl[2] += by * (hsl[2]); + hsla[2] += by * (hsla[2]); } - diff = hsl[2] - old; + diff = hsla[2] - old; + } else if (modifier == 3) { // alpha + double old = hsla[3]; + hsla[3] += by/2; + diff = hsla[3] - old; } else { // hue - double old = hsl[0]; - hsl[0] += by/2; - while (hsl[0] < 0) - hsl[0] += 1; - while (hsl[0] > 1) - hsl[0] -= 1; - diff = hsl[0] - old; + double old = hsla[0]; + hsla[0] += by/2; + while (hsla[0] < 0) + hsla[0] += 1; + while (hsla[0] > 1) + hsla[0] -= 1; + diff = hsla[0] - old; } float rgb[3]; - sp_color_hsl_to_rgb_floatv (rgb, hsl[0], hsl[1], hsl[2]); + sp_color_hsl_to_rgb_floatv (rgb, hsla[0], hsla[1], hsla[2]); gchar c[64]; sp_svg_write_color (c, sizeof(c), @@ -1256,10 +1262,14 @@ RotateableSwatch::color_adjust(float *hsl, double by, guint32 cc, guint modifier ); SPCSSAttr *css = sp_repr_css_attr_new (); - if (fillstroke == SS_FILL) - sp_repr_css_set_property (css, "fill", c); - else - sp_repr_css_set_property (css, "stroke", c); + + if (modifier == 3) { // alpha + Inkscape::CSSOStringStream osalpha; + osalpha << hsla[3]; + sp_repr_css_set_property(css, (fillstroke == SS_FILL) ? "fill-opacity" : "stroke-opacity", osalpha.str().c_str()); + } else { + sp_repr_css_set_property (css, (fillstroke == SS_FILL) ? "fill" : "stroke", c); + } sp_desktop_set_style (parent->getDesktop(), css); sp_repr_css_attr_unref (css); return diff; @@ -1270,7 +1280,7 @@ RotateableSwatch::do_motion(double by, guint modifier) { if (parent->_mode[fillstroke] != SS_COLOR) return; - if (!cr_set && modifier != 3) { + if (!scrolling && !cr_set) { GtkWidget *w = GTK_WIDGET(gobj()); GdkPixbuf *pixbuf = NULL; @@ -1278,6 +1288,8 @@ RotateableSwatch::do_motion(double by, guint modifier) { pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_s_xpm); } else if (modifier == 1) { // lightness pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_l_xpm); + } else if (modifier == 3) { // alpha + pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_a_xpm); } else { // hue pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_h_xpm); } @@ -1305,43 +1317,51 @@ RotateableSwatch::do_motion(double by, guint modifier) { cc = startcolor; } - float hsl[3]; + float hsla[4]; double diff = 0; - if (modifier != 3) { - diff = color_adjust(hsl, by, cc, modifier); - } - if (modifier == 3) { // Alt, do nothing + diff = color_adjust(hsla, by, cc, modifier); + + if (modifier == 3) { // alpha + DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, (_("Adjust alpha"))); + double ch = hsla[3]; + parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>alpha</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Shift</b> to adjust saturation, without modifiers to adjust hue"), ch - diff, ch, diff); } else if (modifier == 2) { // saturation DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust saturation"))); - double ch = hsl[1]; - parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>saturation</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, without modifiers to adjust hue"), ch - diff, ch, diff); + double ch = hsla[1]; + parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>saturation</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff); } else if (modifier == 1) { // lightness DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust lightness"))); - double ch = hsl[2]; - parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>lightness</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, without modifiers to adjust hue"), ch - diff, ch, diff); + double ch = hsla[2]; + parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>lightness</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff); } else { // hue DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust hue"))); - double ch = hsl[0]; - parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>hue</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Ctrl</b> to adjust lightness"), ch - diff, ch, diff); + double ch = hsla[0]; + parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>hue</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, with <b>Ctrl</b> to adjust lightness"), ch - diff, ch, diff); } } + +void +RotateableSwatch::do_scroll(double by, guint modifier) { + do_motion(by/30.0, modifier); + do_release(by/30.0, modifier); +} + void RotateableSwatch::do_release(double by, guint modifier) { if (parent->_mode[fillstroke] != SS_COLOR) return; - float hsl[3]; - if (modifier != 3) { - color_adjust(hsl, by, startcolor, modifier); - } + float hsla[4]; + color_adjust(hsla, by, startcolor, modifier); if (cr_set) { GtkWidget *w = GTK_WIDGET(gobj()); @@ -1357,7 +1377,9 @@ RotateableSwatch::do_release(double by, guint modifier) { cr_set = false; } - if (modifier == 3) { // Alt, do nothing + if (modifier == 3) { // alpha + DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, ("Adjust alpha")); } else if (modifier == 2) { // saturation DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, SP_VERB_DIALOG_FILL_STROKE, ("Adjust saturation")); @@ -1467,6 +1489,11 @@ RotateableStrokeWidth::do_release(double by, guint modifier) { parent->getDesktop()->event_context->_message_context->clear(); } +void +RotateableStrokeWidth::do_scroll(double by, guint modifier) { + do_motion(by/10.0, modifier); + startvalue_set = false; +} Dialog::FillAndStroke *get_fill_and_stroke_panel(SPDesktop *desktop) { diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index a9e9d7274..fac4f22e6 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -61,8 +61,10 @@ public: ~RotateableSwatch(); double color_adjust (float *hsl, double by, guint32 cc, guint state); + virtual void do_motion (double by, guint state); virtual void do_release (double by, guint state); + virtual void do_scroll (double by, guint state); private: guint fillstroke; @@ -87,6 +89,7 @@ public: double value_adjust(double current, double by, guint modifier, bool final); virtual void do_motion (double by, guint state); virtual void do_release (double by, guint state); + virtual void do_scroll (double by, guint state); private: SelectedStyle *parent; |
