From 1d854ff519b9c0867bfa4ecaf2f6329ca256f06a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 10:29:06 -0500 Subject: Experimental merge of Ponyscape features into trunk (will not compile) (bzr r13090.1.1) --- src/ui/dialog/Makefile_insert | 4 + src/ui/dialog/lpe-powerstroke-properties.cpp | 203 +++ src/ui/dialog/lpe-powerstroke-properties.h | 99 ++ src/ui/dialog/objects.cpp | 2048 ++++++++++++++++++++++++++ src/ui/dialog/objects.h | 255 ++++ src/ui/dialog/tags.cpp | 1182 +++++++++++++++ src/ui/dialog/tags.h | 181 +++ 7 files changed, 3972 insertions(+) create mode 100644 src/ui/dialog/lpe-powerstroke-properties.cpp create mode 100644 src/ui/dialog/lpe-powerstroke-properties.h create mode 100644 src/ui/dialog/objects.cpp create mode 100644 src/ui/dialog/objects.h create mode 100644 src/ui/dialog/tags.cpp create mode 100644 src/ui/dialog/tags.h (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index c37767a08..1cf667f2a 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -109,4 +109,8 @@ ink_common_sources += \ ui/dialog/undo-history.h \ ui/dialog/xml-tree.cpp \ ui/dialog/xml-tree.h \ + ui/dialog/lpe-powerstroke-properties.cpp \ + ui/dialog/lpe-powerstroke-properties.h \ + ui/dialog/objects.cpp \ + ui/dialog/objects.h \ $(inkboard_dialogs) diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp new file mode 100644 index 000000000..cef6f494e --- /dev/null +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -0,0 +1,203 @@ +/** + * @file + * Dialog for renaming layers. + */ +/* Author: + * Bryce W. Harrington + * Andrius R. + * Abhishek Sharma + * + * Copyright (C) 2004 Bryce Harrington + * Copyright (C) 2006 Andrius R. + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#include "lpe-powerstroke-properties.h" +#include +#include +#include +#include +#include "inkscape.h" +#include "desktop.h" +#include "document.h" +#include "document-undo.h" +#include "layer-manager.h" +#include "message-stack.h" +#include "desktop-handles.h" +#include "sp-object.h" +#include "sp-item.h" +#include "verbs.h" +#include "selection.h" +#include "selection-chemistry.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +//#include "event-context.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +PowerstrokePropertiesDialog::PowerstrokePropertiesDialog() +: _desktop(NULL), _knotpoint(NULL), _position_visible(false) +{ + Gtk::Box *mainVBox = get_vbox(); + + _layout_table.set_spacings(4); + _layout_table.resize (2, 2); + + // Layer name widgets + _powerstroke_position_entry.set_activates_default(true); + _powerstroke_position_label.set_label(_("Position:")); + _powerstroke_position_label.set_alignment(1.0, 0.5); + + _powerstroke_width_entry.set_activates_default(true); + _powerstroke_width_label.set_label(_("Width:")); + _powerstroke_width_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_powerstroke_position_label, + 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_powerstroke_position_entry, + 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + + _layout_table.attach(_powerstroke_width_label, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_powerstroke_width_entry, 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + + mainVBox->pack_start(_layout_table, true, true, 4); + + // Buttons + _close_button.set_use_stock(true); + _close_button.set_label(Gtk::Stock::CANCEL.id); + _close_button.set_can_default(); + + _apply_button.set_use_underline(true); + _apply_button.set_can_default(); + + _close_button.signal_clicked() + .connect(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_close)); + _apply_button.signal_clicked() + .connect(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_apply)); + + signal_delete_event().connect( + sigc::bind_return( + sigc::hide(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_close)), + true + ) + ); + + add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); + add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); + + _apply_button.grab_default(); + + show_all_children(); + + set_focus(_powerstroke_width_entry); +} + +PowerstrokePropertiesDialog::~PowerstrokePropertiesDialog() { + + _setDesktop(NULL); +} + +void PowerstrokePropertiesDialog::showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt) +{ + PowerstrokePropertiesDialog *dialog = new PowerstrokePropertiesDialog(); + + dialog->_setDesktop(desktop); + dialog->_setKnotPoint(knotpoint); + dialog->_setPt(pt); + + dialog->set_title(_("Modify Node Position")); + dialog->_apply_button.set_label(_("_Move")); + + dialog->set_modal(true); + desktop->setWindowTransient (dialog->gobj()); + dialog->property_destroy_with_parent() = true; + + dialog->show(); + dialog->present(); +} + +void +PowerstrokePropertiesDialog::_apply() +{ + std::istringstream i_pos(_powerstroke_position_entry.get_text()); + std::istringstream i_width(_powerstroke_width_entry.get_text()); + double d_pos, d_width; + if ((i_pos >> d_pos) && i_width >> d_width) { + _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); + } + _close(); +} + +void +PowerstrokePropertiesDialog::_close() +{ + _setDesktop(NULL); + destroy_(); + Glib::signal_idle().connect( + sigc::bind_return( + sigc::bind(sigc::ptr_fun(&::operator delete), this), + false + ) + ); +} + +bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey *event) +{ + + /*switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: { + _apply(); + return true; + } + break; + }*/ + return false; +} + +void PowerstrokePropertiesDialog::_handleButtonEvent(GdkEventButton* event) +{ + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + _apply(); + } +} + +void PowerstrokePropertiesDialog::_setKnotPoint(Geom::Point knotpoint) +{ + _powerstroke_position_entry.set_text(boost::lexical_cast(knotpoint.x())); + _powerstroke_width_entry.set_text(boost::lexical_cast(knotpoint.y())); +} + +void PowerstrokePropertiesDialog::_setPt(const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt) +{ + _knotpoint = const_cast(pt); +} + +void PowerstrokePropertiesDialog::_setDesktop(SPDesktop *desktop) { + if (desktop) { + Inkscape::GC::anchor (desktop); + } + if (_desktop) { + Inkscape::GC::release (_desktop); + } + _desktop = desktop; +} + +} // namespace +} // namespace +} // namespace + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/lpe-powerstroke-properties.h b/src/ui/dialog/lpe-powerstroke-properties.h new file mode 100644 index 000000000..c53eac0d9 --- /dev/null +++ b/src/ui/dialog/lpe-powerstroke-properties.h @@ -0,0 +1,99 @@ +/** @file + * @brief Dialog for renaming layers + */ +/* Author: + * Bryce W. Harrington + * + * Copyright (C) 2004 Bryce Harrington + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_DIALOG_POWERSTROKE_PROPERTIES_H +#define INKSCAPE_DIALOG_POWERSTROKE_PROPERTIES_H + +#include <2geom/point.h> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "live_effects/parameter/powerstrokepointarray.h" + +class SPDesktop; + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +class PowerstrokePropertiesDialog : public Gtk::Dialog { + public: + PowerstrokePropertiesDialog(); + virtual ~PowerstrokePropertiesDialog(); + + Glib::ustring getName() const { return "LayerPropertiesDialog"; } + + static void showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt); + +protected: + + SPDesktop *_desktop; + Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *_knotpoint; + + Gtk::Label _powerstroke_position_label; + Gtk::Entry _powerstroke_position_entry; + Gtk::Label _powerstroke_width_label; + Gtk::Entry _powerstroke_width_entry; + Gtk::Table _layout_table; + bool _position_visible; + + Gtk::Button _close_button; + Gtk::Button _apply_button; + + sigc::connection _destroy_connection; + + static PowerstrokePropertiesDialog &_instance() { + static PowerstrokePropertiesDialog instance; + return instance; + } + + void _setDesktop(SPDesktop *desktop); + void _setPt(const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt); + + void _apply(); + void _close(); + + void _setKnotPoint(Geom::Point knotpoint); + void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); + + bool _handleKeyEvent(GdkEventKey *event); + void _handleButtonEvent(GdkEventButton* event); + + friend class Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity; + +private: + PowerstrokePropertiesDialog(PowerstrokePropertiesDialog const &); // no copy + PowerstrokePropertiesDialog &operator=(PowerstrokePropertiesDialog const &); // no assign +}; + +} // namespace +} // namespace +} // namespace + + +#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp new file mode 100644 index 000000000..31e73db29 --- /dev/null +++ b/src/ui/dialog/objects.cpp @@ -0,0 +1,2048 @@ +/* + * A simple panel for objects + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "objects.h" +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" +#include "inkscape.h" +#include "preferences.h" +#include "sp-item.h" +#include "sp-object.h" +#include "sp-shape.h" +#include "svg/css-ostringstream.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +#include "ui/widget/layertypeicon.h" +#include "ui/widget/insertordericon.h" +#include "ui/widget/clipmaskicon.h" +#include "ui/widget/highlight-picker.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/node.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-root.h" +//#include "event-context.h" +#include "selection.h" +#include "dialogs/dialog-events.h" +#include "widgets/sp-color-notebook.h" +#include "style.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "layer-manager.h" + +//#define DUMP_LAYERS 1 + +namespace Inkscape { +namespace UI { +namespace Dialog { + +using Inkscape::XML::Node; + +/** + * Gets an instance of the Objects panel + */ +ObjectsPanel& ObjectsPanel::getInstance() +{ + return *new ObjectsPanel(); +} + +/** + * Column enumeration + */ +enum { + COL_VISIBLE = 1, + COL_LOCKED, + COL_TYPE, + COL_INSERTORDER, + COL_CLIPMASK, + COL_HIGHLIGHT +}; + +/** + * Button enumeration + */ +enum { + BUTTON_NEW = 0, + BUTTON_RENAME, + BUTTON_TOP, + BUTTON_BOTTOM, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_DUPLICATE, + BUTTON_DELETE, + BUTTON_SOLO, + BUTTON_SHOW_ALL, + BUTTON_HIDE_ALL, + BUTTON_LOCK_OTHERS, + BUTTON_LOCK_ALL, + BUTTON_UNLOCK_ALL, + BUTTON_SETCLIP, + BUTTON_CLIPGROUP, + BUTTON_SETINVCLIP, + BUTTON_UNSETCLIP, + BUTTON_SETMASK, + BUTTON_UNSETMASK, + BUTTON_GROUP, + BUTTON_UNGROUP, + BUTTON_COLLAPSE_ALL, + DRAGNDROP +}; + +/** + * Xml node observer for observing objects in the document + */ +class ObjectsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { +public: + /** + * Creates a new object watcher + * @param pnl The panel to which the object watcher belongs + * @param obj The object to watch + */ + ObjectWatcher(ObjectsPanel* pnl, SPObject* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _highlightAttr(g_quark_from_string("inkscape:highlight-color")), + _lockedAttr(g_quark_from_string("sodipodi:insensitive")), + _labelAttr(g_quark_from_string("inkscape:label")), + _groupAttr(g_quark_from_string("inkscape:groupmode")), + _styleAttr(g_quark_from_string("style")), + _clipAttr(g_quark_from_string("clip-path")), + _maskAttr(g_quark_from_string("mask")) + {} + + virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if ( _pnl && _obj ) { + if ( name == _lockedAttr || name == _labelAttr || name == _highlightAttr || name == _groupAttr || name == _styleAttr || name == _clipAttr || name == _maskAttr ) { + _pnl->_updateObject(_obj, name == _highlightAttr); + if ( name == _styleAttr ) { + _pnl->_updateComposite(); + } + } + } + } + + /** + * Objects panel to which this watcher belongs + */ + ObjectsPanel* _pnl; + + /** + * The object that is being observed + */ + SPObject* _obj; + + /** + * The xml representation of the object that is being observed + */ + Inkscape::XML::Node* _repr; + + /* These are quarks which define the attributes that we are observing */ + GQuark _highlightAttr; + GQuark _lockedAttr; + GQuark _labelAttr; + GQuark _groupAttr; + GQuark _styleAttr; + GQuark _clipAttr; + GQuark _maskAttr; +}; + +class ObjectsPanel::InternalUIBounce +{ +public: + int _actionCode; +}; + +class ObjectsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colObject); + add(_colVisible); + add(_colLocked); + add(_colLabel); + add(_colType); + add(_colHighlight); + add(_colClipMask); + add(_colInsertOrder); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colVisible; + Gtk::TreeModelColumn _colLocked; + Gtk::TreeModelColumn _colType; + Gtk::TreeModelColumn _colHighlight; + Gtk::TreeModelColumn _colClipMask; + Gtk::TreeModelColumn _colInsertOrder; +}; + +/** + * Stylizes a button using the given icon name and tooltip + */ +void ObjectsPanel::_styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ) +{ + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *Gtk::manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + + btn.set_tooltip_text (tooltip); + +} + +/** + * Adds an item to the pop-up (right-click) menu + * @param desktop The active destktop + * @param code Action code + * @param iconName Icon name + * @param fallback Fallback text + * @param id Button id for callback function + * @return The generated menu item + */ +Gtk::MenuItem& ObjectsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) +{ + GtkWidget* iconWidget = 0; + const char* label = 0; + + if ( iconName ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !iconWidget && action && action->image ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); + } + + if ( action ) { + label = action->name; + } + } + } + + if ( !label && fallback ) { + label = fallback; + } + + Gtk::Widget* wrapped = 0; + if ( iconWidget ) { + wrapped = Gtk::manage(Glib::wrap(iconWidget)); + wrapped->show(); + } + + + Gtk::MenuItem* item = 0; + + if (wrapped) { + item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); + } else { + item = Gtk::manage(new Gtk::MenuItem(label, true)); + } + + item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_takeAction), id)); + _popupMenu.append(*item); + + return *item; +} + +/** + * Callback function for when an object changes. Essentially refreshes the entire tree + * @param obj Object which was changed (currently not used as the entire tree is recreated) + */ +void ObjectsPanel::_objectsChanged(SPObject */*obj*/) +{ + //First, unattach the watchers + while (!_objectWatchers.empty()) + { + ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_desktop) { + //Get the current document's root and use that to enumerate the tree + SPDocument* document = _desktop->doc(); + SPRoot* root = document->getRoot(); + if ( root ) { + _selectedConnection.block(); + //Clear the tree store + _store->clear(); + //Add all items recursively + _addObject( root, 0 ); + _selectedConnection.unblock(); + //Set the tree selection + _objectsSelected(_desktop->selection); + //Handle button sensitivity + _checkTreeSelection(); + } + } +} + +/** + * Recursively adds the children of the given item to the tree + * @param obj Root object to add to the tree + * @param parentRow Parent tree row (or NULL if adding to tree root) + */ +void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) +{ + if ( _desktop && obj ) { + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + + if (SP_IS_ITEM(child)) + { + SPItem * item = SP_ITEM(child); + SPGroup * group = SP_IS_GROUP(child) ? SP_GROUP(child) : 0; + + //Add the item to the tree and set the column information + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = item; + row[_model->_colLabel] = item->label() ? item->label() : item->getId(); + row[_model->_colVisible] = !item->isHidden(); + row[_model->_colLocked] = !item->isSensitive(); + row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; + row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00; + row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0); + row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + + //If our parent object is a group and it's expanded, expand the tree + if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded()) + { + _tree.expand_to_path( _store->get_path(iter) ); + } + + //Add an object watcher to the item + ObjectsPanel::ObjectWatcher *w = new ObjectsPanel::ObjectWatcher(this, child); + child->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + + //If the item is a group, recursively add its children + if (group) + { + _addObject( child, &row ); + } + } + } + } +} + +/** + * Updates an item in the tree and optionally recursively updates the item's children + * @param obj The item to update in the tree + * @param recurse Whether to recurse through the item's children + */ +void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) { + //Find the object in the tree store and update it + _store->foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_checkForUpdated), obj) ); + if (recurse) + { + for (SPObject * iter = obj->children; iter != NULL; iter = iter->next) + { + _updateObject(iter, recurse); + } + } +} + +/** + * Checks items in the tree store and updates the given item + * @param iter Current item being looked at in the tree + * @param obj Object to update + * @return + */ +bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + if ( obj == row[_model->_colObject] ) + { + //We found our item in the tree!! Update it! + SPItem * item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; + SPGroup * group = SP_IS_GROUP(obj) ? SP_GROUP(obj) : 0; + + row[_model->_colLabel] = obj->label() ? obj->label() : obj->getId(); + row[_model->_colVisible] = item ? !item->isHidden() : false; + row[_model->_colLocked] = item ? !item->isSensitive() : false; + row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; + row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; + row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? (item->clip_ref->getObject()->inverse ? 3 : 1) : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; + row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + + return true; + } + + return false; +} + +/** + * Updates the composite controls for the selected item + */ +void ObjectsPanel::_updateComposite() { + if (!_blockCompositeUpdate) + { + //Set the default values + bool setValues = true; + + //Get/set the values + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_compositingChanged), &setValues)); + } +} + +/** + * Sets the compositing values for the first selected item in the tree + * @param iter Current tree item + * @param setValues Whether to set the compositing values + * @param blur Blur value to use + */ +void ObjectsPanel::_compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPItem *item = row[_model->_colObject]; + if (*setValues) + { + _setCompositingValues(item); + *setValues = false; + } + } +} + +/** + * Occurs when the current desktop selection changes + * @param sel The current selection + */ +void ObjectsPanel::_objectsSelected( Selection *sel ) { + + bool setOpacity = true; + _selectedConnection.block(); + _tree.get_selection()->unselect_all(); + SPItem *item = NULL; + for (const GSList * iter = sel->itemList(); iter != NULL; iter = iter->next) + { + item = reinterpret_cast(iter->data); + if (setOpacity) + { + _setCompositingValues(item); + setOpacity = false; + } + _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, iter->next == NULL)); + } + if (!item) { + if (_desktop->currentLayer() && SP_IS_ITEM(_desktop->currentLayer())) { + item = SP_ITEM(_desktop->currentLayer()); + _setCompositingValues(item); + _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, true)); + } + } + _selectedConnection.unblock(); + _checkTreeSelection(); +} + +/** + * Helper function for setting the compositing values + * @param item Item to use for setting the compositing values + */ +void ObjectsPanel::_setCompositingValues(SPItem *item) +{ + //Block the connections to avoid interference + _opacityConnection.block(); + _blendConnection.block(); + _blurConnection.block(); + + //Set the opacity + _opacity_adjustment.set_value((item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1) * _opacity_adjustment.get_upper()); + SPFeBlend *spblend = NULL; + SPGaussianBlur *spblur = NULL; + if (item->style->getFilter()) + { + for(SPObject *primitive_obj = item->style->getFilter()->children; primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); primitive_obj = primitive_obj->next) { + if(SP_IS_FEBLEND(primitive_obj) && !spblend) { + //Get the blend mode + spblend = SP_FEBLEND(primitive_obj); + } + + if(SP_IS_GAUSSIANBLUR(primitive_obj) && !spblur) { + //Get the blur value + spblur = SP_GAUSSIANBLUR(primitive_obj); + } + } + } + + //Set the blend mode + _fe_cb.set_blend_mode(spblend ? spblend->blend_mode : Inkscape::Filters::BLEND_NORMAL); + + //Set the blur value + Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); + if (bbox && spblur) { + double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? + _fe_blur.set_blur_value(spblur->stdDeviation.getNumber() * 400 / perimeter); + } else { + _fe_blur.set_blur_value(0); + } + + //Unblock connections + _blurConnection.unblock(); + _blendConnection.unblock(); + _opacityConnection.unblock(); +} + +/** + * Checks the tree and selects the specified item, optionally scrolling to the item + * @param path Current tree path + * @param iter Current tree item + * @param item Item to select in the tree + * @param scrollto Whether to scroll to the item + * @return Whether to continue searching the tree + */ +bool ObjectsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto) +{ + bool stopGoing = false; + + Gtk::TreeModel::Row row = *iter; + if ( item == row[_model->_colObject] ) + { + //We found the item! Expand to the path and select it in the tree. + _tree.expand_to_path( path ); + + Glib::RefPtr select = _tree.get_selection(); + + select->select(iter); + if (scrollto) { + //Scroll to the item in the tree + _tree.scroll_to_row(path); + } + + stopGoing = true; + } + + return stopGoing; +} + +/** + * Pushes the current tree selection to the canvas + */ +void ObjectsPanel::_pushTreeSelectionToCurrent() +{ + if ( _desktop && _desktop->currentRoot() ) { + //block connections for selection and compositing values to prevent interference + _selectionChangedConnection.block(); + + //Clear the selection and then iterate over the tree selection, pushing each item to the desktop + _desktop->selection->clear(); + bool setOpacity = true; + _tree.get_selection()->selected_foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_selected_row_callback), &setOpacity)); + //unblock connections + _selectionChangedConnection.unblock(); + + _checkTreeSelection(); + } +} + +/** + * Helper function for pushing the current tree selection to the current desktop + * @param iter Current tree item + * @param setCompositingValues Whether to set the compositing values + * @param blur + */ +void ObjectsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setCompositingValues ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPItem *item = row[_model->_colObject]; + if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) + { + //If the item is not a layer, then select it and set the current layer to its parent (if it's the first item) + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + else + { + //If the item is a layer, set the current layer + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); + } + if (*setCompositingValues) + { + //Only set the compositing values for the first item + _setCompositingValues(item); + *setCompositingValues = false; + } + } +} + +/** + * Handles button sensitivity + */ +void ObjectsPanel::_checkTreeSelection() +{ + bool sensitive = _tree.get_selection()->count_selected_rows() > 0; + //TODO: top/bottom sensitivity + bool sensitiveNonTop = true; + bool sensitiveNonBottom = true; + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( sensitive ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonTop ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonBottom ); + } +} + +/** + * Sets visibility of items in the tree + * @param iter Current item in the tree + * @param visible Whether the item should be visible or not + */ +void ObjectsPanel::_setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + item->setHidden( !visible ); + row[_model->_colVisible] = visible; + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Sets sensitivity of items in the tree + * @param iter Current item in the tree + * @param locked Whether the item should be locked + */ +void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + item->setLocked( locked ); + row[_model->_colLocked] = locked; + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Handles keyboard events + * @param event Keyboard event passed in from GDK + * @return Whether the event should be eaten (om nom nom) + */ +bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) +{ + + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: + { + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter && !_text_renderer->property_editable()) { + //Rename item + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + _text_renderer->property_editable() = true; + _tree.set_cursor(*path, *_name_column, true); + grab_focus(); + return true; + } + } + break; + case GDK_Home: + { + //Move item(s) to top of containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_FRONT ); + } + return true; + } + case GDK_End: + { + //Move item(s) to bottom of containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_BACK ); + } + return true; + } + case GDK_KEY_Page_Up: + { + //Move item(s) up in containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + else + { + if (event->state & GDK_SHIFT_MASK) { + _fireAction( SP_VERB_LAYER_MOVE_TO_NEXT ); + } else { + _fireAction( SP_VERB_SELECTION_RAISE ); + } + } + return true; + } + case GDK_KEY_Page_Down: + { + //Move item(s) down in containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + else + { + if (event->state & GDK_SHIFT_MASK) { + _fireAction( SP_VERB_LAYER_MOVE_TO_PREV ); + } else { + _fireAction( SP_VERB_SELECTION_LOWER ); + } + } + return true; + } + //TODO: Handle Ctrl-A, etc. + } + return false; +} + +/** + * Handles mouse events + * @param event Mouse event from GDK + * @return whether to eat the event (om nom nom) + */ +bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + static bool overVisible = false; + + //Right mouse button was clicked, launch the pop-up menu + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _tree.get_path_at_pos( x, y, path ) ) { + _checkTreeSelection(); + _popupMenu.popup(event->button, event->time); + if (_tree.get_selection()->is_selected(path)) { + return true; + } + } + } + + //Left mouse button was pressed! In order to handle multiple item drag & drop, + //we need to defer selection by setting the select function so that the tree doesn't + //automatically select anything. In order to handle multiple item icon clicking, + //we need to eat the event. There might be a better way to do both of these... + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { + overVisible = false; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(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)) { + //Click on visible column, eat this event to keep row selection + overVisible = true; + return true; + } else if (col == _tree.get_column(COL_LOCKED-1) || + col == _tree.get_column(COL_TYPE-1) || + col == _tree.get_column(COL_INSERTORDER - 1) || + col == _tree.get_column(COL_HIGHLIGHT-1)) { + //Click on an icon column, eat this event to keep row selection + return true; + } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { + //Click on a selected item with no modifiers, defer selection to the mouse-up by + //setting the select function to _noSelection + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_noSelection)); + _defer_target = path; + } + } + } + + //Restore the selection function to allow tree selection on mouse button release + if ( event->type == GDK_BUTTON_RELEASE) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction)); + } + + //CellRenderers do not have good support for dealing with multiple items, so + //we handle all events on them here + if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (_defer_target) { + //We had deferred a selection target, select it here (assuming no drag & drop) + if (_defer_target == path && !(event->x == 0 && event->y == 0)) + { + _tree.set_cursor(path, *col, false); + } + _defer_target = Gtk::TreeModel::Path(); + } + else { + 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; + SPItem *item = row[_model->_colObject]; + if (col == _tree.get_column(COL_VISIBLE - 1)) { + _desktop->toggleLayerSolo( item ); + DocumentUndo::maybeDone(_desktop->doc(), "layer:solo", SP_VERB_LAYER_SOLO, _("Toggle layer solo")); + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + _desktop->toggleLockOtherLayers( item ); + DocumentUndo::maybeDone(_desktop->doc(), "layer:lockothers", SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); + } + } + } else { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPItem* item = row[_model->_colObject]; + + if (col == _tree.get_column(COL_VISIBLE - 1)) { + if (overVisible) { + //Toggle visibility + bool newValue = !row[_model->_colVisible]; + if (_tree.get_selection()->is_selected(path)) + { + //If the current row is selected, toggle the visibility + //for all selected items + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setVisibleIter), newValue)); + } + else + { + //If the current row is not selected, toggle just its visibility + row[_model->_colVisible] = newValue; + item->setHidden(!newValue); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Unhide objects") : _("Hide objects")); + overVisible = false; + } + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + //Toggle locking + bool newValue = !row[_model->_colLocked]; + if (_tree.get_selection()->is_selected(path)) + { + //If the current row is selected, toggle the sensitivity for + //all selected items + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setLockedIter), newValue)); + } + else + { + //If the current row is not selected, toggle just its sensitivity + row[_model->_colLocked] = newValue; + item->setLocked( newValue ); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Lock objects") : _("Unlock objects")); + + } else if (col == _tree.get_column(COL_TYPE - 1)) { + if (SP_IS_GROUP(item)) + { + //Toggle the current item between a group and a layer + SPGroup * g = SP_GROUP(item); + bool newValue = g->layerMode() == SPGroup::LAYER; + row[_model->_colType] = newValue ? 1: 2; + g->setLayerMode(newValue ? SPGroup::GROUP : SPGroup::LAYER); + g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Layer to group") : _("Group to layer")); + } + } else if (col == _tree.get_column(COL_INSERTORDER - 1)) { + if (SP_IS_GROUP(item)) + { + //Toggle the current item's insert order + SPGroup * g = SP_GROUP(item); + bool newValue = !g->insertBottom(); + row[_model->_colInsertOrder] = newValue ? 2: 1; + g->setInsertBottom(newValue); + g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Set insert mode bottom") : _("Set insert mode top")); + } + } else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { + //Clear the highlight targets + _highlight_target.clear(); + if (_tree.get_selection()->is_selected(path)) + { + //If the current item is selected, store all selected items + //in the highlight source + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeHighlightTarget)); + } else { + //If the current item is not selected, store only it in the highlight source + _storeHighlightTarget(iter); + } + if (_colorSelector) + { + //Set up the color selector + SPColor color; + color.set( row[_model->_colHighlight] ); + _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight])); + } + //Show the color selector dialog + _colorSelectorDialog.show(); + } + } + } + } + } + + //Second mouse button press, set double click status for when the mouse is released + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } + + //Double click on mouse button release, if we're over the label column, edit + //the item name + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { + // Double click on the Layer name, enable editing + _text_renderer->property_editable() = true; + _tree.set_cursor (path, *_name_column, true); + grab_focus(); + } + } + + return false; +} + +/** + * Stores items in the highlight target vector to manipulate with the color selector + * @param iter Current tree item to store + */ +void ObjectsPanel::_storeHighlightTarget(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + _highlight_target.push_back(item); + } +} + +/* + * Drap and drop within the tree + */ +bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +{ + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + //Set up our defaults and clear the source vector + _dnd_into = false; + _dnd_target = NULL; + _dnd_source.clear(); + + //Add all selected items to the source vector + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeDragSource)); + + if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _tree.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/4) && cell_y <= (int)(cell_height * 3/4)); + if (cell_y > (int)(cell_height * 3/4)) { + Gtk::TreeModel::Path next_path = target_path; + next_path.next(); + if (_store->iter_is_valid(_store->get_iter(next_path))) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + // Drop into the top level + _dnd_target = NULL; + } + } + } + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + //Set the drop target. If we're not dropping into a group, we cannot + //drop into it, so set _dnd_into false. + _dnd_target = row[_model->_colObject]; + if (!(SP_IS_GROUP(_dnd_target))) _dnd_into = false; + } + } + + _takeAction(DRAGNDROP); + + return false; +} + +/** + * Stores all selected items as the drag source + * @param iter Current tree item + */ +void ObjectsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + _dnd_source.push_back(item); + } +} + +/* + * Move a layer in response to a drag & drop action + */ +void ObjectsPanel::_doTreeMove( ) +{ + g_assert(_desktop != NULL); + g_assert(_document != NULL); + + std::vector idvector; + + //Clear the desktop selection + _desktop->selection->clear(); + while (!_dnd_source.empty()) + { + SPItem *obj = _dnd_source.back(); + _dnd_source.pop_back(); + + if (obj != _dnd_target) { + //Store the object id (for selection later) and move the object + idvector.push_back(g_strdup(obj->getId())); + obj->moveTo(_dnd_target, _dnd_into); + } + } + + //Select items + while (!idvector.empty()) { + //Grab the id from the vector, get the item in the document and select it + gchar * id = idvector.back(); + idvector.pop_back(); + SPObject *obj = _document->getObjectById(id); + g_free(id); + if (obj && SP_IS_ITEM(obj)) { + SPItem *item = SP_ITEM(obj); + if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) + { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + else + { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); + } + } + } + + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Moved objects")); +} + +/** + * Fires the action verb + */ +void ObjectsPanel::_fireAction( unsigned int code ) +{ + if ( _desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(_desktop); + if ( action ) { + sp_action_perform( action, NULL ); + } + } + } +} + +/** + * Executes the given button action during the idle time + */ +void ObjectsPanel::_takeAction( int val ) +{ + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + Glib::signal_timeout().connect( sigc::mem_fun(*this, &ObjectsPanel::_executeAction), 0 ); + } +} + +/** + * Executes the pending button action + */ +bool ObjectsPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _document && _pending) + { + int val = _pending->_actionCode; +// SPObject* target = _pending->_target; + + switch ( val ) { + case BUTTON_NEW: + { + _fireAction( SP_VERB_LAYER_NEW ); + } + break; + case BUTTON_RENAME: + { + _fireAction( SP_VERB_LAYER_RENAME ); + } + break; + case BUTTON_TOP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_FRONT); + } + } + break; + case BUTTON_BOTTOM: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_BACK); + } + } + break; + case BUTTON_UP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + else + { + _fireAction( SP_VERB_SELECTION_RAISE ); + } + } + break; + case BUTTON_DOWN: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + else + { + _fireAction( SP_VERB_SELECTION_LOWER ); + } + } + break; + case BUTTON_DUPLICATE: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_DUPLICATE ); + } + else + { + _fireAction( SP_VERB_EDIT_DUPLICATE ); + } + } + break; + case BUTTON_DELETE: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_DELETE ); + } + else + { + _fireAction( SP_VERB_EDIT_DELETE ); + } + } + break; + case BUTTON_SOLO: + { + _fireAction( SP_VERB_LAYER_SOLO ); + } + break; + case BUTTON_SHOW_ALL: + { + _fireAction( SP_VERB_LAYER_SHOW_ALL ); + } + break; + case BUTTON_HIDE_ALL: + { + _fireAction( SP_VERB_LAYER_HIDE_ALL ); + } + break; + case BUTTON_LOCK_OTHERS: + { + _fireAction( SP_VERB_LAYER_LOCK_OTHERS ); + } + break; + case BUTTON_LOCK_ALL: + { + _fireAction( SP_VERB_LAYER_LOCK_ALL ); + } + break; + case BUTTON_UNLOCK_ALL: + { + _fireAction( SP_VERB_LAYER_UNLOCK_ALL ); + } + break; + case BUTTON_SETCLIP: + { + _fireAction( SP_VERB_OBJECT_SET_CLIPPATH ); + } + break; + case BUTTON_UNSETCLIP: + { + _fireAction( SP_VERB_OBJECT_UNSET_CLIPPATH ); + } + break; + case BUTTON_SETMASK: + { + _fireAction( SP_VERB_OBJECT_SET_MASK ); + } + break; + case BUTTON_UNSETMASK: + { + _fireAction( SP_VERB_OBJECT_UNSET_MASK ); + } + break; + case BUTTON_GROUP: + { + _fireAction( SP_VERB_SELECTION_GROUP ); + } + break; + case BUTTON_UNGROUP: + { + _fireAction( SP_VERB_SELECTION_UNGROUP ); + } + break; + case BUTTON_COLLAPSE_ALL: + { + for (SPObject* obj = _document->getRoot()->firstChild(); obj != NULL; obj = obj->next) { + if (SP_IS_GROUP(obj)) { + _setCollapsed(SP_GROUP(obj)); + } + } + _objectsChanged(_document->getRoot()); + } + break; + case DRAGNDROP: + { + _doTreeMove( ); + } + break; + } + + delete _pending; + _pending = 0; + } + + return false; +} + +/** + * Handles an unsuccessful item label edit (escape pressed, etc.) + */ +void ObjectsPanel::_handleEditingCancelled() +{ + _text_renderer->property_editable() = false; +} + +/** + * Handle a successful item label edit + * @param path Tree path of the item currently being edited + * @param new_text New label text + */ +void ObjectsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_renderer->property_editable() = false; +} + +/** + * Renames an item in the tree + * @param row Tree row + * @param name New label to give to the item + */ +void ObjectsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && _desktop) { + SPItem* item = row[_model->_colObject]; + if ( item ) { + gchar const* oldLabel = item->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + item->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } + } +} + +/** + * A row selection function used by the tree that doesn't allow any new items to be selected. + * Currently, this is used to allow multi-item drag & drop. + */ +bool ObjectsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ ) +{ + return false; +} + +/** + * Default row selection function taken from the layers dialog + */ +bool ObjectsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + bool val = true; + if ( !currentlySelected && _toggleEvent ) + { + GdkEvent* event = gtk_get_current_event(); + if ( event ) { + // (keep these checks separate, so we know when to call gdk_event_free() + if ( event->type == GDK_BUTTON_PRESS ) { + GdkEventButton const* target = reinterpret_cast(_toggleEvent); + GdkEventButton const* evtb = reinterpret_cast(event); + + if ( (evtb->window == target->window) + && (evtb->send_event == target->send_event) + && (evtb->time == target->time) + && (evtb->state == target->state) + ) + { + // Ooooh! It's a magic one + val = false; + } + } + gdk_event_free(event); + } + } + return val; +} + +/** + * Sets a group to be collapsed and recursively collapses its children + * @param group The group to collapse + */ +void ObjectsPanel::_setCollapsed(SPGroup * group) +{ + group->setExpanded(false); + group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + for (SPObject *iter = group->children; iter != NULL; iter = iter->next) + { + if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + } +} + +/** + * Sets a group to be expanded or collapsed + * @param iter Current tree item + * @param isexpanded Whether to expand or collapse + */ +void ObjectsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; + + SPItem* item = row[_model->_colObject]; + if (item && SP_IS_GROUP(item)) + { + if (isexpanded) + { + //If we're expanding, simply perform the expansion + SP_GROUP(item)->setExpanded(isexpanded); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + else + { + //If we're collapsing, we need to recursively collapse, so call our helper function + _setCollapsed(SP_GROUP(item)); + } + } +} + +/** + * Callback for when the highlight color is changed + * @param csel Color selector + * @param cp Objects panel + */ +void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) +{ + SPColor color; + float alpha = 0; + csel->base->getColorAlpha(color, alpha); + guint32 rgba = color.toRGBA32( alpha ); + + ObjectsPanel *ptr = reinterpret_cast(cp); + + //Set the highlight color for all items in the _highlight_target (all selected items) + for (std::vector::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter) + { + SPItem * target = *iter; + target->setHighlightColor(rgba); + target->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); +} + +/** + * Callback for when the opacity value is changed + */ +void ObjectsPanel::_opacityValueChanged() +{ + _blockCompositeUpdate = true; + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_opacityChangedIter)); + DocumentUndo::maybeDone(_document, "opacity", SP_VERB_DIALOG_OBJECTS, _("Set object opacity")); + _blockCompositeUpdate = false; +} + +/** + * Change the opacity of the selected items in the tree + * @param iter Current tree item + */ +void ObjectsPanel::_opacityChangedIter(const Gtk::TreeIter& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + item->style->opacity.set = TRUE; + item->style->opacity.value = SP_SCALE24_FROM_FLOAT(_opacity_adjustment.get_value() / _opacity_adjustment.get_upper()); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Callback for when the blend mode is changed + */ +void ObjectsPanel::_blendValueChanged() +{ + _blockCompositeUpdate = true; + const Glib::ustring blendmode = _fe_cb.get_blend_mode(); + + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blendChangedIter), blendmode)); + DocumentUndo::done(_document, SP_VERB_DIALOG_OBJECTS, _("Set object blend mode")); + _blockCompositeUpdate = false; +} + +/** + * Sets the blend mode of the selected tree items + * @param iter Current tree item + * @param blendmode Blend mode to set + */ +void ObjectsPanel::_blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + //Since blur and blend are both filters, we need to set both at the same time + SPStyle *style = item->style; + g_assert(style != NULL); + + if (blendmode != "normal") { + gdouble radius = 0; + if (item->style->getFilter()) { + for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { + if (SP_IS_GAUSSIANBLUR(primitive)) { + Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); + if (bbox) { + radius = SP_GAUSSIANBLUR(primitive)->stdDeviation.getNumber(); + } + } + } + } + SPFilter *filter = new_filter_simple_from_item(_document, item, blendmode.c_str(), radius); + sp_style_set_property_url(item, "filter", filter, false); + } else { + for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { + if (SP_IS_FEBLEND(primitive)) { + primitive->deleteObject(); + break; + } + } + if (!item->style->getFilter()->children) { + remove_filter(item, false); + } + } + + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Callback for when the blur value has changed + */ +void ObjectsPanel::_blurValueChanged() +{ + _blockCompositeUpdate = true; + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blurChangedIter), _fe_blur.get_blur_value())); + DocumentUndo::maybeDone(_document, "blur", SP_VERB_DIALOG_OBJECTS, _("Set object blur")); + _blockCompositeUpdate = false; +} + +/** + * Sets the blur value for the selected items in the tree + * @param iter Current tree item + * @param blur Blur value to set + */ +void ObjectsPanel::_blurChangedIter(const Gtk::TreeIter& iter, double blur) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + //Since blur and blend are both filters, we need to set both at the same time + SPStyle *style = item->style; + if (style) { + Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); + double radius; + if (bbox) { + double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? + radius = blur * perimeter / 400; + } else { + radius = 0; + } + + if (radius != 0) { + SPFilter *filter = modify_filter_gaussian_blur_from_item(_document, item, radius); + sp_style_set_property_url(item, "filter", filter, false); + } else if (item->style->filter.set && item->style->getFilter()) { + for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { + if (SP_IS_GAUSSIANBLUR(primitive)) { + primitive->deleteObject(); + break; + } + } + if (!item->style->getFilter()->children) { + remove_filter(item, false); + } + } + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + } +} + +/** + * Constructor + */ +ObjectsPanel::ObjectsPanel() : + UI::Widget::Panel("", "/dialogs/objects", SP_VERB_DIALOG_OBJECTS), + _rootWatcher(0), + _deskTrack(), + _desktop(0), + _document(0), + _model(0), + _pending(0), + _toggleEvent(0), + _defer_target(), + _composite_vbox(false, 0), + _opacity_vbox(false, 0), + _opacity_label(_("Opacity:")), + _opacity_label_unit(_("%")), +#if WITH_GTKMM_3_0 + _opacity_adjustment(Gtk::Adjustment::create(100.0, 0.0, 100.0, 1.0, 1.0, 0.0)), +#else + _opacity_adjustment(100.0, 0.0, 100.0, 1.0, 1.0, 0.0), +#endif + _opacity_hscale(_opacity_adjustment), + _opacity_spin_button(_opacity_adjustment, 0.01, 1), + _fe_cb(UI::Widget::SimpleFilterModifier::BLEND), + _fe_vbox(false, 0), + _fe_alignment(1, 1, 1, 1), + _fe_blur(UI::Widget::SimpleFilterModifier::BLUR), + _blur_vbox(false, 0), + _blur_alignment(1, 1, 1, 1), + _colorSelectorDialog("dialogs.colorpickerwindow") +{ + //Create the tree model and store + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + //Set up the tree + _tree.set_model( _store ); + _tree.set_headers_visible(false); + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + //Create the column CellRenderers + //Visible + Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( + INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); + int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1; + eyeRenderer->property_activatable() = true; + Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum); + if ( col ) { + col->add_attribute( eyeRenderer->property_active(), _model->_colVisible ); + } + + //Locked + Inkscape::UI::Widget::ImageToggler * renderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( + INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) ); + int lockedColNum = _tree.append_column("lock", *renderer) - 1; + renderer->property_activatable() = true; + col = _tree.get_column(lockedColNum); + if ( col ) { + col->add_attribute( renderer->property_active(), _model->_colLocked ); + } + + //Type + Inkscape::UI::Widget::LayerTypeIcon * typeRenderer = Gtk::manage( new Inkscape::UI::Widget::LayerTypeIcon()); + int typeColNum = _tree.append_column("type", *typeRenderer) - 1; + typeRenderer->property_activatable() = true; + col = _tree.get_column(typeColNum); + if ( col ) { + col->add_attribute( typeRenderer->property_active(), _model->_colType ); + } + + //Insert order + Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon()); + int insertColNum = _tree.append_column("type", *insertRenderer) - 1; + col = _tree.get_column(insertColNum); + if ( col ) { + col->add_attribute( insertRenderer->property_active(), _model->_colInsertOrder ); + } + + //Clip/mask + Inkscape::UI::Widget::ClipMaskIcon * clipRenderer = Gtk::manage( new Inkscape::UI::Widget::ClipMaskIcon()); + int clipColNum = _tree.append_column("clipmask", *clipRenderer) - 1; + col = _tree.get_column(clipColNum); + if ( col ) { + col->add_attribute( clipRenderer->property_active(), _model->_colClipMask ); + } + + //Highlight + Inkscape::UI::Widget::HighlightPicker * highlightRenderer = Gtk::manage( new Inkscape::UI::Widget::HighlightPicker()); + int highlightColNum = _tree.append_column("highlight", *highlightRenderer) - 1; + col = _tree.get_column(highlightColNum); + if ( col ) { + col->add_attribute( highlightRenderer->property_active(), _model->_colHighlight ); + } + + //Label + _text_renderer = Gtk::manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + //Set the expander and search columns + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + _tree.set_search_column(_model->_colLabel); + + //Set up the tree selection + _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &ObjectsPanel::_pushTreeSelectionToCurrent) ); + _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction) ); + + //Set up tree signals + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleKeyEvent), false ); + _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleDragDrop), false); + _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), false)); + _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), true)); + + //Set up the label editing signals + _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEdited) ); + _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEditingCancelled) ); + + //Set up the scroller window and pack the page + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + _scroller.get_preferred_size(sreq_natural, sreq); +#else + sreq = _scroller.size_request(); +#endif + int minHeight = 70; + if (sreq.height < minHeight) { + // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar + _scroller.set_size_request(sreq.width, minHeight); + } + + _page.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); + + //Set up the compositing items + //Blend mode filter effect + _composite_vbox.pack_start(_fe_vbox, false, false, 2); + _fe_alignment.set_padding(0, 0, 4, 0); + _fe_alignment.add(_fe_cb); + _fe_vbox.pack_start(_fe_alignment, false, false, 0); + _blendConnection = _fe_cb.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blendValueChanged)); + + //Blur filter effect + _composite_vbox.pack_start(_blur_vbox, false, false, 2); + _blur_alignment.set_padding(0, 0, 4, 0); + _blur_alignment.add(_fe_blur); + _blur_vbox.pack_start(_blur_alignment, false, false, 0); + _blurConnection = _fe_blur.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blurValueChanged)); + + //Opacity + _composite_vbox.pack_start(_opacity_vbox, false, false, 2); + _opacity_label.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER); + _opacity_hbox.pack_start(_opacity_label, false, false, 3); + _opacity_vbox.pack_start(_opacity_hbox, false, false, 0); + _opacity_hbox.pack_start(_opacity_hscale, true, true, 0); + _opacity_hbox.pack_start(_opacity_spin_button, false, false, 0); + _opacity_hbox.pack_start(_opacity_label_unit, false, false, 3); + _opacity_hscale.set_draw_value(false); +#if WITH_GTKMM_3_0 + _opacityConnection = _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); + _opacity_label.set_mnemonic_widget(_opacity_hscale); +#else + _opacityConnection = _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_opacityValueChanged)); + _opacity_label.set_mnemonic_widget(_opacity_hscale); +#endif + + //Keep the labels aligned + GtkSizeGroup *labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget(labels, GTK_WIDGET(_opacity_label.gobj())); + gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_cb.get_blur_label()->gobj())); + gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_blur.get_blur_label()->gobj())); + + //Pack the compositing functions and the button row + _page.pack_end(_composite_vbox, Gtk::PACK_SHRINK); + _page.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + + //Pack into the panel contents + _getContents()->pack_start(_page, Gtk::PACK_EXPAND_WIDGET); + + SPDesktop* targetDesktop = getDesktop(); + + //Set up the button row + Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_ADD, _("New Layer") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_REMOVE, _("Remove") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) ); + _watching.push_back( btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GOTO_BOTTOM, _("Move To Bottom") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GO_DOWN, _("Move Down") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GO_UP, _("Move Up") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) ); + _watchingNonTop.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GOTO_TOP, _("Move To Top") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) ); + _watchingNonTop.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_UNINDENT, _("Collapse All") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); + + _watching.push_back(&_composite_vbox); + + //Set up the pop-up menu + // ------------------------------------------------------- + { + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_EDIT_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SOLO, 0, "Solo", (int)BUTTON_SOLO ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SHOW_ALL, 0, "Show All", (int)BUTTON_SHOW_ALL ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_HIDE_ALL, 0, "Hide All", (int)BUTTON_HIDE_ALL ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_OTHERS, 0, "Lock Others", (int)BUTTON_LOCK_OTHERS ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_ALL, 0, "Lock All", (int)BUTTON_LOCK_ALL ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_UNLOCK_ALL, 0, "Unlock All", (int)BUTTON_UNLOCK_ALL ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_RAISE, GTK_STOCK_GO_UP, "Up", (int)BUTTON_UP ) ); + _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_LOWER, GTK_STOCK_GO_DOWN, "Down", (int)BUTTON_DOWN ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_GROUP, 0, "Group", (int)BUTTON_GROUP ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_UNGROUP, 0, "Ungroup", (int)BUTTON_UNGROUP ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_CLIPPATH, 0, "Set Clip", (int)BUTTON_SETCLIP ) ); + //not implemented + //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) ); + + //will never be implemented + //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_INVERSE_CLIPPATH, 0, "Set Inverse Clip", (int)BUTTON_SETINVCLIP ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_CLIPPATH, 0, "Unset Clip", (int)BUTTON_UNSETCLIP ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_MASK, 0, "Set Mask", (int)BUTTON_SETMASK ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_MASK, 0, "Unset Mask", (int)BUTTON_UNSETMASK ) ); + + _popupMenu.show_all_children(); + } + // ------------------------------------------------------- + + //Set initial sensitivity of buttons + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( false ); + } + + //Set up the color selection dialog + GtkWidget *dlg = GTK_WIDGET(_colorSelectorDialog.gobj()); + sp_transientize(dlg); + + _colorSelectorDialog.hide(); + _colorSelectorDialog.set_title (_("Select Highlight Color")); + _colorSelectorDialog.set_border_width (4); + _colorSelectorDialog.property_modal() = true; + _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); + _colorSelectorDialog.get_vbox()->pack_start ( + *Glib::wrap(&_colorSelector->vbox), true, true, 0); + + g_signal_connect(G_OBJECT(_colorSelector), "dragged", + G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + g_signal_connect(G_OBJECT(_colorSelector), "released", + G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + g_signal_connect(G_OBJECT(_colorSelector), "changed", + G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + + gtk_widget_show(GTK_WIDGET(_colorSelector)); + + setDesktop( targetDesktop ); + + show_all_children(); + + //Connect the desktop changed connection + desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectsPanel::setDesktop) ); + _deskTrack.connect(GTK_WIDGET(gobj())); +} + +/** + * Destructor + */ +ObjectsPanel::~ObjectsPanel() +{ + //Close the highlight selection dialog + _colorSelectorDialog.hide(); + _colorSelector = NULL; + + //Set the desktop to null, which will disconnect all object watchers + setDesktop(NULL); + + if ( _model ) + { + delete _model; + _model = 0; + } + + if (_pending) { + delete _pending; + _pending = 0; + } + + if ( _toggleEvent ) + { + gdk_event_free( _toggleEvent ); + _toggleEvent = 0; + } + + desktopChangeConn.disconnect(); + _deskTrack.disconnect(); +} + +/** + * Sets the current document + */ +void ObjectsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) +{ + //Clear all object watchers + while (!_objectWatchers.empty()) + { + ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + //Delete the root watcher + if (_rootWatcher) + { + _rootWatcher->_repr->removeObserver(*_rootWatcher); + delete _rootWatcher; + _rootWatcher = NULL; + } + + _document = document; + + if (document && document->getRoot() && document->getRoot()->getRepr()) + { + //Create a new root watcher for the document and then call _objectsChanged to fill the tree + _rootWatcher = new ObjectsPanel::ObjectWatcher(this, document->getRoot()); + document->getRoot()->getRepr()->addObserver(*_rootWatcher); + _objectsChanged(document->getRoot()); + } +} + +/** + * Set the current panel desktop + */ +void ObjectsPanel::setDesktop( SPDesktop* desktop ) +{ + Panel::setDesktop(desktop); + + if ( desktop != _desktop ) { + _documentChangedConnection.disconnect(); + _selectionChangedConnection.disconnect(); + if ( _desktop ) { + _desktop = 0; + } + + _desktop = Panel::getDesktop(); + if ( _desktop ) { + //Connect desktop signals + _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &ObjectsPanel::setDocument)); + _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &ObjectsPanel::_objectsSelected)); + + setDocument(_desktop, _desktop->doc()); + } else { + setDocument(NULL, NULL); + } + } + _deskTrack.setBase(desktop); +} +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h new file mode 100644 index 000000000..7b07afd63 --- /dev/null +++ b/src/ui/dialog/objects.h @@ -0,0 +1,255 @@ +/* + * A simple dialog for objects UI. + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_OBJECTS_PANEL_H +#define SEEN_OBJECTS_PANEL_H + +#include +#include +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/panel.h" +#include "ui/widget/object-composite-settings.h" +#include "desktop-tracker.h" +#include "ui/widget/style-subject.h" +#include "selection.h" +#include "ui/widget/filter-effect-chooser.h" + +class SPObject; +class SPGroup; +struct SPColorSelector; + +namespace Inkscape { + +namespace UI { +namespace Dialog { + + +/** + * A panel that displays objects. + */ +class ObjectsPanel : public UI::Widget::Panel +{ +public: + ObjectsPanel(); + virtual ~ObjectsPanel(); + + static ObjectsPanel& getInstance(); + + void setDesktop( SPDesktop* desktop ); + void setDocument( SPDesktop* desktop, SPDocument* document); + +private: + //Internal Classes: + class ModelColumns; + class InternalUIBounce; + class ObjectWatcher; + + //Connections, Watchers, Trackers: + + //Document root watcher + ObjectsPanel::ObjectWatcher* _rootWatcher; + + //All object watchers + std::vector _objectWatchers; + + //Connection for when the desktop changes + sigc::connection desktopChangeConn; + + //Connection for when the document changes + sigc::connection _documentChangedConnection; + + //Connection for when the active selection in the document changes + sigc::connection _selectionChangedConnection; + + //Connection for when the selection in the dialog changes + sigc::connection _selectedConnection; + + //Connections for when the opacity/blend/blur of the active selection in the document changes + sigc::connection _opacityConnection; + sigc::connection _blendConnection; + sigc::connection _blurConnection; + + //Desktop tracker for grabbing the desktop changed connection + DesktopTracker _deskTrack; + + //Members: + + //The current desktop + SPDesktop* _desktop; + + //The current document + SPDocument* _document; + + //Tree data model + ModelColumns* _model; + + //Prevents the composite controls from updating + bool _blockCompositeUpdate; + + // + InternalUIBounce* _pending; + + //Whether the drag & drop was dragged into an item + gboolean _dnd_into; + + //List of drag & drop source items + std::vector _dnd_source; + + //Drag & drop target item + SPItem* _dnd_target; + + //List of items to change the highlight on + std::vector _highlight_target; + + //GUI Members: + + GdkEvent* _toggleEvent; + + Gtk::TreeModel::Path _defer_target; + + Glib::RefPtr _store; + std::vector _watching; + std::vector _watchingNonTop; + std::vector _watchingNonBottom; + + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::TreeView::Column *_name_column; +#if WITH_GTKMM_3_0 + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; +#else + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; +#endif + Gtk::ScrolledWindow _scroller; + Gtk::Menu _popupMenu; + Inkscape::UI::Widget::SpinButton _spinBtn; + Gtk::VBox _page; + + /* Composite Settings */ + Gtk::VBox _composite_vbox; + Gtk::VBox _opacity_vbox; + Gtk::HBox _opacity_hbox; + Gtk::Label _opacity_label; + Gtk::Label _opacity_label_unit; +#if WITH_GTKMM_3_0 + Glib::RefPtr _opacity_adjustment; +#else + Gtk::Adjustment _opacity_adjustment; +#endif + Gtk::HScale _opacity_hscale; + Inkscape::UI::Widget::SpinButton _opacity_spin_button; + + Inkscape::UI::Widget::SimpleFilterModifier _fe_cb; + Gtk::VBox _fe_vbox; + Gtk::Alignment _fe_alignment; + Inkscape::UI::Widget::SimpleFilterModifier _fe_blur; + Gtk::VBox _blur_vbox; + Gtk::Alignment _blur_alignment; + + Gtk::Dialog _colorSelectorDialog; + SPColorSelector *_colorSelector; + + + //Methods: + + ObjectsPanel(ObjectsPanel const &); // no copy + ObjectsPanel &operator=(ObjectsPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ); + void _fireAction( unsigned int code ); + + Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); + + void _setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ); + void _setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _storeHighlightTarget(const Gtk::TreeModel::iterator& iter); + void _storeDragSource(const Gtk::TreeModel::iterator& iter); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + + void _doTreeMove(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _pushTreeSelectionToCurrent(); + void _selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setOpacity ); + + void _checkTreeSelection(); + + void _takeAction( int val ); + bool _executeAction(); + + void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); + void _setCollapsed(SPGroup * group); + + bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + + void _compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ); + void _updateComposite(); + void _setCompositingValues(SPItem *item); + + void _updateObject(SPObject *obj, bool recurse); + bool _checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj); + + void _objectsSelected(Selection *sel); + bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto); + + void _objectsChanged(SPObject *obj); + void _addObject( SPObject* obj, Gtk::TreeModel::Row* parentRow ); + + void _opacityChangedIter(const Gtk::TreeIter& iter); + void _opacityValueChanged(); + + void _blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode); + void _blendValueChanged(); + + void _blurChangedIter(const Gtk::TreeIter& iter, double blur); + void _blurValueChanged(); + + + void setupDialog(const Glib::ustring &title); + + friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); + +}; + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_OBJECTS_PANEL_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp new file mode 100644 index 000000000..f994b571f --- /dev/null +++ b/src/ui/dialog/tags.cpp @@ -0,0 +1,1182 @@ +/* + * A simple panel for tags + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "tags.h" +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" +#include "inkscape.h" +#include "layer-fns.h" +#include "layer-manager.h" +#include "preferences.h" +#include "sp-item.h" +#include "sp-object.h" +#include "sp-shape.h" +#include "svg/css-ostringstream.h" +#include "ui/icon-names.h" +#include "ui/widget/layertypeicon.h" +#include "ui/widget/addtoicon.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/node.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-root.h" +#include "event-context.h" +#include "selection.h" +#include "dialogs/dialog-events.h" +#include "widgets/sp-color-notebook.h" +#include "style.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-tag.h" +#include "sp-defs.h" +#include "sp-tag-use.h" +#include "sp-tag-use-reference.h" + +//#define DUMP_LAYERS 1 + +namespace Inkscape { +namespace UI { +namespace Dialog { + +using Inkscape::XML::Node; + +TagsPanel& TagsPanel::getInstance() +{ + return *new TagsPanel(); +} + +enum { + COL_ADD = 1 +}; + +enum { + BUTTON_NEW = 0, + BUTTON_TOP, + BUTTON_BOTTOM, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_DELETE, + DRAGNDROP +}; + +class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { +public: + ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) : + _pnl(pnl), + _obj(obj), + _repr(repr), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + ObjectWatcher(TagsPanel* pnl, SPObject* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if ( _pnl && _obj ) { + if ( name == _labelAttr ) { + _pnl->_updateObject( _obj); + } + } + } + + TagsPanel* _pnl; + SPObject* _obj; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; +}; + +class TagsPanel::InternalUIBounce +{ +public: + int _actionCode; +}; + +void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) +{ + bool set = false; + + if ( iconName ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + set = true; + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !set && action && action->image ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + set = true; + } + } + } + + btn.set_tooltip_text (tooltip); +} + + +Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) +{ + GtkWidget* iconWidget = 0; + const char* label = 0; + + if ( iconName ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !iconWidget && action && action->image ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); + } + + if ( action ) { + label = action->name; + } + } + } + + if ( !label && fallback ) { + label = fallback; + } + + Gtk::Widget* wrapped = 0; + if ( iconWidget ) { + wrapped = manage(Glib::wrap(iconWidget)); + wrapped->show(); + } + + + Gtk::MenuItem* item = 0; + + if (wrapped) { + item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); + } else { + item = Gtk::manage(new Gtk::MenuItem(label, true)); + } + + item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id)); + _popupMenu.append(*item); + + return *item; +} + +void TagsPanel::_fireAction( unsigned int code ) +{ + if ( _desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(_desktop); + if ( action ) { + sp_action_perform( action, NULL ); + } + } + } +} + +void TagsPanel::_takeAction( int val ) +{ + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 ); + } +} + +bool TagsPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _pending) + { + int val = _pending->_actionCode; +// SPObject* target = _pending->_target; + + switch ( val ) { + case BUTTON_NEW: + { + _fireAction( SP_VERB_TAG_NEW ); + } + break; + case BUTTON_TOP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_FRONT); + } + } + break; + case BUTTON_BOTTOM: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_BACK); + } + } + break; + case BUTTON_UP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + else + { + _fireAction( SP_VERB_SELECTION_RAISE ); + } + } + break; + case BUTTON_DOWN: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + else + { + _fireAction( SP_VERB_SELECTION_LOWER ); + } + } + break; + case BUTTON_DELETE: + { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); + } + break; + case DRAGNDROP: + { + _doTreeMove( ); + } + break; + } + + delete _pending; + _pending = 0; + } + + return false; +} + + +class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colParentObject); + add(_colObject); + add(_colLabel); + add(_colAddRemove); + add(_colAllowAddRemove); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colParentObject; + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colAddRemove; + Gtk::TreeModelColumn _colAllowAddRemove; +}; + +void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete) +{ + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && obj->parent) { + todelete->push_back(obj); + } +} + +void TagsPanel::_updateObject( SPObject *obj ) { + _store->foreach( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) ); +} + +bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + if ( obj == row[_model->_colObject] ) + { + /* + * We get notified of layer update here (from layer->setLabel()) before layer->label() is set + * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which + * has the correct value (bug #168351) + */ + //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId(); + gchar const *label; + SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0; + if (use && use->ref->isAttached()) { + label = use->ref->getObject()->getAttribute("inkscape:label"); + } else { + label = obj->getAttribute("inkscape:label"); + } + row[_model->_colLabel] = label ? label : obj->getId(); + row[_model->_colAddRemove] = SP_IS_TAG(obj); + } + + return false; +} + +void TagsPanel::_objectsSelected( Selection *sel ) { + + _selectedConnection.block(); + _tree.get_selection()->unselect_all(); + for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next) + { + SPObject *obj = reinterpret_cast(iter->data); + _store->foreach(sigc::bind( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); + } + _selectedConnection.unblock(); + _checkTreeSelection(); +} + +bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + SPObject * it = row[_model->_colObject]; + if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj ) + { + Glib::RefPtr select = _tree.get_selection(); + + select->select(iter); + } + return false; +} + +void TagsPanel::_objectsChanged(SPObject* root) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_desktop) { + SPDocument* document = _desktop->doc(); + SPDefs* root = document->getDefs(); + if ( root ) { + _selectedConnection.block(); + _store->clear(); + _addObject( document, root, 0 ); + _selectedConnection.unblock(); + _objectsSelected(_desktop->selection); + _checkTreeSelection(); + } + } +} + +void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) +{ + if ( _desktop && obj ) { + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG(child)) + { + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = child->label() ? child->label() : child->getId(); + row[_model->_colAddRemove] = true; + row[_model->_colAllowAddRemove] = true; + + _tree.expand_to_path( _store->get_path(iter) ); + + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); + child->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + _addObject( doc, child, &row ); + } + } + if (SP_IS_TAG(obj) && obj->children) + { + Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row rowitems = *iteritems; + rowitems[_model->_colObject] = NULL; + rowitems[_model->_colParentObject] = obj; + rowitems[_model->_colLabel] = _("Items"); + rowitems[_model->_colAddRemove] = false; + rowitems[_model->_colAllowAddRemove] = false; + + _tree.expand_to_path( _store->get_path(iteritems) ); + + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child)) + { + SPItem *item = SP_TAG_USE(child)->ref->getObject(); + Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; + row[_model->_colAddRemove] = false; + row[_model->_colAllowAddRemove] = true; + + if (SP_TAG(obj)->expanded()) { + _tree.expand_to_path( _store->get_path(iter) ); + } + + if (item) { + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); + item->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + } + } + } + } + } +} + +void TagsPanel::_select_tag( SPTag * tag ) +{ + for (SPObject * child = tag->children; child != NULL; child = child->next) + { + if (SP_IS_TAG(child)) { + _select_tag(SP_TAG(child)); + } else if (SP_IS_TAG_USE(child)) { + SPObject * obj = SP_TAG_USE(child)->ref->getObject(); + if (obj) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); + _desktop->selection->add(obj); + } + } + } +} + +void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _select_tag(SP_TAG(obj)); + } else if (SP_IS_TAG_USE(obj)) { + SPObject * item = SP_TAG_USE(obj)->ref->getObject(); + if (item) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + } + } + } +} + +void TagsPanel::_pushTreeSelectionToCurrent() +{ + _selectionChangedConnection.block(); + // TODO hunt down the possible API abuse in getting NULL + if ( _desktop && _desktop->currentRoot() ) { + _desktop->selection->clear(); + _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback)); + } + _selectionChangedConnection.unblock(); + + _checkTreeSelection(); +} + +void TagsPanel::_checkTreeSelection() +{ + bool sensitive = _tree.get_selection()->count_selected_rows() > 0; + bool sensitiveNonTop = true; + bool sensitiveNonBottom = true; +// if ( _tree.get_selection()->count_selected_rows() > 0 ) { +// sensitive = true; +// +// SPObject* inTree = _selectedLayer(); +// if ( inTree ) { +// +// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0); +// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); +// +// } +// } + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( sensitive ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonTop ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonBottom ); + } +} + +bool TagsPanel::_handleKeyEvent(GdkEventKey *event) +{ + + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter && !_text_renderer->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && SP_IS_TAG(obj)) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_renderer->property_editable() = true; + _tree.set_cursor(*path, *_name_column, true); + grab_focus(); + return true; + } + } + } + case GDK_KEY_Delete: { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); + } + return true; + } + break; + } + return false; +} + +bool TagsPanel::_handleButtonEvent(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + // TODO - fix to a better is-popup function + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _tree.get_path_at_pos( x, y, path ) ) { + _checkTreeSelection(); + _popupMenu.popup(event->button, event->time); + if (_tree.get_selection()->is_selected(path)) { + return true; + } + } + } + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { + // 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(event->x); + int y = static_cast(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_ADD-1)) { + down_at_add = true; + return true; + } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection)); + _defer_target = path; + } else { + down_at_add = false; + } + } else { + down_at_add = false; + } + } + + if ( event->type == GDK_BUTTON_RELEASE) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction)); + } + + // 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)) { + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (_defer_target) { + if (_defer_target == path && !(event->x == 0 && event->y == 0)) + { + _tree.set_cursor(path, *col, false); + } + _defer_target = Gtk::TreeModel::Path(); + } else { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + + if (obj) { + if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { + if (SP_IS_TAG(obj)) { + bool wasadded = false; + for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next) + { + SPObject *newobj = reinterpret_cast(iter->data); + bool addchild = true; + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { + addchild = false; + } + } + if (addchild) { + Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref"); + clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false); + obj->appendChild(clone); + wasadded = true; + } + } + if (wasadded) { + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to tag")); + } + } else { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * tobj = *iter; + if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { + tobj->parent->getRepr()->removeChild(tobj->getRepr()); + } + } + } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); + } + } + } + } + } + } + + + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } + + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) { + // Double click on the Layer name, enable editing + _text_renderer->property_editable() = true; + _tree.set_cursor (path, *_name_column, true); + grab_focus(); + } + } + } + + return false; +} + +void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPObject* obj = row[_model->_colObject]; + SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0; + if (item) + { + _dnd_source.push_back(item); + } +} + +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +{ + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + _dnd_into = true; + _dnd_target = _document->getDefs(); + _dnd_source.clear(); + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource)); + + if (_dnd_source.empty()) { + return true; + } + + if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _tree.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y > (int)(cell_height * 2/3)) { + Gtk::TreeModel::Path next_path = target_path; + next_path.next(); + if (_store->iter_is_valid(_store->get_iter(next_path))) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + // Drop into the top level + _dnd_target = _document->getDefs(); + _dnd_into = true; + } + } + } + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + SPObject *pobj = row[_model->_colParentObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _dnd_target = SP_TAG(obj); + } else if (SP_IS_TAG(obj->parent)) { + _dnd_target = SP_TAG(obj->parent); + _dnd_into = true; + } + } else if (pobj && SP_IS_TAG(pobj)) { + _dnd_target = SP_TAG(pobj); + _dnd_into = true; + } else { + return true; + } + } + } + + _takeAction(DRAGNDROP); + + return false; +} + +/* + * Move a layer in response to a drag & drop action + */ +void TagsPanel::_doTreeMove( ) +{ + if (_dnd_target) { + for (std::vector::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter) + { + SPTag *src = *iter; + if (src != _dnd_target) { + src->moveTo(_dnd_target, _dnd_into); + } + } + _desktop->selection->clear(); + while (!_dnd_source.empty()) + { + SPTag *src = _dnd_source.back(); + _select_tag(src); + _dnd_source.pop_back(); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS, + _("Moved tags")); + } +} + + +void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_renderer->property_editable() = false; +} + +void TagsPanel::_handleEditingCancelled() +{ + _text_renderer->property_editable() = false; +} + +void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && _desktop) { + SPObject* obj = row[_model->_colObject]; + if ( obj ) { + if (SP_IS_TAG(obj)) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } + } + } +} + +bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + return false; +} + +bool TagsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + bool val = true; + if ( !currentlySelected && _toggleEvent ) + { + GdkEvent* event = gtk_get_current_event(); + if ( event ) { + // (keep these checks separate, so we know when to call gdk_event_free() + if ( event->type == GDK_BUTTON_PRESS ) { + GdkEventButton const* target = reinterpret_cast(_toggleEvent); + GdkEventButton const* evtb = reinterpret_cast(event); + + if ( (evtb->window == target->window) + && (evtb->send_event == target->send_event) + && (evtb->time == target->time) + && (evtb->state == target->state) + ) + { + // Ooooh! It's a magic one + val = false; + } + } + gdk_event_free(event); + } + } + return val; +} + +void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colParentObject]; + if (obj && SP_IS_TAG(obj)) + { + SP_TAG(obj)->setExpanded(isexpanded); + obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Constructor + */ +TagsPanel::TagsPanel() : + UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS), + _rootWatcher(0), + deskTrack(), + _desktop(0), + _document(0), + _model(0), + _pending(0), + _toggleEvent(0), + _defer_target(), + desktopChangeConn() +{ + //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + _tree.set_model( _store ); + _tree.set_headers_visible(false); + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon()); + int addColNum = _tree.append_column("type", *addRenderer) - 1; + Gtk::TreeViewColumn *col = _tree.get_column(addColNum); + if ( col ) { + col->add_attribute( addRenderer->property_active(), _model->_colAddRemove ); + col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove ); + } + + _text_renderer = manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + + _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) ); + _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) ); + + _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false); + _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false)); + _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true)); + + _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) ); + _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) ); + + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false ); + + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + _scroller.get_preferred_size(sreq_natural, sreq); +#else + sreq = _scroller.size_request(); +#endif + int minHeight = 70; + if (sreq.height < minHeight) { + // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar + _scroller.set_size_request(sreq.width, minHeight); + } + + _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); + + _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + + _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET); + + SPDesktop* targetDesktop = getDesktop(); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new tag") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); + _buttonsSecondary.pack_start(*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) ); +// _buttonsRow.add( *btn ); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Tag") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); + _watching.push_back( btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); + + // ------------------------------------------------------- + { + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); + + _popupMenu.show_all_children(); + } + // ------------------------------------------------------- + + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( false ); + } + + setDesktop( targetDesktop ); + + show_all_children(); + + // restorePanelPrefs(); + + // Connect this up last + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); +} + +TagsPanel::~TagsPanel() +{ + + setDesktop(NULL); + + if ( _model ) + { + delete _model; + _model = 0; + } + + if (_pending) { + delete _pending; + _pending = 0; + } + + if ( _toggleEvent ) + { + gdk_event_free( _toggleEvent ); + _toggleEvent = 0; + } + + desktopChangeConn.disconnect(); + deskTrack.disconnect(); +} + +void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_rootWatcher) + { + _rootWatcher->_repr->removeObserver(*_rootWatcher); + delete _rootWatcher; + _rootWatcher = NULL; + } + + _document = document; + + if (document && document->getDefs() && document->getDefs()->getRepr()) + { + _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs()); + document->getDefs()->getRepr()->addObserver(*_rootWatcher); + _objectsChanged(document->getDefs()); + } +} + +void TagsPanel::setDesktop( SPDesktop* desktop ) +{ + Panel::setDesktop(desktop); + + if ( desktop != _desktop ) { + _documentChangedConnection.disconnect(); + _selectionChangedConnection.disconnect(); + if ( _desktop ) { + _desktop = 0; + } + + _desktop = Panel::getDesktop(); + if ( _desktop ) { + //setLabel( _desktop->doc()->name ); + _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument)); + _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected)); + + setDocument(_desktop, _desktop->doc()); + } + } +/* + GSList const *layers = _desktop->doc()->getResourceList( "layer" ); + g_message( "layers list starts at %p", layers ); + for ( GSList const *iter=layers ; iter ; iter = iter->next ) { + SPObject *layer=static_cast(iter->data); + g_message(" {%s} [%s]", layer->id, layer->label() ); + } +*/ + deskTrack.setBase(desktop); +} + + + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h new file mode 100644 index 000000000..d35dfba01 --- /dev/null +++ b/src/ui/dialog/tags.h @@ -0,0 +1,181 @@ +/* + * A simple dialog for tags UI. + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_TAGS_PANEL_H +#define SEEN_TAGS_PANEL_H + +#include +#include +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/panel.h" +#include "ui/widget/object-composite-settings.h" +#include "desktop-tracker.h" +#include "ui/widget/style-subject.h" +#include "selection.h" +#include "ui/widget/filter-effect-chooser.h" + +class SPObject; +class SPTag; +struct SPColorSelector; + +namespace Inkscape { + +namespace UI { +namespace Dialog { + + +/** + * A panel that displays layers. + */ +class TagsPanel : public UI::Widget::Panel +{ +public: + TagsPanel(); + virtual ~TagsPanel(); + + //virtual void setOrientation( Gtk::AnchorType how ); + + static TagsPanel& getInstance(); + + void setDesktop( SPDesktop* desktop ); + void setDocument( SPDesktop* desktop, SPDocument* document); + +protected: + //virtual void _handleAction( int setId, int itemId ); + friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); +private: + class ModelColumns; + class InternalUIBounce; + class ObjectWatcher; + + TagsPanel(TagsPanel const &); // no copy + TagsPanel &operator=(TagsPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); + void _fireAction( unsigned int code ); + Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _storeDragSource(const Gtk::TreeModel::iterator& iter); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + + void _doTreeMove(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _pushTreeSelectionToCurrent(); + void _selected_row_callback( const Gtk::TreeModel::iterator& iter ); + void _select_tag( SPTag * tag ); + + void _checkTreeSelection(); + + void _takeAction( int val ); + bool _executeAction(); + + void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); + + bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + + void _updateObject(SPObject *obj); + bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj); + + void _objectsSelected(Selection *sel); + bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); + + void _objectsChanged(SPObject *root); + void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ); + + void _checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete); + +// std::vector groupConnections; + TagsPanel::ObjectWatcher* _rootWatcher; + std::vector _objectWatchers; + + // Hooked to the layer manager: + sigc::connection _documentChangedConnection; + sigc::connection _selectionChangedConnection; + + sigc::connection _changedConnection; + sigc::connection _addedConnection; + sigc::connection _removedConnection; + + // Internal + sigc::connection _selectedConnection; + sigc::connection _expandedConnection; + sigc::connection _collapsedConnection; + + DesktopTracker deskTrack; + SPDesktop* _desktop; + SPDocument* _document; + ModelColumns* _model; + InternalUIBounce* _pending; + gboolean _dnd_into; + std::vector _dnd_source; + SPObject* _dnd_target; + + GdkEvent* _toggleEvent; + bool down_at_add; + + Gtk::TreeModel::Path _defer_target; + + Glib::RefPtr _store; + std::vector _watching; + std::vector _watchingNonTop; + std::vector _watchingNonBottom; + + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::TreeView::Column *_name_column; +#if WITH_GTKMM_3_0 + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; +#else + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; +#endif + Gtk::ScrolledWindow _scroller; + Gtk::Menu _popupMenu; + Inkscape::UI::Widget::SpinButton _spinBtn; + Gtk::VBox _layersPage; + + sigc::connection desktopChangeConn; + +}; + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_OBJECTS_PANEL_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 9bfba5c24a89f0d2ae75fc78a0aa21743a29e978 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 11:56:51 -0500 Subject: Experimental merge of Ponyscape features into trunk (will not compile) (bzr r13090.1.2) --- src/ui/dialog/objects.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 31e73db29..5023a8813 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -57,6 +57,8 @@ //#define DUMP_LAYERS 1 +guint get_group0_keyval(GdkEventKey *event); + namespace Inkscape { namespace UI { namespace Dialog { @@ -414,7 +416,7 @@ bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) row[_model->_colLocked] = item ? !item->isSensitive() : false; row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; - row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? (item->clip_ref->getObject()->inverse ? 3 : 1) : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; + row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; return true; @@ -2035,6 +2037,14 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop ) } //namespace UI } //namespace Inkscape +guint get_group0_keyval(GdkEventKey *event) { + guint keyval = 0; + gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( + gdk_display_get_default()), event->hardware_keycode, + (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, + NULL, NULL, NULL); + return keyval; +} /* Local Variables: -- cgit v1.2.3 From 8830d1ad5ab0693313d760cc99e2df0f35c9f6d9 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 16:29:52 -0500 Subject: Updated to include (non-functional) Objects dialogue (bzr r13090.1.6) --- src/ui/dialog/objects.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 5023a8813..ebfa16f02 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -37,6 +37,7 @@ #include "ui/widget/insertordericon.h" #include "ui/widget/clipmaskicon.h" #include "ui/widget/highlight-picker.h" +#include "ui/tools/node-tool.h" #include "verbs.h" #include "widgets/icon.h" #include "xml/node.h" @@ -54,6 +55,7 @@ #include "sp-clippath.h" #include "sp-mask.h" #include "layer-manager.h" +#include "tools-switch.h" //#define DUMP_LAYERS 1 @@ -2037,6 +2039,9 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop ) } //namespace UI } //namespace Inkscape +//should be okay to put these here because they are never referenced anywhere else +using namespace Inkscape::UI::Tools; + guint get_group0_keyval(GdkEventKey *event) { guint keyval = 0; gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( @@ -2046,6 +2051,42 @@ guint get_group0_keyval(GdkEventKey *event) { return keyval; } +void SPItem::setHighlightColor(guint32 const color) +{ + g_free(_highlightColor); + if (color & 0x000000ff) + { + _highlightColor = g_strdup_printf("%u", color); + } + else + { + _highlightColor = NULL; + } + + NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + tools_switch(tool->desktop, TOOLS_NODES); + } + } +} + +void SPItem::unsetHighlightColor() +{ + g_free(_highlightColor); + _highlightColor = NULL; + NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + tools_switch(tool->desktop, TOOLS_NODES); + } + } +} + /* Local Variables: mode:c++ -- cgit v1.2.3 From fc643d9de8b5b3faf6d43559a43308fbce56e592 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 17:39:47 -0500 Subject: Fix objects dialogue (bzr r13090.1.9) --- src/ui/dialog/dialog-manager.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 6d32e3aa8..bbb55ceee 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -54,6 +54,7 @@ #include "ui/dialog/xml-tree.h" #include "ui/dialog/clonetiler.h" #include "ui/dialog/svg-fonts-dialog.h" +#include "ui/dialog/objects.h" namespace Inkscape { namespace UI { @@ -108,6 +109,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); + registerFactory("ObjectsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -142,6 +144,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); + registerFactory("ObjectsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); -- cgit v1.2.3 From dc1f7ce719d703d8dd4d7747d1967a3e8a1bfb18 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 4 Mar 2014 16:53:56 -0500 Subject: Remove tag dialog temporarily (bzr r13090.1.13) --- src/ui/dialog/Makefile_insert | 2 -- src/ui/dialog/dialog-manager.cpp | 6 +++--- src/ui/dialog/swatches.cpp | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index bdb1abcda..1cf667f2a 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -113,6 +113,4 @@ ink_common_sources += \ ui/dialog/lpe-powerstroke-properties.h \ ui/dialog/objects.cpp \ ui/dialog/objects.h \ - ui/dialog/tags.cpp \ - ui/dialog/tags.h \ $(inkboard_dialogs) diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index bbfea8cf0..1fddbf007 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -55,7 +55,7 @@ #include "ui/dialog/clonetiler.h" #include "ui/dialog/svg-fonts-dialog.h" #include "ui/dialog/objects.h" -#include "ui/dialog/tags.h" +//#include "ui/dialog/tags.h" namespace Inkscape { namespace UI { @@ -111,7 +111,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - registerFactory("TagsPanel", &create); + //registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -147,7 +147,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - registerFactory("TagsPanel", &create); + //registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 5e77a28ab..711bcfe2d 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -20,6 +20,7 @@ #include "swatches.h" #include +#include #include #include @@ -57,6 +58,22 @@ #include "gradient-chemistry.h" #include "helper/action.h" #include "helper/action-context.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-pattern.h" +#include "icon-size.h" +#include "widgets/icon.h" +#include "filedialog.h" +#include "sp-stop.h" +#include "svg/svg-color.h" +#include "sp-radial-gradient.h" +#include "color-rgba.h" +#include "event-context.h" +#include +//sorry! +#ifdef WIN32 +#include +#endif namespace Inkscape { namespace UI { @@ -64,6 +81,7 @@ namespace Dialogs { #define VBLOCK 16 #define PREVIEW_PIXBUF_WIDTH 128 +#define SWATCHES_FILE_NAME "swatches.svg" void _loadPaletteFile( gchar const *filename, gboolean user=FALSE ); -- cgit v1.2.3 From 12971e975dae83c23e89cdbff99e990d3916b6ff Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 4 Mar 2014 18:05:52 -0500 Subject: Added some basic swatch stuff (does not compile) (bzr r13090.1.14) --- src/ui/dialog/swatches.cpp | 2940 ++++++++++++++++++++++++++++++-------------- src/ui/dialog/swatches.h | 155 ++- 2 files changed, 2157 insertions(+), 938 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 711bcfe2d..a0c79b8ac 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -43,10 +43,10 @@ #include "path-prefix.h" #include "preferences.h" #include "sp-item.h" +#include "sp-gradient-fns.h" #include "sp-gradient.h" #include "sp-gradient-vector.h" #include "style.h" -#include "ui/previewholder.h" #include "widgets/desktop-widget.h" #include "widgets/gradient-vector.h" #include "widgets/eek-preview.h" @@ -57,7 +57,6 @@ #include "verbs.h" #include "gradient-chemistry.h" #include "helper/action.h" -#include "helper/action-context.h" #include "xml/node-observer.h" #include "xml/repr.h" #include "sp-pattern.h" @@ -68,1172 +67,2255 @@ #include "svg/svg-color.h" #include "sp-radial-gradient.h" #include "color-rgba.h" -#include "event-context.h" +#include "svg/css-ostringstream.h" +//#include "event-context.h" //no longer exists #include -//sorry! #ifdef WIN32 #include #endif +guint get_group0_keyval(GdkEventKey *event); +void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); + namespace Inkscape { namespace UI { namespace Dialogs { -#define VBLOCK 16 -#define PREVIEW_PIXBUF_WIDTH 128 #define SWATCHES_FILE_NAME "swatches.svg" -void _loadPaletteFile( gchar const *filename, gboolean user=FALSE ); - -std::list userSwatchPages; -std::list systemSwatchPages; -static std::map docPalettes; -static std::vector docTrackings; -static std::map docPerPanel; - - -class SwatchesPanelHook : public SwatchesPanel -{ -public: - static void convertGradient( GtkMenuItem *menuitem, gpointer userData ); - static void deleteGradient( GtkMenuItem *menuitem, gpointer userData ); -}; +static char* trim( char* str ) { + char* ret = str; + while ( *str && (*str == ' ' || *str == '\t') ) { + str++; + } + ret = str; + while ( *str ) { + str++; + } + str--; + while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { + *str-- = 0; + } + return ret; +} -static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(false); +static void skipWhitespace( char*& str ) { + while ( *str == ' ' || *str == '\t' ) { + str++; } } -static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(true); +static bool parseNum( char*& str, int& val ) { + val = 0; + while ( '0' <= *str && *str <= '9' ) { + val = val * 10 + (*str - '0'); + str++; } + bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); + return retval; } -static GtkWidget* popupMenu = 0; -static GtkWidget *popupSubHolder = 0; -static GtkWidget *popupSub = 0; -static std::vector popupItems; -static std::vector popupExtras; -static ColorItem* bounceTarget = 0; -static SwatchesPanel* bouncePanel = 0; +static char * SwatchFile; +static SPDocument * SwatchDocument; +static unsigned int page_suffix; -static void redirClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) +static void loadPalletFile() { - if ( bounceTarget ) { - handleClick( GTK_WIDGET(menuitem), bounceTarget ); + if (!SwatchDocument) { + SwatchFile=g_build_filename(INKSCAPE_PALETTESDIR, _("swatches.svg"), NULL); + SwatchDocument=SPDocument::createNewDoc (SwatchFile, TRUE); + if (!SwatchDocument) { + SwatchDocument = SPDocument::createNewDoc(NULL, TRUE, true); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } } } -static void redirSecondaryClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) +static void addStop( Inkscape::XML::Node *parent, Glib::ustring const &color, gfloat opacity, gchar const *offset ) { - if ( bounceTarget ) { - handleSecondaryClick( GTK_WIDGET(menuitem), 0, bounceTarget ); +#ifdef SP_GR_VERBOSE + g_message("addStop(%p, %s, %d, %s)", parent, color.c_str(), opacity, offset); +#endif + Inkscape::XML::Node *stop = parent->document()->createElement("svg:stop"); + { + gchar *tmp = g_strdup_printf( "stop-color:%s;stop-opacity:%f;", color.c_str(), opacity < 0.0 ? 0.0 : (opacity > 1.0 ? 1.0 : opacity) ); + stop->setAttribute( "style", tmp ); + g_free(tmp); } + + stop->setAttribute( "offset", offset ); + + parent->appendChild(stop); + Inkscape::GC::release(stop); } -static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) +static SPGroup* importGPL(SPDocument* doc, const gchar* full) { - if ( gr ) { - bool shown = false; - if ( desktop && desktop->doc() ) { - Inkscape::Selection *selection = sp_desktop_selection( desktop ); - GSList const *items = selection->itemList(); - if (items) { - SPStyle *query = sp_style_new( desktop->doc() ); - int result = objects_query_fillstroke(const_cast(items), query, true); - if ( (result == QUERY_STYLE_MULTIPLE_SAME) || (result == QUERY_STYLE_SINGLE) ) { - // could be pertinent - if (query->fill.isPaintserver()) { - SPPaintServer* server = query->getFillPaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient* grad = SP_GRADIENT(server); - if ( grad->isSwatch() && grad->getId() == gr->getId()) { - desktop->_dlg_mgr->showDialog("FillAndStroke"); - shown = true; + SPGroup* ret = NULL; + if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { + + /*Load the pallet file here*/ + char block[1024]; + FILE *f = Inkscape::IO::fopen_utf8name( full, "r" ); + if ( f ) { + char* result = fgets( block, sizeof(block), f ); + if ( result ) { + if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { + bool inHeader = true; + bool hasErr = false; + + Inkscape::XML::Node * page = doc->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (doc->getObjectById(id)); + + page->setAttribute("id", id); + + do { + result = fgets( block, sizeof(block), f ); + block[sizeof(block) - 1] = 0; + if ( result ) { + if ( block[0] == '#' ) { + // ignore comment + } else { + char *ptr = block; + // very simple check for header versus entry + while ( *ptr == ' ' || *ptr == '\t' ) { + ptr++; + } + if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { + // blank line. skip it. + } else if ( '0' <= *ptr && *ptr <= '9' ) { + // should be an entry link + inHeader = false; + ptr = block; + Glib::ustring name(""); + skipWhitespace(ptr); + if ( *ptr ) { + int r = 0; + int g = 0; + int b = 0; + hasErr = parseNum(ptr, r); + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, g); + } + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, b); + } + if ( !hasErr && *ptr ) { + char* n = trim(ptr); + if (n != NULL) { + name = g_dpgettext2(NULL, "Palette", n); + } + } + if ( !hasErr ) { + // Add the entry now + + Inkscape::XML::Node *grad = doc->getReprDoc()->createElement("svg:linearGradient"); + grad->setAttribute("inkscape:label", name.c_str()); + grad->setAttribute( "osb:paint", "solid", 0 ); + SPColor color((float)r / 255, (float)g / 255, (float)b / 255); + addStop(grad, color.toString(), 1, "0"); + page->appendChild(grad); + Inkscape::GC::release(grad); + } + } else { + hasErr = true; + } + } else { + if ( !inHeader ) { + // Hmmm... probably bad. Not quite the format we want? + hasErr = true; + } else { + char* sep = strchr(result, ':'); + if ( sep ) { + *sep = 0; + char* val = trim(sep + 1); + char* name = trim(result); + if ( *name ) { + if ( strcmp( "Name", name ) == 0 ) + { + page->setAttribute("inkscape:label", val); + } + } else { + // error + hasErr = true; + } + } else { + // error + hasErr = true; + } + } + } } } + } while ( result && !hasErr ); + if ( !hasErr ) { + doc->getDefs()->appendChild(page); + Inkscape::GC::release(page); + SPObject* obj = doc->getObjectByRepr(page); + if (SP_IS_GROUP(obj)) { + ret = SP_GROUP(obj); + } + #if ENABLE_MAGIC_COLORS + ColorItem::_wireMagicColors( onceMore ); + #endif // ENABLE_MAGIC_COLORS + } else { + delete page; } } - sp_style_unref(query); } - } - if (!shown) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (prefs->getBool("/dialogs/gradienteditor/showlegacy", false)) { - // Legacy gradient dialog - GtkWidget *dialog = sp_gradient_vector_editor_new( gr ); - gtk_widget_show( dialog ); - } else { - // Invoke the gradient tool - Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT ); - if ( verb ) { - SPAction *action = verb->get_action( Inkscape::ActionContext( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP ) ); - if ( action ) { - sp_action_perform( action, NULL ); - } - } - } + fclose(f); } + /* end loading the pallet file*/ } + return ret; } -static void editGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ ) +SwatchesPanel& SwatchesPanel::getInstance() { - if ( bounceTarget ) { - SwatchesPanel* swp = bouncePanel; - SPDesktop* desktop = swp ? swp->getDesktop() : 0; - SPDocument *doc = desktop ? desktop->doc() : 0; - if (doc) { - std::string targetName(bounceTarget->def.descr); - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( targetName == grad->getId() ) { - editGradientImpl( desktop, grad ); - break; + return *new SwatchesPanel(); +} + +class SwatchesPanel::StopWatcher : public Inkscape::XML::NodeObserver { +public: + StopWatcher(SwatchesPanel* pnl, SPStop* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()) + { + _repr->addObserver(*this); + } + + ~StopWatcher() { + _repr->removeObserver(*this); + } + + virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} + virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} + virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ){} + virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + + virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if (_pnl && _obj) { + _pnl->_defsChanged( ); + } + } + + SwatchesPanel* _pnl; + SPStop* _obj; + Inkscape::XML::Node* _repr; +}; + +class SwatchesPanel::GradientWatcher : public Inkscape::XML::NodeObserver { +public: + GradientWatcher(SwatchesPanel* pnl, SPGradient* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")), + _swatchAttr(g_quark_from_string("osb:paint")) + { + _repr->addObserver(*this); + } + + ~GradientWatcher() { + _repr->removeObserver(*this); + } + + virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj && _obj->isSwatch()) { + _pnl->_defsChanged( ); + } + } + virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj && _obj->isSwatch() ) { + _pnl->_defsChanged( ); + } + } + virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) + { + if ( _pnl && _obj && _obj->isSwatch() ) { + _pnl->_defsChanged( ); + } + } + virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if (_pnl && _obj && ((_obj->isSwatch() && name == _labelAttr) || name == _swatchAttr)) { + _pnl->_defsChanged( ); + } + } + + SwatchesPanel* _pnl; + SPGradient* _obj; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; + GQuark _swatchAttr; +}; + +class SwatchesPanel::SwatchWatcher : public Inkscape::XML::NodeObserver { +public: + SwatchWatcher(SwatchesPanel* pnl, SPObject* obj, bool builtIn) : + _pnl(pnl), + _obj(obj), + _builtIn(builtIn), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")), + _swatchAttr(g_quark_from_string("osb:paint")) + { + _repr->addObserver(*this); + } + + ~SwatchWatcher() { + _repr->removeObserver(*this); + } + + virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj) { + SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); + if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); } } } } -} - -void SwatchesPanelHook::convertGradient( GtkMenuItem * /*menuitem*/, gpointer userData ) -{ - if ( bounceTarget ) { - SwatchesPanel* swp = bouncePanel; - SPDesktop* desktop = swp ? swp->getDesktop() : 0; - SPDocument *doc = desktop ? desktop->doc() : 0; - gint index = GPOINTER_TO_INT(userData); - if ( doc && (index >= 0) && (static_cast(index) < popupItems.size()) ) { - Glib::ustring targetName = popupItems[index]; - - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( targetName == grad->getId() ) { - grad->setSwatch(); - DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT, - _("Add gradient stop")); - break; + virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); + } + } + } + virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) + { + if ( _pnl && _obj) { + SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); + if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); } } } } -} + virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if (_pnl && _obj && name == _labelAttr) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); + } + } + } -void SwatchesPanelHook::deleteGradient( GtkMenuItem */*menuitem*/, gpointer /*userData*/ ) + SwatchesPanel* _pnl; + SPObject* _obj; + bool _builtIn; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; + GQuark _swatchAttr; +}; + +class SwatchesPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord { - if ( bounceTarget ) { - SwatchesPanel* swp = bouncePanel; - SPDesktop* desktop = swp ? swp->getDesktop() : 0; - sp_gradient_unset_swatch(desktop, bounceTarget->def.descr); +public: + + ModelColumns() + { + add(_colObject); + add(_colLabel); } -} + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; +}; -static SwatchesPanel* findContainingPanel( GtkWidget *widget ) +class SwatchesPanel::ModelColumnsDoc : public Gtk::TreeModel::ColumnRecord { - SwatchesPanel *swp = 0; +public: - std::map rawObjects; - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - rawObjects[GTK_WIDGET(it->first->gobj())] = it->first; + ModelColumnsDoc() + { + add(_colObject); + add(_colLabel); + add(_colPixbuf); } + virtual ~ModelColumnsDoc() {} - for (GtkWidget* curr = widget; curr && !swp; curr = gtk_widget_get_parent(curr)) { - if (rawObjects.find(curr) != rawObjects.end()) { - swp = rawObjects[curr]; + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn > _colPixbuf; +}; + +static void StripChildGroups(Inkscape::XML::Node * node, SPObject* addTo) +{ + for (Inkscape::XML::Node * it = node->firstChild(); it != NULL;) { + if (!strcmp(it->name(), "svg:g")) { + Inkscape::XML::Node * todel = it; + it = it->next(); + node->removeChild(todel); + } else { + it = it->next(); } } - - return swp; + addTo->appendChildRepr(node); } -static void removeit( GtkWidget *widget, gpointer data ) +static void BubbleChildGroups(Inkscape::XML::Node * node, SPObject* addTo) { - gtk_container_remove( GTK_CONTAINER(data), widget ); + std::queue groups; + for (Inkscape::XML::Node * it = node->firstChild(); it != NULL; ) { + if (!strcmp(it->name(), "svg:g")) { + groups.push(it->duplicate(addTo->document->getReprDoc())); + Inkscape::XML::Node * todel = it; + it = it->next(); + node->removeChild(todel); + } else { + it = it->next(); + } + } + addTo->appendChildRepr(node); + while (!groups.empty()) { + Inkscape::XML::Node * it = groups.front(); + groups.pop(); + BubbleChildGroups(it, addTo); + Inkscape::GC::release(it); + } } -/* extern'ed from colot-item.cpp */ -gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ); +void SwatchesPanel::_addSwatchButtonClicked(SPGroup* swatch, bool recurse) +{ + if (_currentDocument) { + if (swatch && SP_IS_GROUP(swatch) ) { + Inkscape::XML::Node * copy = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); + if (recurse) { + BubbleChildGroups(copy, _currentDocument->getDefs()); + } else { + StripChildGroups(copy, _currentDocument->getDefs()); + } + Inkscape::GC::release(copy); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); + } + } +} -gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ) +void SwatchesPanel::_importButtonClicked(bool addToDoc, bool addToBI) { - gboolean handled = FALSE; - - if ( event && (event->button == 3) && (event->type == GDK_BUTTON_PRESS) ) { - SwatchesPanel* swp = findContainingPanel( widget ); - - if ( !popupMenu ) { - popupMenu = gtk_menu_new(); - GtkWidget* child = 0; - - //TRANSLATORS: An item in context menu on a colour in the swatches - child = gtk_menu_item_new_with_label(_("Set fill")); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(redirClick), - user_data); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - - //TRANSLATORS: An item in context menu on a colour in the swatches - child = gtk_menu_item_new_with_label(_("Set stroke")); - - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(redirSecondaryClick), - user_data); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - - child = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - - child = gtk_menu_item_new_with_label(_("Delete")); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(SwatchesPanelHook::deleteGradient), - user_data ); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - gtk_widget_set_sensitive( child, FALSE ); - - child = gtk_menu_item_new_with_label(_("Edit...")); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(editGradient), - user_data ); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - - child = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - - child = gtk_menu_item_new_with_label(_("Convert")); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - //popupExtras.push_back(child); - //gtk_widget_set_sensitive( child, FALSE ); + if (addToDoc || addToBI) { + //# Get the current directory for finding files + static Glib::ustring open_path; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + if(open_path.empty()) + { + Glib::ustring attr = prefs->getString("/dialogs/open/path"); + if (!attr.empty()) open_path = attr; + } + + //# Test if the open_path directory exists + if (!Inkscape::IO::file_test(open_path.c_str(), + (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) + open_path = ""; + + #ifdef WIN32 + //# If no open path, default to our win32 documents folder + if (open_path.empty()) + { + // The path to the My Documents folder is read from the + // value "HKEY_CURRENT_USER\Software\Windows\CurrentVersion\Explorer\Shell Folders\Personal" + HKEY key = NULL; + if(RegOpenKeyExA(HKEY_CURRENT_USER, + "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { - popupSubHolder = child; - popupSub = gtk_menu_new(); - gtk_menu_item_set_submenu( GTK_MENU_ITEM(child), popupSub ); + WCHAR utf16path[_MAX_PATH]; + DWORD value_type; + DWORD data_size = sizeof(utf16path); + if(RegQueryValueExW(key, L"Personal", NULL, &value_type, + (BYTE*)utf16path, &data_size) == ERROR_SUCCESS) + { + g_assert(value_type == REG_SZ); + gchar *utf8path = g_utf16_to_utf8( + (const gunichar2*)utf16path, -1, NULL, NULL, NULL); + if(utf8path) + { + open_path = Glib::ustring(utf8path); + g_free(utf8path); + } + } } + } + #endif - gtk_widget_show_all(popupMenu); + //# If no open path, default to our home directory + if (open_path.empty()) + { + open_path = g_get_home_dir(); + open_path.append(G_DIR_SEPARATOR_S); } - if ( user_data ) { - ColorItem* item = reinterpret_cast(user_data); - bool show = swp && (swp->getSelectedIndex() == 0); - for ( std::vector::iterator it = popupExtras.begin(); it != popupExtras.end(); ++ it) { - gtk_widget_set_sensitive(*it, show); - } + Gtk::Window * parent = SP_ACTIVE_DESKTOP->getToplevel(); + //# Create a dialog + Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance = + Inkscape::UI::Dialog::FileOpenDialog::create( + *parent, open_path, + Inkscape::UI::Dialog::SWATCH_TYPES, + _("Select file to open")); - bounceTarget = item; - bouncePanel = swp; - popupItems.clear(); - if ( popupMenu ) { - gtk_container_foreach(GTK_CONTAINER(popupSub), removeit, popupSub); - bool processed = false; - GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); - if ( wdgt ) { - SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt); - if ( dtw && dtw->desktop ) { - // Pick up all gradients with vectors - const GSList *gradients = (dtw->desktop->doc())->getResourceList("gradient"); - gint index = 0; - for (const GSList *curr = gradients; curr; curr = curr->next) { - SPGradient* grad = SP_GRADIENT(curr->data); - if ( grad->hasStops() && !grad->isSwatch() ) { - //gl = g_slist_prepend(gl, curr->data); - processed = true; - GtkWidget *child = gtk_menu_item_new_with_label(grad->getId()); - gtk_menu_shell_append(GTK_MENU_SHELL(popupSub), child); - - popupItems.push_back(grad->getId()); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(SwatchesPanelHook::convertGradient), - GINT_TO_POINTER(index) ); - index++; - } - } + //# Show the dialog + bool const success = openDialogInstance->show(); - gtk_widget_show_all(popupSub); - } - } - gtk_widget_set_sensitive( popupSubHolder, processed ); + //# Save the folder the user selected for later + open_path = openDialogInstance->getCurrentDirectory(); - gtk_menu_popup(GTK_MENU(popupMenu), NULL, NULL, NULL, NULL, event->button, event->time); - handled = TRUE; - } + if (!success) + { + delete openDialogInstance; + return; } - } - return handled; -} + //# User selected something. Get name and type + Glib::ustring fileName = openDialogInstance->getFilename(); + //# We no longer need the file dialog object - delete it + delete openDialogInstance; + openDialogInstance = NULL; -static char* trim( char* str ) { - char* ret = str; - while ( *str && (*str == ' ' || *str == '\t') ) { - str++; - } - ret = str; - while ( *str ) { - str++; - } - str--; - while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { - *str-- = 0; - } - return ret; -} -static void skipWhitespace( char*& str ) { - while ( *str == ' ' || *str == '\t' ) { - str++; + if (!fileName.empty()) + { + Glib::ustring newFileName = Glib::filename_to_utf8(fileName); + + if ( newFileName.size() > 0) + fileName = newFileName; + else + g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); + + open_path = Glib::path_get_dirname (fileName); + open_path.append(G_DIR_SEPARATOR_S); + prefs->setString("/dialogs/open/path", open_path); + + SPDocument* importdoc = SPDocument::createNewDoc(fileName.c_str(), true); + Inkscape::XML::Node * page = NULL; + if (importdoc && importdoc->getDefs()) { + if (addToBI) { + page = SwatchDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (SwatchDocument->getObjectById(id)); + + page->setAttribute("id", id); + gchar* name = g_path_get_basename(importdoc->getName()); + page->setAttribute("inkscape:label", name); + g_free(name); + } + + for (SPObject* it = importdoc->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GROUP(it)) { + if (page) { + Inkscape::XML::Node * copy = it->getRepr()->duplicate(SwatchDocument->getReprDoc()); + page->appendChild(copy); + } + if (addToDoc) { + _addSwatchButtonClicked(SP_GROUP(it), false); + } + } + } + if (page) { + SwatchDocument->getDefs()->appendChildRepr(page); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } + + importdoc->doUnref(); + } else { + SPGroup* g = importGPL(addToBI ? SwatchDocument : _currentDocument, fileName.c_str()); + if (addToBI) { + if (addToDoc) { + _addSwatchButtonClicked(g, false); + } + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } else { + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); + } + } + } } } -static bool parseNum( char*& str, int& val ) { - val = 0; - while ( '0' <= *str && *str <= '9' ) { - val = val * 10 + (*str - '0'); - str++; +void SwatchesPanel::SetSelectedFill(SPGradient* swatch) +{ + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->fill.isSet()) { + if (it->style->fill.isPaintserver()) { + SPPaintServer * server = it->style->getFillPaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = swatch->getRepr(); + if (repr != drepr && grad != swatch) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); + } + for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { + Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); + swatch->appendChildRepr(clone); + Inkscape::GC::release(clone); + } + swatch->setSwatch(); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); + } + } + } else if (it->style->fill.isColor()) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); + } + addStop(swatch->getRepr(), it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); + swatch->setSwatch(); + if (!_noLink.get_active()) { + SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); + } + } + } } - bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); - return retval; } - -void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ ) +void SwatchesPanel::SetSelectedStroke(SPGradient* swatch) { - char block[1024]; - FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" ); - if ( f ) { - char* result = fgets( block, sizeof(block), f ); - if ( result ) { - if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { - bool inHeader = true; - bool hasErr = false; - - SwatchPage *onceMore = new SwatchPage(); - - do { - result = fgets( block, sizeof(block), f ); - block[sizeof(block) - 1] = 0; - if ( result ) { - if ( block[0] == '#' ) { - // ignore comment - } else { - char *ptr = block; - // very simple check for header versus entry - while ( *ptr == ' ' || *ptr == '\t' ) { - ptr++; + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->stroke.isSet()) { + if (it->style->stroke.isPaintserver()) { + SPPaintServer * server = it->style->getStrokePaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = swatch->getRepr(); + if (repr != drepr && grad != swatch) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); } - if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { - // blank line. skip it. - } else if ( '0' <= *ptr && *ptr <= '9' ) { - // should be an entry link - inHeader = false; - ptr = block; - Glib::ustring name(""); - skipWhitespace(ptr); - if ( *ptr ) { - int r = 0; - int g = 0; - int b = 0; - hasErr = parseNum(ptr, r); - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, g); - } - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, b); - } - if ( !hasErr && *ptr ) { - char* n = trim(ptr); - if (n != NULL) { - name = g_dpgettext2(NULL, "Palette", n); - } - } - if ( !hasErr ) { - // Add the entry now - Glib::ustring nameStr(name); - ColorItem* item = new ColorItem( r, g, b, nameStr ); - onceMore->_colors.push_back(item); - } - } else { - hasErr = true; - } - } else { - if ( !inHeader ) { - // Hmmm... probably bad. Not quite the format we want? - hasErr = true; - } else { - char* sep = strchr(result, ':'); - if ( sep ) { - *sep = 0; - char* val = trim(sep + 1); - char* name = trim(result); - if ( *name ) { - if ( strcmp( "Name", name ) == 0 ) - { - onceMore->_name = val; - } - else if ( strcmp( "Columns", name ) == 0 ) - { - gchar* endPtr = 0; - guint64 numVal = g_ascii_strtoull( val, &endPtr, 10 ); - if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { - // overflow - } else if ( (numVal == 0) && (endPtr == val) ) { - // failed conversion - } else { - onceMore->_prefWidth = numVal; - } - } - } else { - // error - hasErr = true; - } - } else { - // error - hasErr = true; - } - } + for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { + Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); + swatch->appendChildRepr(clone); + Inkscape::GC::release(clone); + } + swatch->setSwatch(); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); } } - } while ( result && !hasErr ); - if ( !hasErr ) { - if (user) - userSwatchPages.push_back(onceMore); - else - systemSwatchPages.push_back(onceMore); -#if ENABLE_MAGIC_COLORS - ColorItem::_wireMagicColors( onceMore ); -#endif // ENABLE_MAGIC_COLORS - } else { - delete onceMore; + } else if (it->style->stroke.isColor()) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); + } + addStop(swatch->getRepr(), it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); + swatch->setSwatch(); + if (!_noLink.get_active()) { + SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); } } } + } +} - fclose(f); +void SwatchesPanel::MoveSwatchDown(SPGradient* swatch) +{ + if (_currentDocument && swatch) { + SPObject* next = swatch->next; + while (next && (!SP_IS_GRADIENT(next) || !(SP_GRADIENT(next)->isSwatch()))) { + next = next->next; + } + if (next) { + Inkscape::XML::Node* repr = swatch->getRepr(); + repr->parent()->changeOrder(repr, next->getRepr()); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Right")); + } } } -static bool -compare_swatch_names(SwatchPage const *a, SwatchPage const *b) { +void SwatchesPanel::MoveSwatchUp(SPGradient* swatch) +{ + if (_currentDocument && swatch) { + SPObject* g = NULL; + SPObject* next = swatch->parent->firstChild(); + while (next && next != swatch) { + if (SP_IS_GRADIENT(next) && SP_GRADIENT(next)->isSwatch()) { + g = next; + } + next = next->next; + } + if (g) { + g = g->getPrev(); + Inkscape::XML::Node* repr = swatch->getRepr(); + repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Left")); + } + } +} - return g_utf8_collate(a->_name.c_str(), b->_name.c_str()) < 0; +void SwatchesPanel::RemoveSwatch(SPGradient* swatch) +{ + if (_currentDocument) { + if (swatch->isReferenced()) { + Inkscape::XML::Node * repr = swatch->getRepr(); + repr->parent()->removeChild(repr); + _currentDocument->getDefs()->getRepr()->appendChild(repr); + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); + } else { + swatch->deleteObject(false); + } + } } -static void loadEmUp() +void SwatchesPanel::_setSelectionSwatch(SPGradient* swatch, bool isStroke) { - static bool beenHere = false; - gboolean userPalete = true; - if ( !beenHere ) { - beenHere = true; - - std::list sources; - sources.push_back( profile_path("palettes") ); - sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) ); - sources.push_back( g_strdup(CREATE_PALETTESDIR) ); - - // Use this loop to iterate through a list of possible document locations. - while (!sources.empty()) { - gchar *dirname = sources.front(); - if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS ) - && Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) { - GError *err = 0; - GDir *directory = g_dir_open(dirname, 0, &err); - if (!directory) { - gchar *safeDir = Inkscape::IO::sanitizeString(dirname); - g_warning(_("Palettes directory (%s) is unavailable."), safeDir); - g_free(safeDir); + if (_currentDocument) { + if (swatch) { + if (_noLink.get_active()) { + if (swatch->isSolid()) { + ColorRGBA rgba(swatch->getFirstStop()->getEffectiveColor().toRGBA32(swatch->getFirstStop()->opacity)); + sp_desktop_set_color(_currentDesktop, rgba, false, !isStroke); } else { - gchar *filename = 0; - while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) { - gchar* lower = g_ascii_strdown( filename, -1 ); -// if ( g_str_has_suffix(lower, ".gpl") ) { - if ( !g_str_has_suffix(lower, "~") ) { - gchar* full = g_build_filename(dirname, filename, NULL); - if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { - _loadPaletteFile(full, userPalete); - } - g_free(full); - } -// } - g_free(lower); - } - g_dir_close(directory); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); + + Inkscape::XML::Node * clone = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); + _currentDocument->getDefs()->appendChildRepr(clone); + SPGradient* grad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); + Inkscape::GC::release(clone); + grad->setSwatch(false); + SPGradient* normalized = sp_gradient_ensure_vector_normalized(grad); +// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { +// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); +// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); +// } + sp_desktop_set_style(_currentDesktop, css); + sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); + sp_repr_css_attr_unref (css); } + } else { + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); + + SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); +// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { +// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); +// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); +// } + sp_desktop_set_style(_currentDesktop, css); + sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); + sp_repr_css_attr_unref (css); } - - // toss the dirname - g_free(dirname); - sources.pop_front(); - userPalete = false; + } else { + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, isStroke ? "stroke" : "fill", "none"); + sp_desktop_set_style(_currentDesktop, css); + } + if (isStroke) { + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item stroke swatch")); + } else { + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item fill swatch")); } } +} - // Sort the list of swatches by name, grouped by user/system - userSwatchPages.sort(compare_swatch_names); - systemSwatchPages.sort(compare_swatch_names); +void SwatchesPanel::_swatchClicked(GdkEventButton* event, SPGradient* swatch) +{ + if (_currentDesktop) { + if (event->button == 3) { + Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); + + Gtk::MenuItem* mi; + + Glib::ustring us = Glib::ustring::compose("%1", swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]")); + mi = Gtk::manage(new Gtk::MenuItem(swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]"))); + Gtk::Label* namelbl = dynamic_cast(mi->get_child()); + if (namelbl) { + namelbl->set_markup(us); + } + mi->show(); + mi->set_sensitive(false); + menu->append(*mi); + + Gtk::SeparatorMenuItem* sep; + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set Fill"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, false)); + mi->show(); + mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set Stroke"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, true)); + mi->show(); + mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); + menu->append(*mi); + + if (swatch) { + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Fill"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedFill), swatch)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Stroke"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedStroke), swatch)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Left"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchUp), swatch)); + mi->show(); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Right"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchDown), swatch)); + mi->show(); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::RemoveSwatch), swatch)); + mi->show(); + menu->append(*mi); + } + menu->popup(event->button, event->time); + } else if (!_currentDesktop->selection->isEmpty()) { + _setSelectionSwatch(swatch, event->state & GDK_SHIFT_MASK); + } + } } +void SwatchesPanel::MoveDown(SPGroup* page) +{ + if (_currentDocument && page) { + SPObject* next = page->next; + while (next && !SP_IS_GROUP(next)) { + next = next->next; + } + if (next) { + Inkscape::XML::Node* repr = page->getRepr(); + repr->parent()->changeOrder(repr, next->getRepr()); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Down")); + } + } +} - -SwatchesPanel& SwatchesPanel::getInstance() +void SwatchesPanel::MoveUp(SPGroup* page) { - return *new SwatchesPanel(); + if (_currentDocument && page) { + SPObject* g = NULL; + SPObject* next = page->parent->firstChild(); + while (next && next != page) { + if (SP_IS_GROUP(next)) { + g = next; + } + next = next->next; + } + if (g) { + g = g->getPrev(); + Inkscape::XML::Node* repr = page->getRepr(); + repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Up")); + } + } } +void SwatchesPanel::Remove(SPGroup* page) +{ + if (_currentDocument && page) { + std::vector toMove; + for(SPObject* obj = page->firstChild(); obj != NULL; obj = obj->next) { + if (SP_IS_GRADIENT(obj)) { + SPGradient* grad = SP_GRADIENT(obj); + if (grad->isReferenced()) { + toMove.push_back(grad->getRepr()); + } + } + } + while (!toMove.empty()) { + Inkscape::XML::Node * repr = toMove.back(); + toMove.pop_back(); + repr->parent()->removeChild(repr); + _currentDocument->getDefs()->getRepr()->appendChild(repr); + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); + } + page->deleteObject(false); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Remove Swatch Group")); + } +} -/** - * Constructor - */ -SwatchesPanel::SwatchesPanel(gchar const* prefsPath) : - Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, "", true), - _holder(0), - _clear(0), - _remove(0), - _currentIndex(0), - _currentDesktop(0), - _currentDocument(0) +void SwatchesPanel::AddSelectedFill(SPGroup* page) { - Gtk::RadioMenuItem* hotItem = 0; - _holder = new PreviewHolder(); - _clear = new ColorItem( ege::PaintDef::CLEAR ); - _remove = new ColorItem( ege::PaintDef::NONE ); - if (docPalettes.empty()) { - SwatchPage *docPalette = new SwatchPage(); - - docPalette->_name = "Auto"; - docPalettes[0] = docPalette; - } - - loadEmUp(); - if ( !systemSwatchPages.empty() ) { - SwatchPage* first = 0; - int index = 0; - Glib::ustring targetName; - if ( !_prefs_path.empty() ) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - targetName = prefs->getString(_prefs_path + "/palette"); - if (!targetName.empty()) { - if (targetName == "Auto") { - first = docPalettes[0]; - } else { - //index++; - std::vector pages = _getSwatchSets(); - for ( std::vector::iterator iter = pages.begin(); iter != pages.end(); ++iter ) { - if ( (*iter)->_name == targetName ) { - first = *iter; - break; + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->fill.isSet()) { + if (it->style->fill.isPaintserver()) { + SPPaintServer * server = it->style->getFillPaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + if (_noLink.get_active()) { + Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); + clone->setAttribute( "osb:paint", "gradient", 0 ); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else if (grad->isSwatch()) { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); + + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); + if (repr->parent() != drepr) { + repr->parent()->removeChild(repr); + drepr->appendChild(repr); + } + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); } - index++; } + } else if (it->style->fill.isColor()) { + Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); + grad->setAttribute( "osb:paint", "solid", 0 ); + addStop(grad, it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); + if (page) { + page->appendChild(grad); + } else { + _currentDocument->getDefs()->appendChild(grad); + } + SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); + Inkscape::GC::release(grad); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); } } } + } +} - if ( !first ) { - first = docPalettes[0]; - _currentIndex = 0; - } else { - _currentIndex = index; - } - - _rebuild(); - - Gtk::RadioMenuItem::Group groupOne; - - int i = 0; - std::vector swatchSets = _getSwatchSets(); - for ( std::vector::iterator it = swatchSets.begin(); it != swatchSets.end(); ++it) { - SwatchPage* curr = *it; - Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); - if ( curr == first ) { - hotItem = single; +void SwatchesPanel::AddSelectedStroke(SPGroup* page) +{ + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->stroke.isSet()) { + if (it->style->stroke.isPaintserver()) { + SPPaintServer * server = it->style->getStrokePaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + if (_noLink.get_active()) { + Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); + clone->setAttribute( "osb:paint", "gradient", 0 ); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else if (grad->isSwatch()) { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); + + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); + if (repr->parent() != drepr) { + repr->parent()->removeChild(repr); + drepr->appendChild(repr); + } + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } + } + } else if (it->style->stroke.isColor()) { + Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); + grad->setAttribute( "osb:paint", "solid", 0 ); + addStop(grad, it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); + if (page) { + page->appendChild(grad); + } else { + _currentDocument->getDefs()->appendChild(grad); + } + SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); + Inkscape::GC::release(grad); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); + } } - _regItem( single, 3, i ); - - i++; } } +} - if (Glib::ustring(prefsPath) == "/dialogs/swatches") { - Gtk::Requisition sreq; -#if WITH_GTKMM_3_0 - Gtk::Requisition sreq_natural; - get_preferred_size(sreq_natural, sreq); -#else - sreq = size_request(); -#endif - int minHeight = 60; - if (sreq.height < minHeight) { - set_size_request(70, minHeight); - } +void SwatchesPanel::_addBIButtonClicked(GdkEventButton* event) +{ + if (popUpImportMenu) { + popUpImportMenu->popup(event->button, event->time); } +} - _getContents()->pack_start(*_holder, Gtk::PACK_EXPAND_WIDGET); - _setTargetFillable(_holder); - - show_all_children(); - - restorePanelPrefs(); - if ( hotItem ) { - hotItem->set_active(); +void SwatchesPanel::NewGroupBI() +{ + if (_currentDocument) { + Inkscape::XML::Node * page = SwatchDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (SwatchDocument->getObjectById(id)); + + page->setAttribute("id", id); + + SwatchDocument->getDefs()->appendChild(page); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } } -SwatchesPanel::~SwatchesPanel() +void SwatchesPanel::NewGroup() { - _trackDocument( this, 0 ); - - _documentConnection.disconnect(); - _selChanged.disconnect(); - - if ( _clear ) { - delete _clear; - } - if ( _remove ) { - delete _remove; - } - if ( _holder ) { - delete _holder; + if (_currentDocument) { + Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (_currentDocument->getObjectById(id)); + + page->setAttribute("id", id); + + _currentDocument->getDefs()->appendChild(page); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("New Swatch Group")); } } -void SwatchesPanel::setOrientation(SPAnchorType how) +void SwatchesPanel::SaveAs() { - // Must call the parent class or bad things might happen - Inkscape::UI::Widget::Panel::setOrientation( how ); - - if ( _holder ) - { - _holder->setOrientation(SP_ANCHOR_SOUTH); + if (_currentDocument) { + Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (_currentDocument->getObjectById(id)); + + page->setAttribute("id", id); + + std::vector toMove; + for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GRADIENT(it)) { + SPGradient* grad = SP_GRADIENT(it); + if (grad->isSwatch()) { + toMove.push_back(grad->getRepr()); + } + } + } + while (!toMove.empty()) { + Inkscape::XML::Node* repr = toMove.back(); + toMove.pop_back(); + repr->parent()->removeChild(repr); + page->appendChild(repr); + } + _currentDocument->getDefs()->appendChild(page); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Save Swatch Group")); } } -void SwatchesPanel::setDesktop( SPDesktop* desktop ) +void SwatchesPanel::Duplicate(SPGroup* oldpage) { - if ( desktop != _currentDesktop ) { - if ( _currentDesktop ) { - _documentConnection.disconnect(); - _selChanged.disconnect(); + if (_currentDocument) { + Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (_currentDocument->getObjectById(id)); + + page->setAttribute("id", id); + if (oldpage->label()) page->setAttribute("inkscape:label", oldpage->label()); + + for (SPObject *it = oldpage->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GRADIENT(it)) { + SPGradient* grad = SP_GRADIENT(it); + if (grad->isSwatch()) { + Inkscape::XML::Node * copy = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); + page->appendChild(copy); + Inkscape::GC::release(copy); + } + } } + _currentDocument->getDefs()->appendChild(page); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Duplicate Swatch Group")); + } +} - _currentDesktop = desktop; +void SwatchesPanel::_lblClick(GdkEventButton* event, SPGroup* page) +{ + Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); + + Gtk::MenuItem* mi; + Glib::ustring us = Glib::ustring::compose("%1", page ? (page->label() ? page->label() : page->getId()) : _("[Base]")); + mi = Gtk::manage(new Gtk::MenuItem(page ? (page->label() ? page->label() : page->getId()) : _("[Base]"))); + Gtk::Label* namelbl = dynamic_cast(mi->get_child()); + if (namelbl) { + namelbl->set_markup(us); + } + mi->show(); + mi->set_sensitive(false); + menu->append(*mi); + + Gtk::SeparatorMenuItem* sep; + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Fill"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedFill), page)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Stroke"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedStroke), page)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + if (page) { + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Up"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveUp), page)); + mi->show(); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Down"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveDown), page)); + mi->show(); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Duplicate"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Duplicate), page)); + mi->show(); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Remove), page)); + mi->show(); + menu->append(*mi); + } else { + mi = Gtk::manage(new Gtk::MenuItem(_("Create New Group"))); + mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); + mi->show(); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Save As New Group"))); + mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::SaveAs)); + mi->show(); + menu->append(*mi); + } + + menu->popup(event->button, event->time); +} - if ( desktop ) { - _currentDesktop->selection->connectChanged( - sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); +void SwatchesPanel::_defsChanged() +{ + if (_storeDoc) { + _storeDoc->clear(); + } + + while (!docWatchers.empty()) { + Inkscape::XML::NodeObserver* w = docWatchers.back(); + docWatchers.pop_back(); + delete w; + } + + std::vector tableChildren = _insideTable.get_children(); + for (std::vector::iterator c = tableChildren.begin(); c != tableChildren.end(); ++c) { + _insideTable.remove(**c); + } + + if (_currentDocument) { + Gtk::EventBox* eb; + Gtk::Label* lbl; + if (_showlabels) { + eb = Gtk::manage(new Gtk::EventBox()); + eb->add_events(Gdk::BUTTON_PRESS_MASK); + eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), NULL)); + + lbl = Gtk::manage(new Gtk::Label(_("[Base]"))); + eb->add(*lbl); + _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + } + Glib::ustring str1 = Glib::ustring(_("[None]")); + ColorItem* item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str1)); + //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); + item->setName(_("[None]")); + _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + + unsigned int i = 1; + for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GRADIENT(it)) { + SPGradient* grad = SP_GRADIENT(it); + if (grad->hasStops()) { + + GradientWatcher* w = new GradientWatcher(this, grad); + docWatchers.push_back(w); + + if (grad->isSwatch()) { + + for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { + StopWatcher* sw = new StopWatcher(this, s); + docWatchers.push_back(sw); + } - _currentDesktop->selection->connectModified( - sigc::hide(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection)))); + if (_storeDoc) { + Gtk::TreeModel::iterator iter = _storeDoc->append(); + Gtk::TreeModel::Row row = *iter; + row[_modelDoc->_colObject] = grad; + row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); + GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); + row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); + } + Glib::ustring str2 = Glib::ustring(it->label() ? it->label() : it->getId()); + item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str2)); + item->setGradient(grad); + //item->colorItemHandleButtonPress().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->setName(it->label() ? it->label() : it->getId()); + if (_showlabels) { + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } else { + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } - _currentDesktop->connectToolSubselectionChanged( - sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + i++; + } + } + } + } + + for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GROUP(it)) { + SwatchWatcher* w = new SwatchWatcher(this, it, false); + docWatchers.push_back(w); + + if (_showlabels) { + i += 20 - (i % 20); + eb = Gtk::manage(new Gtk::EventBox()); + eb->add_events(Gdk::BUTTON_PRESS_MASK); + eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), SP_GROUP(it))); + lbl = Gtk::manage(new Gtk::Label(it->label() ? it->label() : it->getId())); + eb->add(*lbl); + _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + } + + Gtk::TreeModel::iterator rowiter; + + if (_storeDoc) { + rowiter = _storeDoc->append(); + Gtk::TreeModel::Row row = *rowiter; + row[_modelDoc->_colObject] = it; + row[_modelDoc->_colLabel] = it->label() ? it->label() : it->getId(); + } + + for (SPObject *cit = it->firstChild(); cit != NULL; cit = cit->next) { + if (SP_IS_GRADIENT(cit)) { + SPGradient* grad = SP_GRADIENT(cit); + + if (grad->hasStops()) { + + GradientWatcher* w = new GradientWatcher(this, grad); + docWatchers.push_back(w); + + if (grad->isSwatch()) { + + for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { + StopWatcher* sw = new StopWatcher(this, s); + docWatchers.push_back(sw); + } - sigc::bound_mem_functor1 first = sigc::mem_fun(*this, &SwatchesPanel::_setDocument); - sigc::slot base2 = first; - sigc::slot slot2 = sigc::hide<0>( base2 ); - _documentConnection = desktop->connectDocumentReplaced( slot2 ); + if (_storeDoc && rowiter) { + Gtk::TreeModel::iterator iter = _storeDoc->append(rowiter->children()); + Gtk::TreeModel::Row row = *iter; + row[_modelDoc->_colObject] = grad; + row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); + GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); + row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); - _setDocument( desktop->doc() ); - } else { - _setDocument(0); + _editDoc.expand_to_path(_storeDoc->get_path(iter)); + } + Glib::ustring str3= Glib::ustring(cit->label() ? cit->label() : cit->getId()); + item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str3)); + item->setGradient(grad); + //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->setName(cit->label() ? cit->label() : cit->getId()); + if (_showlabels) { + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } else { + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } + i++; + } + } + } + } + } } } + + _scroller.show_all_children(); + _scroller.queue_draw(); } - -class DocTrack +Gtk::MenuItem* SwatchesPanel::_addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow) { -public: - DocTrack(SPDocument *doc, sigc::connection &docDestroy, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : - doc(doc), - updatePending(false), - lastGradientUpdate(0.0), - docDestroy(docDestroy), - gradientRsrcChanged(gradientRsrcChanged), - defsChanged(defsChanged), - defsModified(defsModified) - { - if ( !timer ) { - timer = new Glib::Timer(); - refreshTimer = Glib::signal_timeout().connect( sigc::ptr_fun(handleTimerCB), 33 ); + Gtk::MenuItem* mi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId(),1)); + Gtk::Menu* m = NULL; + + Gtk::TreeModel::Row* r; + if (_store) { + Gtk::TreeModel::iterator iter = parentRow ? _store->append(parentRow->children()) : _store->append(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = group; + row[_model->_colLabel] = group->label() ? group->label() : group->getId(); + + if (SP_IS_GROUP(group->parent) && SP_GROUP(group->parent)->expanded()) { + _editBI.expand_to_path(_store->get_path(iter)); } - timerRefCount++; + r = &row; + } else { + r = NULL; } - - ~DocTrack() + + bool hasswatches = false; + for (SPObject * obj = group->firstChild(); obj != NULL; obj = obj->next) { - timerRefCount--; - if ( timerRefCount <= 0 ) { - refreshTimer.disconnect(); - timerRefCount = 0; - if ( timer ) { - timer->stop(); - delete timer; - timer = 0; + if (SP_IS_GROUP(obj)) { + if (!m) { + m = manage(new Gtk::Menu()); + m->show_all(); + mi->set_submenu(*m); + + Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(_("[All]"))); + basemi->show(); + Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); + if (namelbl) { + namelbl->set_markup(_("[All]")); + } + basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, true)); + m->append(*basemi); + + Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + m->append(*sep); } + SwatchWatcher* w = new SwatchWatcher(this, obj, true); + rootWatchers.push_back(w); + m->append(*_addSwatchGroup(SP_GROUP(obj), r)); + } else if (SP_IS_GRADIENT(obj)) { + hasswatches = true; } - if (doc) { - docDestroy.disconnect(); - gradientRsrcChanged.disconnect(); - defsChanged.disconnect(); - defsModified.disconnect(); - doc = NULL; + } + if (!m) { + mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); + } else if (hasswatches) { + Glib::ustring us = Glib::ustring::compose("%1", group->label() ? group->label() : group->getId()); + Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId())); + basemi->show(); + Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); + if (namelbl) { + namelbl->set_markup(us); } + basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); + m->prepend(*basemi); } + mi->show(); + return mi; +} - static bool handleTimerCB(); - - /** - * Checks if update should be queued or executed immediately. - * - * @return true if the update was queued and should not be immediately executed. - */ - static bool queueUpdateIfNeeded(SPDocument *doc); - - static Glib::Timer *timer; - static int timerRefCount; - static sigc::connection refreshTimer; - - SPDocument *doc; - bool updatePending; - double lastGradientUpdate; - sigc::connection docDestroy; - sigc::connection gradientRsrcChanged; - sigc::connection defsChanged; - sigc::connection defsModified; - -private: - DocTrack(DocTrack const &); // no copy - DocTrack &operator=(DocTrack const &); // no assign -}; - -Glib::Timer *DocTrack::timer = 0; -int DocTrack::timerRefCount = 0; -sigc::connection DocTrack::refreshTimer; +void SwatchesPanel::_swatchesChanged() +{ + while (!rootWatchers.empty()) { + Inkscape::XML::NodeObserver* w = rootWatchers.back(); + rootWatchers.pop_back(); + delete w; + } -static const double DOC_UPDATE_THREASHOLD = 0.090; + std::vector menuChildren = popUpMenu->get_children(); + for (std::vector::iterator c = menuChildren.begin(); c != menuChildren.end(); ++c) { + popUpMenu->remove(**c); + } + + if (_store) { + _store->clear(); + } + + Gtk::MenuItem* mi; + + for (SPObject * obj = SwatchDocument->getDefs()->firstChild(); obj != NULL; obj = obj->next) + { + if (SP_IS_GROUP(obj)) { + SwatchWatcher* w = new SwatchWatcher(this, obj, true); + rootWatchers.push_back(w); + popUpMenu->append(*_addSwatchGroup(SP_GROUP(obj), NULL)); + + } + } + Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + popUpMenu->append(*sep); + + mi = manage(new Gtk::MenuItem(_("New Swatch Group..."),1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); + mi->show(); + popUpMenu->append(*mi); + + mi = manage(new Gtk::MenuItem(_("Add Swatch File..."),1)); + mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, false)); + mi->show(); + popUpMenu->append(*mi); + + mi = manage(new Gtk::MenuItem(_("Import Swatch File..."),1)); + mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, true)); + mi->show(); + popUpMenu->append(*mi); +} -bool DocTrack::handleTimerCB() +void SwatchesPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ) { - double now = timer->elapsed(); + bool set = false; + + if ( iconName ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + set = true; + } - std::vector needCallback; - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { - DocTrack *track = *it; - if ( track->updatePending && ( (now - track->lastGradientUpdate) >= DOC_UPDATE_THREASHOLD) ) { - needCallback.push_back(track); + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !set && action && action->image ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + set = true; + } } } + + btn.set_tooltip_text (fallback); + + if ( !set ) { + btn.set_label( fallback ); + } +} - for (std::vector::iterator it = needCallback.begin(); it != needCallback.end(); ++it) { - DocTrack *track = *it; - if ( std::find(docTrackings.begin(), docTrackings.end(), track) != docTrackings.end() ) { // Just in case one gets deleted while we are looping - // Note: calling handleDefsModified will call queueUpdateIfNeeded and thus update the time and flag. - SwatchesPanel::handleDefsModified(track->doc); +void SwatchesPanel::_addButtonClicked(GdkEventButton* event) { + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3 || event->button == 1) ) { + if (popUpMenu) { + popUpMenu->popup(event->button, event->time); } } +} - return true; +void SwatchesPanel::NoLinkToggled() { + static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring nolink = Glib::ustring::compose("%1/nolink", _prefs_path); + prefs->setBool(nolink, _noLink.get_active()); } -bool DocTrack::queueUpdateIfNeeded( SPDocument *doc ) +bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) { - bool deferProcessing = false; - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { - DocTrack *track = *it; - if ( track->doc == doc ) { - double now = timer->elapsed(); - double elapsed = now - track->lastGradientUpdate; - - if ( elapsed < DOC_UPDATE_THREASHOLD ) { - deferProcessing = true; - track->updatePending = true; - } else { - track->lastGradientUpdate = now; - track->updatePending = false; - } + static unsigned doubleclick = 0; + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } - break; + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _editBI.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnBI) { + // Double click on the Layer name, enable editing + _text_rendererBI->property_editable() = true; + _editBI.set_cursor (path, *_name_columnBI, true); + grab_focus(); } } - return deferProcessing; + + return false; } -void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) +bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) { - SPDocument *oldDoc = NULL; - if (docPerPanel.find(panel) != docPerPanel.end()) { - oldDoc = docPerPanel[panel]; - if (!oldDoc) { - docPerPanel.erase(panel); // Should not be needed, but clean up just in case. - } - } - if (oldDoc != document) { - if (oldDoc) { - docPerPanel[panel] = NULL; - bool found = false; - for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { - found = (it->second == document); - } - if (!found) { - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ - if ((*it)->doc == oldDoc) { - delete *it; - docTrackings.erase(it); - break; - } + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); + if (iter && !_text_rendererBI->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_rendererBI->property_editable() = true; + _editBI.set_cursor(*path, *_name_columnBI, true); + grab_focus(); + return true; } } } - - if (document) { - bool found = false; - for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { - found = (it->second == document); - } - docPerPanel[panel] = document; - if (!found) { - sigc::connection conn0 = document->connectDestroy(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDocumentDestroy), document)); - sigc::connection conn1 = document->connectResourcesChanged( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) ); - sigc::connection conn2 = document->getDefs()->connectRelease( sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document)) ); - sigc::connection conn3 = document->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document))) ); - - DocTrack *dt = new DocTrack(document, conn0, conn1, conn2, conn3); - docTrackings.push_back(dt); - - if (docPalettes.find(document) == docPalettes.end()) { - SwatchPage *docPalette = new SwatchPage(); - docPalette->_name = "Auto"; - docPalettes[document] = docPalette; + case GDK_KEY_Delete: { + + Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); + if (iter) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj) { + obj->deleteObject(false); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } } + return true; } + break; } + return false; } -void SwatchesPanel::_setDocument( SPDocument *document ) +void SwatchesPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) { - if ( document != _currentDocument ) { - _trackDocument(this, document); - _currentDocument = document; - handleGradientsChange( document ); - } + Gtk::TreeModel::iterator iter = _editBI.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_rendererBI->property_editable() = false; } -static void recalcSwatchContents(SPDocument* doc, - boost::ptr_vector &tmpColors, - std::map &previewMappings, - std::map &gradMappings) +void SwatchesPanel::_handleEditingCancelled() { - std::vector newList; - - if (doc) { - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( grad->isSwatch() ) { - newList.push_back(SP_GRADIENT(item->data)); + _text_rendererBI->property_editable() = false; +} + +void SwatchesPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && SwatchDocument) { + SPObject* obj = row[_model->_colObject]; + if ( obj ) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } } } +} - if ( !newList.empty() ) { - std::reverse(newList.begin(), newList.end()); - for ( std::vector::iterator it = newList.begin(); it != newList.end(); ++it ) - { - SPGradient* grad = *it; - - cairo_surface_t *preview = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - PREVIEW_PIXBUF_WIDTH, VBLOCK); - cairo_t *ct = cairo_create(preview); - - Glib::ustring name( grad->getId() ); - ColorItem* item = new ColorItem( 0, 0, 0, name ); - - cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); - cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(grad, PREVIEW_PIXBUF_WIDTH); - cairo_set_source(ct, check); - cairo_paint(ct); - cairo_set_source(ct, gradient); - cairo_paint(ct); - - cairo_destroy(ct); - cairo_pattern_destroy(gradient); - cairo_pattern_destroy(check); - - cairo_pattern_t *prevpat = cairo_pattern_create_for_surface(preview); - cairo_surface_destroy(preview); +void SwatchesPanel::_setCollapsed(SPGroup * group) +{ + group->setExpanded(false); + group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + for (SPObject *iter = group->children; iter != NULL; iter = iter->next) + { + if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + } +} - previewMappings[item] = prevpat; +void SwatchesPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; - tmpColors.push_back(item); - gradMappings[item] = grad; + SPObject* obj = row[_model->_colObject]; + if (obj && SP_IS_GROUP(obj)) + { + if (isexpanded) + { + SP_GROUP(obj)->setExpanded(isexpanded); + obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + else + { + _setCollapsed(SP_GROUP(obj)); } } + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } -void SwatchesPanel::handleDocumentDestroy(SPDocument *document) +void SwatchesPanel::_deleteButtonClicked() { - if (document) { - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ - if ((*it)->doc == document) { - delete *it; - docTrackings.erase(it); - break; - } + Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPObject* obj = row[_model->_colObject]; + if (obj) { + obj->deleteObject(false); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } + } +} - if (docPalettes.find(document) != docPalettes.end()) { - docPalettes.erase(document); +bool SwatchesPanel::_handleButtonEventDoc(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + // TODO - fix to a better is-popup function + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _editDoc.get_path_at_pos( x, y, path ) ) { + Gtk::TreeModel::Children::iterator iter = _editDoc.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_modelDoc->_colObject]; + if (SP_IS_GRADIENT(obj)) { + _swatchClicked(event, SP_GRADIENT(obj)); + } else if (SP_IS_GROUP(obj)) { + _lblClick(event, SP_GROUP(obj)); + } else { + _lblClick(event, NULL); + } + } else { + _lblClick(event, NULL); } + } + + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - if (it->second == document) { - SwatchesPanel* swp = it->first; - std::vector pages = swp->_getSwatchSets(); - if ((swp->_currentIndex >= static_cast(pages.size())) && (pages.size() > 0)) - { - swp->_setSelectedIndex(swp->_getSwatchSets().size() - 1); - } - swp->_rebuild(); - docPerPanel.erase(it); - break; - } + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _editDoc.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnDoc) { + // Double click on the Layer name, enable editing + _text_rendererDoc->property_editable() = true; + _editDoc.set_cursor (path, *_name_columnDoc, true); + grab_focus(); } } + + return false; } -void SwatchesPanel::handleGradientsChange(SPDocument *document) +void SwatchesPanel::_deleteButtonClickedDoc() { - SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; - if (docPalette) { - boost::ptr_vector tmpColors; - std::map tmpPrevs; - std::map tmpGrads; - recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - - for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { - it->first->setPattern(it->second); - cairo_pattern_destroy(it->second); + Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); + if (iter) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_modelDoc->_colObject]; + if (SP_IS_GRADIENT(obj)) { + RemoveSwatch(SP_GRADIENT(obj)); + } else if (SP_IS_GROUP(obj)) { + Remove(SP_GROUP(obj)); } + } +} - for (std::map::iterator it = tmpGrads.begin(); it != tmpGrads.end(); ++it) { - it->first->setGradient(it->second); - } - - docPalette->_colors.swap(tmpColors); - - // Figure out which SwatchesPanel instances are affected and update them. - - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - if (it->second == document) { - SwatchesPanel* swp = it->first; - std::vector pages = swp->_getSwatchSets(); - SwatchPage* curr = pages[swp->_currentIndex]; - if (curr == docPalette) { - swp->_rebuild(); +bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) +{ + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); + if (iter && !_text_rendererDoc->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_modelDoc->_colObject]; + if (obj) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_rendererDoc->property_editable() = true; + _editDoc.set_cursor(*path, *_name_columnDoc, true); + grab_focus(); + return true; } } } + case GDK_KEY_Delete: { + + _deleteButtonClickedDoc(); + return true; + } + break; } + return false; } -void SwatchesPanel::handleDefsModified(SPDocument *document) +void SwatchesPanel::_renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name) { - SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; - if (docPalette && !DocTrack::queueUpdateIfNeeded(document) ) { - boost::ptr_vector tmpColors; - std::map tmpPrevs; - std::map tmpGrads; - recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - - if ( tmpColors.size() != docPalette->_colors.size() ) { - handleGradientsChange(document); - } else { - int cap = std::min(docPalette->_colors.size(), tmpColors.size()); - for (int i = 0; i < cap; i++) { - ColorItem *newColor = &tmpColors[i]; - ColorItem *oldColor = &docPalette->_colors[i]; - if ( (newColor->def.getType() != oldColor->def.getType()) || - (newColor->def.getR() != oldColor->def.getR()) || - (newColor->def.getG() != oldColor->def.getG()) || - (newColor->def.getB() != oldColor->def.getB()) ) { - oldColor->def.setRGB(newColor->def.getR(), newColor->def.getG(), newColor->def.getB()); - } - if (tmpGrads.find(newColor) != tmpGrads.end()) { - oldColor->setGradient(tmpGrads[newColor]); - } - if ( tmpPrevs.find(newColor) != tmpPrevs.end() ) { - oldColor->setPattern(tmpPrevs[newColor]); - } + if ( row && SwatchDocument) { + SPObject* obj = row[_modelDoc->_colObject]; + if ( obj ) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); } } - - for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { - cairo_pattern_destroy(it->second); - } } } +void SwatchesPanel::_handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _editDoc.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObjectDoc(row, new_text); + _text_rendererDoc->property_editable() = false; +} + +void SwatchesPanel::_handleEditingCancelledDoc() +{ + _text_rendererDoc->property_editable() = false; +} -std::vector SwatchesPanel::_getSwatchSets() const +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool SwatchesPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) { - std::vector tmp; - if (docPalettes.find(_currentDocument) != docPalettes.end()) { - tmp.push_back(docPalettes[_currentDocument]); + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + bool _dnd_top = false; + _dnd_into = false; + _dnd_target = SwatchDocument->getDefs()->lastChild(); + Gtk::TreeModel::iterator itersel = _editBI.get_selection()->get_selected(); + if (!itersel) { + return true; } + Gtk::TreeModel::Row rowsel = *itersel; + _dnd_source = rowsel[_model->_colObject]; - tmp.insert(tmp.end(), userSwatchPages.begin(), userSwatchPages.end()); - tmp.insert(tmp.end(), systemSwatchPages.begin(), systemSwatchPages.end()); + if (!_dnd_source) { + return true; + } + + if (_editBI.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _editBI.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y < (int)(cell_height * 1/3)) { + Gtk::TreeModel::Path next_path = target_path; + if (next_path.prev()) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + _dnd_top = true; + // Drop into the top level + _dnd_target = NULL; + } + } + } + if (!_dnd_top) { + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (obj) { + _dnd_target = obj; + } + } + } + } + + if (_dnd_source != _dnd_target) { + + Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; + Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); + + if (target_ref != our_ref) { + if (!target_ref) { + target_ref = SwatchDocument->getDefs()->getRepr(); + if (target_ref != our_ref->parent()) { + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else { + our_ref->parent()->changeOrder(our_ref, NULL); + } + } else if (_dnd_into) { + // Move this inside of the target at the end + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else if (target_ref->parent() != our_ref->parent()) { + // Change in parent, need to remove and add + our_ref->parent()->removeChild(our_ref); + target_ref->parent()->addChild(our_ref, target_ref); + } else { + // Same parent, just move + our_ref->parent()->changeOrder(our_ref, target_ref); + } + } + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } - return tmp; + return true; } -void SwatchesPanel::_updateFromSelection() +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool SwatchesPanel::_handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time) { - SwatchPage *docPalette = (docPalettes.find(_currentDocument) != docPalettes.end()) ? docPalettes[_currentDocument] : 0; - if ( docPalette ) { - Glib::ustring fillId; - Glib::ustring strokeId; - - SPStyle *tmpStyle = sp_style_new( sp_desktop_document(_currentDesktop) ); - int result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_FILL ); - switch (result) { - case QUERY_STYLE_SINGLE: - case QUERY_STYLE_MULTIPLE_AVERAGED: - case QUERY_STYLE_MULTIPLE_SAME: - { - if (tmpStyle->fill.set && tmpStyle->fill.isPaintserver()) { - SPPaintServer* server = tmpStyle->getFillPaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient* target = 0; - SPGradient* grad = SP_GRADIENT(server); - - if ( grad->isSwatch() ) { - target = grad; - } else if ( grad->ref ) { - SPGradient *tmp = grad->ref->getObject(); - if ( tmp && tmp->isSwatch() ) { - target = tmp; - } - } - if ( target ) { - //XML Tree being used directly here while it shouldn't be - gchar const* id = target->getRepr()->attribute("id"); - if ( id ) { - fillId = id; - } - } - } + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + bool _dnd_top = false; + _dnd_into = false; + _dnd_target = _currentDocument->getDefs()->lastChild(); + Gtk::TreeModel::iterator itersel = _editDoc.get_selection()->get_selected(); + if (!itersel) { + return true; + } + Gtk::TreeModel::Row rowsel = *itersel; + _dnd_source = rowsel[_modelDoc->_colObject]; + + if (!_dnd_source) { + return true; + } + + if (_editDoc.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _editDoc.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y < (int)(cell_height * 1/3)) { + Gtk::TreeModel::Path next_path = target_path; + if (next_path.prev()) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_storeDoc->iter_is_valid(_storeDoc->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + _dnd_top = true; + // Drop into the top level + _dnd_target = NULL; } - break; } } - - result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); - switch (result) { - case QUERY_STYLE_SINGLE: - case QUERY_STYLE_MULTIPLE_AVERAGED: - case QUERY_STYLE_MULTIPLE_SAME: - { - if (tmpStyle->stroke.set && tmpStyle->stroke.isPaintserver()) { - SPPaintServer* server = tmpStyle->getStrokePaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient* target = 0; - SPGradient* grad = SP_GRADIENT(server); - if ( grad->isSwatch() ) { - target = grad; - } else if ( grad->ref ) { - SPGradient *tmp = grad->ref->getObject(); - if ( tmp && tmp->isSwatch() ) { - target = tmp; - } - } - if ( target ) { - //XML Tree being used directly here while it shouldn't be - gchar const* id = target->getRepr()->attribute("id"); - if ( id ) { - strokeId = id; - } + if (!_dnd_top) { + Gtk::TreeModel::iterator iter = _storeDoc->get_iter(target_path); + if (_storeDoc->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_modelDoc->_colObject]; + if (obj) { + _dnd_target = obj; + if (SP_IS_GRADIENT(obj)) { + _dnd_into = false; + if (SP_IS_GROUP(_dnd_source)) { + _dnd_target = obj->parent; } + } else if (SP_IS_GROUP(_dnd_source)) { + _dnd_into = false; } } - break; } } - sp_style_unref(tmpStyle); - - for ( boost::ptr_vector::iterator it = docPalette->_colors.begin(); it != docPalette->_colors.end(); ++it ) { - ColorItem* item = &*it; - bool isFill = (fillId == item->def.descr); - bool isStroke = (strokeId == item->def.descr); - item->setState( isFill, isStroke ); + } + + if (_dnd_source != _dnd_target) { + + Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; + Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); + + if (target_ref != our_ref) { + if (!target_ref) { + target_ref = _currentDocument->getDefs()->getRepr(); + if (target_ref != our_ref->parent()) { + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else { + our_ref->parent()->changeOrder(our_ref, NULL); + } + } else if (_dnd_into) { + // Move this inside of the target at the end + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else if (target_ref->parent() != our_ref->parent()) { + // Change in parent, need to remove and add + our_ref->parent()->removeChild(our_ref); + target_ref->parent()->addChild(our_ref, target_ref); + } else { + // Same parent, just move + our_ref->parent()->changeOrder(our_ref, target_ref); + } } + DocumentUndo::done( _currentDocument , SP_VERB_DIALOG_SWATCHES, + _("Moved Swatches")); } + + return true; } -void SwatchesPanel::_handleAction( int setId, int itemId ) + +/** + * Constructor + */ +SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : + Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, ""), + _scroller(), + _insideTable(1, 2), + _insideV(), + _insideH(), + _buttonsRow(), + _outsideV(), + _noLink(_("Don't Link")), + _showlabels(showLabels), + _store(0), + _scrollerBI(), + _editBI(), + _buttonsRowBI(), + _editBIV(), + _storeDoc(0), + _scrollerDoc(), + _editDoc(), + _buttonsRowDoc(), + _editDocV(), + _notebook(), + rootWatcher(0), + docWatcher(0), + _currentDesktop(0), + _currentDocument(0) { - switch( setId ) { - case 3: + _insideH.pack_start(_insideTable, Gtk::PACK_SHRINK); + if (_showlabels) { + _insideV.pack_start(_insideH, Gtk::PACK_SHRINK); + _scroller.add(_insideV); + } else { + _scroller.property_height_request() = 45; + _scroller.add(_insideH); + } + + popUpMenu = manage( new Gtk::Menu() ); + popUpMenu->show_all_children(); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Add Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked) ); + _buttonsRow.pack_start(*btn, Gtk::PACK_SHRINK); + +// btn = manage( new Gtk::Button() ); +// _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_DISCONNECT, C_("Unlink", "New") ); +// _buttonsRow.pack_end(*btn, Gtk::PACK_SHRINK); + + static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring nolink = Glib::ustring::compose("%1/nolink", prefsPath); + _noLink.set_tooltip_text(_("Don't link swatches")); + _noLink.set_active(prefs->getBool(nolink, false)); + _noLink.signal_toggled().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NoLinkToggled)); + _buttonsRow.pack_end(_noLink, Gtk::PACK_SHRINK); + + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_NONE); + + if (_showlabels) { + _outsideV.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + _outsideV.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); + + _notebook.append_page(_outsideV, "Use"); + + { + ModelColumnsDoc *zoop = new ModelColumnsDoc(); + _modelDoc = zoop; + + _storeDoc = Gtk::TreeStore::create( *zoop ); + + _editDoc.set_model( _storeDoc ); + _editDoc.set_headers_visible(false); + _editDoc.set_reorderable(true); + _editDoc.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked)); + _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClickedDoc))); + _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + + _pixbuf_rendererDoc = manage(new Gtk::CellRendererPixbuf()); + int pixbufColNum = _editDoc.append_column("Pixbuf", *_pixbuf_rendererDoc) - 1; + _pixbuf_columnDoc = _editDoc.get_column(pixbufColNum); + _pixbuf_columnDoc->add_attribute(_pixbuf_rendererDoc->property_pixbuf(), _modelDoc->_colPixbuf); + + _text_rendererDoc = manage(new Gtk::CellRendererText()); + int nameColNum = _editDoc.append_column("Name", *_text_rendererDoc) - 1; + _name_columnDoc = _editDoc.get_column(nameColNum); + _name_columnDoc->add_attribute(_text_rendererDoc->property_text(), _modelDoc->_colLabel); + + _text_rendererDoc->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditedDoc) ); + _text_rendererDoc->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelledDoc) ); + + _editDoc.set_expander_column( *_editDoc.get_column(nameColNum) ); + + _editDoc.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); + _editDoc.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); + _editDoc.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEventDoc), false ); + + _editDoc.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDropDoc), false); + + _scrollerDoc.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scrollerDoc.set_shadow_type(Gtk::SHADOW_IN); + _scrollerDoc.add(_editDoc); + + _editDocV.pack_start(_scrollerDoc, Gtk::PACK_EXPAND_WIDGET); + _editDocV.pack_end(_buttonsRowDoc, Gtk::PACK_SHRINK); + + _notebook.append_page(_editDocV, "Edit"); + } + { - _setSelectedIndex(itemId); + popUpImportMenu = Gtk::manage(new Gtk::Menu()); + + Gtk::MenuItem* mi = Gtk::manage(new Gtk::MenuItem(_("New Swatch Group..."))); + mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroupBI)); + mi->show(); + popUpImportMenu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Import Swatch File..."))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), false, true)); + mi->show(); + popUpImportMenu->append(*mi); + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + _editBI.set_model( _store ); + _editBI.set_headers_visible(false); + _editBI.set_reorderable(true); + _editBI.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); + btn->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::_addBIButtonClicked)); + _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClicked))); + _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); + + _text_rendererBI = manage(new Gtk::CellRendererText()); + int nameColNum = _editBI.append_column("Name", *_text_rendererBI) - 1; + _name_columnBI = _editBI.get_column(nameColNum); + _name_columnBI->add_attribute(_text_rendererBI->property_text(), _model->_colLabel); + + _text_rendererBI->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEdited) ); + _text_rendererBI->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelled) ); + + _editBI.set_expander_column( *_editBI.get_column(nameColNum) ); + + _editBI.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); + _editBI.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); + _editBI.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEvent), false ); + + _editBI.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDrop), false); + _editBI.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), false)); + _editBI.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), true)); + + _scrollerBI.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scrollerBI.set_shadow_type(Gtk::SHADOW_IN); + _scrollerBI.add(_editBI); + + _editBIV.pack_start(_scrollerBI, Gtk::PACK_EXPAND_WIDGET); + _editBIV.pack_end(_buttonsRowBI, Gtk::PACK_SHRINK); + + _notebook.append_page(_editBIV, "Edit Built-In"); } - break; + + _getContents()->pack_end(_notebook, Gtk::PACK_EXPAND_WIDGET); + } else { + //_outsideV.pack_end(_scroller, Gtk::PACK_SHRINK); + _buttonsRow.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); + //_getContents()->pack_end(_outsideV, Gtk::PACK_SHRINK); + _getContents()->pack_end(_buttonsRow, Gtk::PACK_SHRINK); } + + loadPalletFile(); + + rootWatcher = new SwatchWatcher(this, SwatchDocument->getDefs(), true); + SwatchDocument->getDefs()->getRepr()->addObserver(*rootWatcher); + _swatchesChanged(); } -void SwatchesPanel::_setSelectedIndex( int index ) +SwatchesPanel::~SwatchesPanel() { - std::vector pages = _getSwatchSets(); - if ( index >= 0 && index < static_cast(pages.size()) ) { - _currentIndex = index; + if (rootWatcher) { + rootWatcher->_repr->removeObserver(*rootWatcher); + delete rootWatcher; + } + + if (docWatcher) { + docWatcher->_repr->removeObserver(*docWatcher); + delete docWatcher; + } + + _documentConnection.disconnect(); + _selChanged.disconnect(); +} - if ( !_prefs_path.empty() ) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name); +void SwatchesPanel::setDesktop( SPDesktop* desktop ) +{ + Inkscape::UI::Widget::Panel::setDesktop(desktop); + if ( desktop != _currentDesktop ) { + if ( _currentDesktop ) { + _documentConnection.disconnect(); + _selChanged.disconnect(); } - _rebuild(); + _currentDesktop = desktop; + + if ( desktop ) { + //_currentDesktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + + _documentConnection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &SwatchesPanel::_setDocument)); + + _setDocument( desktop, desktop->doc() ); + } else { + _setDocument(0, 0); + } } } -void SwatchesPanel::_rebuild() +void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) { - std::vector pages = _getSwatchSets(); - if (_currentIndex < static_cast(pages.size())) { - SwatchPage* curr = pages[_currentIndex]; - _holder->clear(); - - if ( curr->_prefWidth > 0 ) { - _holder->setColumnPref( curr->_prefWidth ); + if ( document != _currentDocument ) { + if (docWatcher) { + docWatcher->_repr->removeObserver(*docWatcher); + delete docWatcher; + docWatcher = NULL; } - _holder->freezeUpdates(); - // TODO restore once 'clear' works _holder->addPreview(_clear); - _holder->addPreview(_remove); - for ( boost::ptr_vector::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) { - _holder->addPreview(&*it); + _currentDocument = document; + + if (_currentDocument) { + docWatcher = new SwatchWatcher(this, _currentDocument->getDefs(), false); + _currentDocument->getDefs()->getRepr()->addObserver(*docWatcher); } - _holder->thawUpdates(); + _defsChanged(); } } @@ -1241,6 +2323,48 @@ void SwatchesPanel::_rebuild() } //namespace UI } //namespace Inkscape +//should be okay to add this here +guint get_group0_keyval(GdkEventKey *event) { + guint keyval = 0; + gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( + gdk_display_get_default()), event->hardware_keycode, + (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, + NULL, NULL, NULL); + return keyval; +} + +void +sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) +{ + + bool intercepted = false; + + if (gradient->isSolid()) { + ColorRGBA color(gradient->getFirstStop()->getEffectiveColor().toRGBA32(gradient->getFirstStop()->opacity)); + guint32 rgba = SP_RGBA32_F_COMPOSE(color[0], color[1], color[2], color[3]); + gchar b[64]; + sp_svg_write_color(b, sizeof(b), rgba); + SPCSSAttr *css = sp_repr_css_attr_new(); + if (fill) { + sp_repr_css_set_property(css, "fill", b); + Inkscape::CSSOStringStream osalpha; + osalpha << color[3]; + sp_repr_css_set_property(css, "fill-opacity", osalpha.str().c_str()); + } else { + sp_repr_css_set_property(css, "stroke", b); + Inkscape::CSSOStringStream osalpha; + osalpha << color[3]; + sp_repr_css_set_property(css, "stroke-opacity", osalpha.str().c_str()); + } + intercepted = desktop->_set_style_signal.emit(css); + } + + if (!intercepted) { + for (const GSList *it = desktop->selection->itemList(); it != NULL; it = it->next) { + sp_item_set_gradient(SP_ITEM(it->data), gradient, SP_IS_RADIALGRADIENT(gradient) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, !fill ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); + } + } +} /* Local Variables: diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h index 3abb81d98..cb8f87962 100644 --- a/src/ui/dialog/swatches.h +++ b/src/ui/dialog/swatches.h @@ -12,66 +12,161 @@ #include "ui/widget/panel.h" #include "enums.h" +#include "sp-object.h" +#include "sp-item-group.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sp-gradient.h" +#include "xml/node-observer.h" namespace Inkscape { namespace UI { -class PreviewHolder; - namespace Dialogs { -class ColorItem; -class SwatchPage; -class DocTrack; - /** * A panel that displays paint swatches. */ class SwatchesPanel : public Inkscape::UI::Widget::Panel { public: - SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches"); + SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches", bool showLabels = true); virtual ~SwatchesPanel(); - + static SwatchesPanel& getInstance(); - virtual void setOrientation(SPAnchorType how); - virtual void setDesktop( SPDesktop* desktop ); virtual SPDesktop* getDesktop() {return _currentDesktop;} - virtual int getSelectedIndex() {return _currentIndex;} // temporary - protected: - static void handleDocumentDestroy(SPDocument *document); - static void handleGradientsChange(SPDocument *document); - - virtual void _updateFromSelection(); - virtual void _handleAction( int setId, int itemId ); - virtual void _setDocument( SPDocument *document ); - virtual void _setSelectedIndex( int index ); - virtual void _rebuild(); - virtual std::vector _getSwatchSets() const; + virtual void _setDocument( SPDesktop* desktop, SPDocument *document ); private: + class ModelColumns; + class ModelColumnsDoc; + + class StopWatcher; + class GradientWatcher; + class SwatchWatcher; + SwatchesPanel(SwatchesPanel const &); // no copy SwatchesPanel &operator=(SwatchesPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ); + + void _setSelectionSwatch(SPGradient* swatchItem, bool isStroke); + + void NoLinkToggled(); + void NewGroup(); + void NewGroupBI(); + void _addBIButtonClicked(GdkEventButton* event); + void Duplicate(SPGroup* page); + void SaveAs(); + void AddSelectedFill(SPGroup* page); + void AddSelectedStroke(SPGroup* page); + void MoveUp(SPGroup* page); + void MoveDown(SPGroup* page); + void Remove(SPGroup* page); + + void SetSelectedFill(SPGradient* swatch); + void SetSelectedStroke(SPGradient* swatch); + void MoveSwatchUp(SPGradient* swatch); + void MoveSwatchDown(SPGradient* swatch); + void RemoveSwatch(SPGradient* swatch); + + void _lblClick(GdkEventButton* event, SPGroup* page); + void _addSwatchButtonClicked(SPGroup* swatch, bool recurse); + void _defsChanged(); + void _importButtonClicked(bool addToDoc, bool addToBI); + void _deleteButtonClicked(); + void _addButtonClicked(GdkEventButton* event); + void _swatchClicked(GdkEventButton* event, SPGradient* swatchItem); + + Gtk::MenuItem* _addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow); + void _swatchesChanged(); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _setCollapsed(SPGroup * group); + void _setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded); + + void _deleteButtonClickedDoc(); + bool _handleButtonEventDoc(GdkEventButton* event); + bool _handleKeyEventDoc(GdkEventKey *event); + + void _handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelledDoc(); + void _renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name); + + bool _handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + + Gtk::Menu *popUpMenu; + Gtk::Menu *popUpImportMenu; + + Gtk::ScrolledWindow _scroller; + Gtk::Table _insideTable; + Gtk::VBox _insideV; + Gtk::HBox _insideH; + Gtk::HBox _buttonsRow; + Gtk::VBox _outsideV; + Gtk::CheckButton _noLink; + bool _showlabels; + + SwatchesPanel::ModelColumns* _model; + Glib::RefPtr _store; + + Gtk::CellRendererText *_text_rendererBI; + Gtk::TreeView::Column *_name_columnBI; + Gtk::ScrolledWindow _scrollerBI; + Gtk::TreeView _editBI; + Gtk::HBox _buttonsRowBI; + Gtk::VBox _editBIV; + + SwatchesPanel::ModelColumnsDoc* _modelDoc; + Glib::RefPtr _storeDoc; + + Gtk::CellRendererText *_text_rendererDoc; + Gtk::CellRendererPixbuf *_pixbuf_rendererDoc; + Gtk::TreeView::Column *_name_columnDoc; + Gtk::TreeView::Column *_pixbuf_columnDoc; + Gtk::ScrolledWindow _scrollerDoc; + Gtk::TreeView _editDoc; + Gtk::HBox _buttonsRowDoc; + Gtk::VBox _editDocV; + + Gtk::Notebook _notebook; + + SwatchWatcher* rootWatcher; + std::vector rootWatchers; + + std::vector docWatchers; + SwatchWatcher* docWatcher; - static void _trackDocument( SwatchesPanel *panel, SPDocument *document ); - static void handleDefsModified(SPDocument *document); - - PreviewHolder* _holder; - ColorItem* _clear; - ColorItem* _remove; - int _currentIndex; SPDesktop* _currentDesktop; SPDocument* _currentDocument; + + bool _dnd_into; + SPObject* _dnd_source; + SPObject* _dnd_target; sigc::connection _documentConnection; sigc::connection _selChanged; - - friend class DocTrack; }; } //namespace Dialogs -- cgit v1.2.3 From 3093434e177d4bb7ccc57c1339fad00d47431c17 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 4 Mar 2014 21:24:03 -0500 Subject: Added a few swatch related functions (does not compile) (bzr r13090.1.15) --- src/ui/dialog/swatches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index a0c79b8ac..2956c6d17 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -68,7 +68,7 @@ #include "sp-radial-gradient.h" #include "color-rgba.h" #include "svg/css-ostringstream.h" -//#include "event-context.h" //no longer exists +#include "ui/tools/tool-base.h" //event-context.h #include #ifdef WIN32 #include -- cgit v1.2.3 From fcffbecabedd7c6bca1312918c918d57fee3cf8c Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 15:24:04 -0500 Subject: Added new swatches dialog (bzr r13090.1.16) --- src/ui/dialog/color-item.cpp | 860 ++++++++----------------------------------- src/ui/dialog/color-item.h | 108 ++---- src/ui/dialog/filedialog.h | 1 + src/ui/dialog/swatches.cpp | 48 +-- 4 files changed, 203 insertions(+), 814 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 7940c28ae..6eece0c17 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -11,18 +11,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - -#include #include +#include #include #include @@ -45,6 +36,7 @@ #include "xml/repr.h" #include "verbs.h" #include "widgets/gradient-vector.h" +#include "sp-paint-server.h" #include "color.h" // for SP_RGBA32_U_COMPOSE @@ -53,756 +45,206 @@ namespace Inkscape { namespace UI { namespace Dialogs { -static std::vector mimeStrings; -static std::map mimeToInt; - -#if ENABLE_MAGIC_COLORS -// TODO remove this soon: -extern std::vector possible; -#endif // ENABLE_MAGIC_COLORS - - -#if ENABLE_MAGIC_COLORS -static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b ) +bool ColorItem::on_enter_notify_event(GdkEventCrossing* event) { - bool changed = false; - - if ( node ) { - gchar const * val = node->attribute("inkscape:x-fill-tag"); - if ( val && (match == val) ) { - SPObject *obj = document->getObjectByRepr( node ); - - gchar c[64] = {0}; - sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, "fill", c ); - - sp_desktop_apply_css_recursive( obj, css, true ); - static_cast(obj)->updateRepr(); - - changed = true; - } - - val = node->attribute("inkscape:x-stroke-tag"); - if ( val && (match == val) ) { - SPObject *obj = document->getObjectByRepr( node ); - - gchar c[64] = {0}; - sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, "stroke", c ); - - sp_desktop_apply_css_recursive( (SPItem*)obj, css, true ); - ((SPItem*)obj)->updateRepr(); - - changed = true; - } - - Inkscape::XML::Node* first = node->firstChild(); - changed |= bruteForce( document, first, match, r, g, b ); - - changed |= bruteForce( document, node->next(), match, r, g, b ); - } - - return changed; -} -#endif // ENABLE_MAGIC_COLORS - -static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(false); - } -} - -static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(true); - } -} - -static gboolean handleEnterNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"), - item->def.descr.c_str()); - desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); - g_free(msg); - } - } - return FALSE; -} - -static gboolean handleLeaveNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - desktop->tipsMessageContext()->clear(); - } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"),def); + desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); + g_free(msg); } - return FALSE; + return Gtk::Widget::on_enter_notify_event(event); } -static void dieDieDie( GObject *obj, gpointer user_data ) +bool ColorItem::on_leave_notify_event(GdkEventCrossing* event) { - g_message("die die die %p %p", obj, user_data ); -} - -static bool getBlock( std::string& dst, guchar ch, std::string const & str ) -{ - bool good = false; - std::string::size_type pos = str.find(ch); - if ( pos != std::string::npos ) - { - std::string::size_type pos2 = str.find( '(', pos ); - if ( pos2 != std::string::npos ) { - std::string::size_type endPos = str.find( ')', pos2 ); - if ( endPos != std::string::npos ) { - dst = str.substr( pos2 + 1, (endPos - pos2 - 1) ); - good = true; - } - } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + desktop->tipsMessageContext()->clear(); } - return good; + return Gtk::Widget::on_leave_notify_event(event); } -static bool popVal( guint64& numVal, std::string& str ) +void ColorItem::selection_modified(Selection* selection, guint flags) { - bool good = false; - std::string::size_type endPos = str.find(','); - if ( endPos == std::string::npos ) { - endPos = str.length(); - } - - if ( endPos != std::string::npos && endPos > 0 ) { - std::string xxx = str.substr( 0, endPos ); - const gchar* ptr = xxx.c_str(); - gchar* endPtr = 0; - numVal = g_ascii_strtoull( ptr, &endPtr, 10 ); - if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { - // overflow - } else if ( (numVal == 0) && (endPtr == ptr) ) { - // failed conversion - } else { - good = true; - str.erase( 0, endPos + 1 ); - } - } - - return good; + selection_changed(selection); } -// TODO resolve this more cleanly: -extern gboolean colorItemHandleButtonPress( GtkWidget* /*widget*/, GdkEventButton* event, gpointer user_data); - -static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpointer data ) +void ColorItem::selection_changed(Selection* selection) { - ColorItem* item = reinterpret_cast(data); - if ( item ) + SPItem* item = selection->singleItem(); + SPPaintServer* grad; + if (item && + ( + (item->style->fill.isPaintserver() && + SP_IS_GRADIENT( (grad = item->style->getFillPaintServer()) ) + && SP_GRADIENT(grad)->getVector() == gradient) || + + (item->style->stroke.isPaintserver() && + SP_IS_GRADIENT( (grad = item->style->getStrokePaintServer()) ) && + SP_GRADIENT(grad)->getVector() == gradient) + ) + ) { - using Inkscape::IO::Resource::get_path; - using Inkscape::IO::Resource::ICONS; - using Inkscape::IO::Resource::SYSTEM; - int width = 32; - int height = 24; - - if (item->def.getType() != ege::PaintDef::RGB){ - GError *error = NULL; - gsize bytesRead = 0; - gsize bytesWritten = 0; - gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), - -1, - &bytesRead, - &bytesWritten, - &error); - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_scale(localFilename, width, height, FALSE, &error); - g_free(localFilename); - gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); - } else { - GdkPixbuf* pixbuf = 0; - if ( item->getGradient() ){ - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(item->getGradient(), width); - cairo_t *ct = cairo_create(s); - cairo_set_source(ct, gradient); - cairo_paint(ct); - cairo_destroy(ct); - cairo_pattern_destroy(gradient); - cairo_surface_flush(s); - - pixbuf = ink_pixbuf_create_from_cairo_surface(s); - } else { - Glib::RefPtr thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); - guint32 fillWith = (0xff000000 & (item->def.getR() << 24)) - | (0x00ff0000 & (item->def.getG() << 16)) - | (0x0000ff00 & (item->def.getB() << 8)); - thumb->fill( fillWith ); - pixbuf = thumb->gobj(); - g_object_ref(G_OBJECT(pixbuf)); - } - gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); + if (!_isSelected) { + _isSelected = true; + queue_draw(); } + } else if (_isSelected) { + _isSelected = false; + queue_draw(); } - -} - -//"drag-drop" -// gboolean dragDropColorData( GtkWidget *widget, -// GdkDragContext *drag_context, -// gint x, -// gint y, -// guint time, -// gpointer user_data) -// { -// // TODO finish - -// return TRUE; -// } - - -SwatchPage::SwatchPage() - : _prefWidth(0) -{ -} - -SwatchPage::~SwatchPage() -{ -} - - -ColorItem::ColorItem(ege::PaintDef::ColorType type) : - def(type), - _isFill(false), - _isStroke(false), - _isLive(false), - _linkIsTone(false), - _linkPercent(0), - _linkGray(0), - _linkSrc(0), - _grad(0), - _pattern(0) -{ -} - -ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) : - def( r, g, b, name ), - _isFill(false), - _isStroke(false), - _isLive(false), - _linkIsTone(false), - _linkPercent(0), - _linkGray(0), - _linkSrc(0), - _grad(0), - _pattern(0) -{ -} - -ColorItem::~ColorItem() -{ - if (_pattern != NULL) { - cairo_pattern_destroy(_pattern); - } -} - -ColorItem::ColorItem(ColorItem const &other) : - Inkscape::UI::Previewable() -{ - if ( this != &other ) { - *this = other; - } -} - -ColorItem &ColorItem::operator=(ColorItem const &other) -{ - if ( this != &other ) { - def = other.def; - - // TODO - correct linkage - _linkSrc = other._linkSrc; - g_message("Erk!"); - } - return *this; } -void ColorItem::setState( bool fill, bool stroke ) +ColorItem::ColorItem( SPGradient* grad, const gchar* name, SPDesktop* desktop ) : + Glib::ObjectBase("coloritem"), + Gtk::Widget(), + def( name ), + gradient(grad), + _isSelected(false) { - if ( (_isFill != fill) || (_isStroke != stroke) ) { - _isFill = fill; - _isStroke = stroke; - - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - EekPreview * preview = EEK_PREVIEW(widget->gobj()); - - int val = eek_preview_get_linked( preview ); - val &= ~(PREVIEW_FILL | PREVIEW_STROKE); - if ( _isFill ) { - val |= PREVIEW_FILL; - } - if ( _isStroke ) { - val |= PREVIEW_STROKE; - } - eek_preview_set_linked( preview, static_cast(val) ); - } - } - } + set_has_window(true); + add_events(Gdk::BUTTON_PRESS_MASK); + add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + sel_connection = desktop->selection->connectChanged(sigc::mem_fun(*this, &ColorItem::selection_changed)); + mod_connection = desktop->selection->connectModified(sigc::mem_fun(*this, &ColorItem::selection_modified)); + selection_changed(desktop->selection); } -void ColorItem::setGradient(SPGradient *grad) +void ColorItem::on_size_request(Gtk::Requisition* requisition) { - if (_grad != grad) { - _grad = grad; - // TODO regen and push to listeners - } - - setName( gr_prepare_label(_grad) ); + requisition->height = 20; + requisition->width = 20; } -void ColorItem::setName(const Glib::ustring name) +void ColorItem::on_size_allocate(Gtk::Allocation& allocation) { - //def.descr = name; - - for ( std::vector::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()); - } + set_allocation(allocation); + if (m_refGdkWindow) + { + m_refGdkWindow->move_resize( allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height() ); } } -void ColorItem::setPattern(cairo_pattern_t *pattern) +void ColorItem::on_map() { - if (pattern) { - cairo_pattern_reference(pattern); - } - if (_pattern) { - cairo_pattern_destroy(_pattern); - } - _pattern = pattern; - - _updatePreviews(); + Gtk::Widget::on_map(); } -void ColorItem::_dragGetColorData( GtkWidget */*widget*/, - GdkDragContext */*drag_context*/, - GtkSelectionData *data, - guint info, - guint /*time*/, - gpointer user_data) +void ColorItem::on_unmap() { - ColorItem* item = reinterpret_cast(user_data); - std::string key; - if ( info < mimeStrings.size() ) { - key = mimeStrings[info]; - } else { - g_warning("ERROR: unknown value (%d)", info); - } - - if ( !key.empty() ) { - char* tmp = 0; - int len = 0; - int format = 0; - item->def.getMIMEData(key, tmp, len, format); - if ( tmp ) { - GdkAtom dataAtom = gdk_atom_intern( key.c_str(), FALSE ); - gtk_selection_data_set( data, dataAtom, format, (guchar*)tmp, len ); - delete[] tmp; - } - } + Gtk::Widget::on_unmap(); } -void ColorItem::_dropDataIn( GtkWidget */*widget*/, - GdkDragContext */*drag_context*/, - gint /*x*/, gint /*y*/, - GtkSelectionData */*data*/, - guint /*info*/, - guint /*event_time*/, - gpointer /*user_data*/) +void ColorItem::on_realize() { + set_realized(); + ensure_style(); + + if(!m_refGdkWindow) + { + //Create the GdkWindow: + + GdkWindowAttr attributes; + memset(&attributes, 0, sizeof(attributes)); + + Gtk::Allocation allocation = get_allocation(); + + //Set initial position and size of the Gdk::Window: + attributes.x = allocation.get_x(); + attributes.y = allocation.get_y(); + attributes.width = allocation.get_width(); + attributes.height = allocation.get_height(); + + attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + + m_refGdkWindow = Gdk::Window::create(get_parent_window(), &attributes, + GDK_WA_X | GDK_WA_Y); + set_window(m_refGdkWindow); + + //Attach this widget's style to its Gdk::Window. + style_attach(); + + //make the widget receive expose events + m_refGdkWindow->set_user_data(gobj()); + } } -void ColorItem::_colorDefChanged(void* data) +void ColorItem::on_unrealize() { - ColorItem* item = reinterpret_cast(data); - if ( item ) { - item->_updatePreviews(); - } + m_refGdkWindow.reset(); + + Gtk::Widget::on_unrealize(); } -void ColorItem::_updatePreviews() +bool ColorItem::on_expose_event(GdkEventExpose* event) { - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - EekPreview * preview = EEK_PREVIEW(widget->gobj()); - - _regenPreview(preview); - - widget->queue_draw(); - } - } - - for ( std::vector::iterator it = _listeners.begin(); it != _listeners.end(); ++it ) { - guint r = def.getR(); - guint g = def.getG(); - guint b = def.getB(); - - if ( (*it)->_linkIsTone ) { - r = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * r) ) / 100; - g = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * g) ) / 100; - b = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * b) ) / 100; - } else { - r = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * r) ) / 100; - g = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * g) ) / 100; - b = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * b) ) / 100; - } - - (*it)->def.setRGB( r, g, b ); - } - - -#if ENABLE_MAGIC_COLORS - // Look for objects using this color + if(m_refGdkWindow) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - SPDocument* document = sp_desktop_document( desktop ); - Inkscape::XML::Node *rroot = document->getReprRoot(); - if ( rroot ) { - - // Find where this thing came from - Glib::ustring paletteName; - bool found = false; - int index = 0; - for ( std::vector::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) { - SwatchPage* curr = *it2; - index = 0; - for ( boost::ptr_vector::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) { - if ( this == &*zz ) { - found = true; - paletteName = curr->_name; - break; - } else { - index++; - } - } - } - - if ( !paletteName.empty() ) { - gchar* str = g_strdup_printf("%d|", index); - paletteName.insert( 0, str ); - g_free(str); - str = 0; - - if ( bruteForce( document, rroot, paletteName, def.getR(), def.getG(), def.getB() ) ) { - SPDocumentUndo::done( document , SP_VERB_DIALOG_SWATCHES, - _("Change color definition")); - } - } - } - } - } -#endif // ENABLE_MAGIC_COLORS - -} - -void ColorItem::_regenPreview(EekPreview * preview) -{ - if ( def.getType() != ege::PaintDef::RGB ) { - using Inkscape::IO::Resource::get_path; - using Inkscape::IO::Resource::ICONS; - using Inkscape::IO::Resource::SYSTEM; - GError *error = NULL; - gsize bytesRead = 0; - gsize bytesWritten = 0; - gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), - -1, - &bytesRead, - &bytesWritten, - &error); - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(localFilename, &error); - if (!pixbuf) { - g_warning("Null pixbuf for %p [%s]", localFilename, localFilename ); - } - g_free(localFilename); - - eek_preview_set_pixbuf( preview, pixbuf ); - } - else if ( !_pattern ){ - eek_preview_set_color( preview, - (def.getR() << 8) | def.getR(), - (def.getG() << 8) | def.getG(), - (def.getB() << 8) | def.getB() ); - } else { - // These correspond to PREVIEW_PIXBUF_WIDTH and VBLOCK from swatches.cpp - // TODO: the pattern to draw should be in the widget that draws the preview, - // so the preview can be scalable - int w = 128; - int h = 16; - - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); - cairo_t *ct = cairo_create(s); - cairo_set_source(ct, _pattern); - cairo_paint(ct); - cairo_destroy(ct); - cairo_surface_flush(s); - - GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s); - eek_preview_set_pixbuf( preview, pixbuf ); - } - - eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0) - | (_listeners.empty() ? 0:PREVIEW_LINK_OUT) - | (_isLive ? PREVIEW_LINK_OTHER:0)) ); -} - -Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio, guint border) -{ - Gtk::Widget* widget = 0; - if ( style == PREVIEW_STYLE_BLURB) { - Gtk::Label *lbl = new Gtk::Label(def.descr); - lbl->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - widget = lbl; - } else { - GtkWidget* eekWidget = eek_preview_new(); - EekPreview * preview = EEK_PREVIEW(eekWidget); - Gtk::Widget* newBlot = Glib::wrap(eekWidget); - _regenPreview(preview); - - eek_preview_set_details( preview, - (::ViewType)view, - (::PreviewSize)size, - ratio, - border ); - - def.addCallback( _colorDefChanged, this ); - eek_preview_set_focus_on_click(preview, FALSE); - newBlot->set_tooltip_text(def.descr); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "clicked", - G_CALLBACK(handleClick), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "alt-clicked", - G_CALLBACK(handleSecondaryClick), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "button-press-event", - G_CALLBACK(colorItemHandleButtonPress), - this); - + Cairo::RefPtr cr = m_refGdkWindow->create_cairo_context(); + if(event) { - std::vector listing = def.getMIMETypes(); - int entryCount = listing.size(); - GtkTargetEntry* entries = new GtkTargetEntry[entryCount]; - GtkTargetEntry* curr = entries; - for ( std::vector::iterator it = listing.begin(); it != listing.end(); ++it ) { - curr->target = g_strdup(it->c_str()); - curr->flags = 0; - if ( mimeToInt.find(*it) == mimeToInt.end() ){ - // these next lines are order-dependent: - mimeToInt[*it] = mimeStrings.size(); - mimeStrings.push_back(*it); - } - curr->info = mimeToInt[curr->target]; - curr++; - } - gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()), - GDK_BUTTON1_MASK, - entries, entryCount, - GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) ); - for ( int i = 0; i < entryCount; i++ ) { - g_free(entries[i].target); - } - delete[] entries; + // clip to the area that needs to be re-exposed so we don't draw any + // more than we need to. + cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); + cr->clip(); } - g_signal_connect( G_OBJECT(newBlot->gobj()), - "drag-data-get", - G_CALLBACK(ColorItem::_dragGetColorData), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "drag-begin", - G_CALLBACK(colorItemDragBegin), - this ); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "enter-notify-event", - G_CALLBACK(handleEnterNotify), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "leave-notify-event", - G_CALLBACK(handleLeaveNotify), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "destroy", - G_CALLBACK(dieDieDie), - this); - - - widget = newBlot; - } - - _previews.push_back( widget ); - - return widget; -} - -void ColorItem::buttonClicked(bool secondary) -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) { - char const * attrName = secondary ? "stroke" : "fill"; - - SPCSSAttr *css = sp_repr_css_attr_new(); - Glib::ustring descr; - switch (def.getType()) { - case ege::PaintDef::CLEAR: { - // TODO actually make this clear - sp_repr_css_set_property( css, attrName, "none" ); - descr = secondary? _("Remove stroke color") : _("Remove fill color"); - break; - } - case ege::PaintDef::NONE: { - sp_repr_css_set_property( css, attrName, "none" ); - descr = secondary? _("Set stroke color to none") : _("Set fill color to none"); - break; - } - case ege::PaintDef::RGB: { - Glib::ustring colorspec; - if ( _grad ){ - colorspec = "url(#"; - colorspec += _grad->getId(); - colorspec += ")"; - } else { - gchar c[64]; - guint32 rgba = (def.getR() << 24) | (def.getG() << 16) | (def.getB() << 8) | 0xff; - sp_svg_write_color(c, sizeof(c), rgba); - colorspec = c; - } - sp_repr_css_set_property( css, attrName, colorspec.c_str() ); - descr = secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"); - break; - } - } - sp_desktop_set_style(desktop, css); - sp_repr_css_attr_unref(css); - - DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); - } -} - -void ColorItem::_wireMagicColors( SwatchPage *colorSet ) -{ - if ( colorSet ) - { - for ( boost::ptr_vector::iterator it = colorSet->_colors.begin(); it != colorSet->_colors.end(); ++it ) - { - std::string::size_type pos = it->def.descr.find("*{"); - if ( pos != std::string::npos ) - { - std::string subby = it->def.descr.substr( pos + 2 ); - std::string::size_type endPos = subby.find("}*"); - if ( endPos != std::string::npos ) - { - subby.erase( endPos ); - //g_message("FOUND MAGIC at '%s'", (*it)->def.descr.c_str()); - //g_message(" '%s'", subby.c_str()); - - if ( subby.find('E') != std::string::npos ) - { - it->def.setEditable( true ); - } - - if ( subby.find('L') != std::string::npos ) - { - it->_isLive = true; - } - - std::string part; - // Tint. index + 1 more val. - if ( getBlock( part, 'T', subby ) ) { - guint64 colorIndex = 0; - if ( popVal( colorIndex, part ) ) { - guint64 percent = 0; - if ( popVal( percent, part ) ) { - it->_linkTint( colorSet->_colors[colorIndex], percent ); - } - } - } - - // Shade/tone. index + 1 or 2 more val. - if ( getBlock( part, 'S', subby ) ) { - guint64 colorIndex = 0; - if ( popVal( colorIndex, part ) ) { - guint64 percent = 0; - if ( popVal( percent, part ) ) { - guint64 grayLevel = 0; - if ( !popVal( grayLevel, part ) ) { - grayLevel = 0; - } - it->_linkTone( colorSet->_colors[colorIndex], percent, grayLevel ); - } - } - } - - } + if (gradient) { + cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); + + Cairo::RefPtr checkpat(new Cairo::Pattern(check)); + + cr->set_source(checkpat); + cr->paint(); + + cairo_pattern_t *g = sp_gradient_create_preview_pattern(gradient, get_allocation().get_width()); + Cairo::RefPtr gpat(new Cairo::Pattern(g)); + cr->set_source(gpat); + cr->paint(); + gpat.clear(); + cairo_pattern_destroy(g); + + checkpat.clear(); + + cairo_pattern_destroy(check); + + if (_isSelected) { + cr->set_source_rgb(0, 0, 0); + cr->set_line_width(3); + cr->move_to(0, get_allocation().get_height()); + cr->line_to(0,0); + cr->line_to(get_allocation().get_width(), 0); + cr->stroke(); + cr->move_to(get_allocation().get_width(), 0); + cr->set_source_rgb(1, 1, 1); + cr->line_to(get_allocation().get_width(), get_allocation().get_height()); + cr->line_to(0, get_allocation().get_height()); + //cr->rectangle(0, 0, get_allocation().get_width(), get_allocation().get_height()); + cr->stroke(); } + } else { + cr->set_source_rgb(1, 1, 1); + cr->paint(); + cr->set_source_rgb(1, 0, 0); + cr->set_line_width(3); + cr->move_to(0,0); + cr->line_to(get_allocation().get_width(), get_allocation().get_height()); + cr->move_to(get_allocation().get_width(), 0); + cr->line_to(0, get_allocation().get_height()); + cr->stroke(); } } + return true; } - -void ColorItem::_linkTint( ColorItem& other, int percent ) -{ - if ( !_linkSrc ) - { - other._listeners.push_back(this); - _linkIsTone = false; - _linkPercent = percent; - if ( _linkPercent > 100 ) - _linkPercent = 100; - if ( _linkPercent < 0 ) - _linkPercent = 0; - _linkGray = 0; - _linkSrc = &other; - - ColorItem::_colorDefChanged(&other); - } -} - -void ColorItem::_linkTone( ColorItem& other, int percent, int grayLevel ) +ColorItem::~ColorItem() { - if ( !_linkSrc ) - { - other._listeners.push_back(this); - _linkIsTone = true; - _linkPercent = percent; - if ( _linkPercent > 100 ) - _linkPercent = 100; - if ( _linkPercent < 0 ) - _linkPercent = 0; - _linkGray = grayLevel; - _linkSrc = &other; - - ColorItem::_colorDefChanged(&other); - } + sel_connection.disconnect(); + mod_connection.disconnect(); } } // namespace Dialogs diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h index 3a0b33193..5d97d8803 100644 --- a/src/ui/dialog/color-item.h +++ b/src/ui/dialog/color-item.h @@ -15,7 +15,11 @@ #include #include "widgets/ege-paint-def.h" -#include "ui/previewable.h" +#include "widgets/eek-preview.h" +#include +#include +#include "desktop.h" +#include "selection.h" class SPGradient; @@ -23,89 +27,43 @@ namespace Inkscape { namespace UI { namespace Dialogs { -class ColorItem; - -class SwatchPage -{ -public: - SwatchPage(); - ~SwatchPage(); - - Glib::ustring _name; - int _prefWidth; - boost::ptr_vector _colors; -}; - /** * The color swatch you see on screen as a clickable box. */ -class ColorItem : public Inkscape::UI::Previewable +class ColorItem : public Gtk::Widget { - friend void _loadPaletteFile( gchar const *filename ); public: - ColorItem( ege::PaintDef::ColorType type ); - ColorItem( unsigned int r, unsigned int g, unsigned int b, - Glib::ustring& name ); + ColorItem( SPGradient * grad, const gchar* name, SPDesktop* desktop ); virtual ~ColorItem(); - ColorItem(ColorItem const &other); - virtual ColorItem &operator=(ColorItem const &other); - virtual Gtk::Widget* getPreview(PreviewStyle style, - ViewType view, - ::PreviewSize size, - guint ratio, - guint border); - void buttonClicked(bool secondary = false); - - 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; } - bool isStroke() { return _isStroke; } - - ege::PaintDef def; - + + SPGradient * getGradient() { return gradient; } + +protected: + + const gchar* def; + SPGradient * gradient; + virtual bool on_enter_notify_event(GdkEventCrossing* event); + virtual bool on_leave_notify_event(GdkEventCrossing* event); + + virtual void on_size_request(Gtk::Requisition* requisition); + virtual void on_size_allocate(Gtk::Allocation& allocation); + virtual void on_map(); + virtual void on_unmap(); + virtual void on_realize(); + virtual void on_unrealize(); + virtual bool on_expose_event(GdkEventExpose* event); + + Glib::RefPtr m_refGdkWindow; + + private: + void selection_changed(Selection* selection); + void selection_modified(Selection* selection, guint flags); - static void _dropDataIn( GtkWidget *widget, - GdkDragContext *drag_context, - gint x, gint y, - GtkSelectionData *data, - guint info, - guint event_time, - gpointer user_data); - - static void _dragGetColorData( GtkWidget *widget, - GdkDragContext *drag_context, - GtkSelectionData *data, - guint info, - guint time, - gpointer user_data); - - static void _wireMagicColors( SwatchPage *colorSet ); - static void _colorDefChanged(void* data); - - void _updatePreviews(); - void _regenPreview(EekPreview * preview); - - void _linkTint( ColorItem& other, int percent ); - void _linkTone( ColorItem& other, int percent, int grayLevel ); - - std::vector _previews; - - bool _isFill; - bool _isStroke; - bool _isLive; - bool _linkIsTone; - int _linkPercent; - int _linkGray; - ColorItem* _linkSrc; - SPGradient* _grad; - cairo_pattern_t *_pattern; - std::vector _listeners; + sigc::connection sel_connection; + sigc::connection mod_connection; + bool _isSelected; }; } // namespace Dialogs diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h index 8dfcf5dce..175031bcf 100644 --- a/src/ui/dialog/filedialog.h +++ b/src/ui/dialog/filedialog.h @@ -48,6 +48,7 @@ typedef enum { IMPORT_TYPES, EXPORT_TYPES, EXE_TYPES, + SWATCH_TYPES, CUSTOM_TYPE } FileDialogType; diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 2956c6d17..efea4b869 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -67,14 +67,14 @@ #include "svg/svg-color.h" #include "sp-radial-gradient.h" #include "color-rgba.h" +#include "ui/tools/tool-base.h" #include "svg/css-ostringstream.h" -#include "ui/tools/tool-base.h" //event-context.h #include #ifdef WIN32 #include #endif -guint get_group0_keyval(GdkEventKey *event); +//lazy! void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); namespace Inkscape { @@ -1335,10 +1335,10 @@ void SwatchesPanel::_defsChanged() eb->add(*lbl); _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); } - Glib::ustring str1 = Glib::ustring(_("[None]")); - ColorItem* item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str1)); - //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); - item->setName(_("[None]")); + + ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); + item->set_tooltip_text(_("[None]")); _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); unsigned int i = 1; @@ -1365,11 +1365,10 @@ void SwatchesPanel::_defsChanged() GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); } - Glib::ustring str2 = Glib::ustring(it->label() ? it->label() : it->getId()); - item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str2)); - item->setGradient(grad); - //item->colorItemHandleButtonPress().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->setName(it->label() ? it->label() : it->getId()); + + item = Gtk::manage(new ColorItem(grad, it->label() ? it->label() : it->getId(), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->set_tooltip_text(it->label() ? it->label() : it->getId()); if (_showlabels) { _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); } else { @@ -1432,11 +1431,10 @@ void SwatchesPanel::_defsChanged() _editDoc.expand_to_path(_storeDoc->get_path(iter)); } - Glib::ustring str3= Glib::ustring(cit->label() ? cit->label() : cit->getId()); - item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str3)); - item->setGradient(grad); - //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->setName(cit->label() ? cit->label() : cit->getId()); + + item = Gtk::manage(new ColorItem(grad, cit->label() ? cit->label() : cit->getId(), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); if (_showlabels) { _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); } else { @@ -1643,7 +1641,7 @@ bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: { @@ -1815,7 +1813,7 @@ void SwatchesPanel::_deleteButtonClickedDoc() bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: { @@ -2323,18 +2321,8 @@ void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) } //namespace UI } //namespace Inkscape -//should be okay to add this here -guint get_group0_keyval(GdkEventKey *event) { - guint keyval = 0; - gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( - gdk_display_get_default()), event->hardware_keycode, - (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, - NULL, NULL, NULL); - return keyval; -} - -void -sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) +//really lazy! +void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) { bool intercepted = false; -- cgit v1.2.3 From a13fdaaa6335ad69b59750a3a9c6b978b921881b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 16:21:29 -0500 Subject: Fixed some swatch sizes (what about the table?) (bzr r13090.1.17) --- src/ui/dialog/swatches.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index efea4b869..91d859f90 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -1333,13 +1333,13 @@ void SwatchesPanel::_defsChanged() lbl = Gtk::manage(new Gtk::Label(_("[Base]"))); eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); } ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); item->set_tooltip_text(_("[None]")); - _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); unsigned int i = 1; for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { @@ -1370,9 +1370,9 @@ void SwatchesPanel::_defsChanged() item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); item->set_tooltip_text(it->label() ? it->label() : it->getId()); if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } i++; @@ -1393,7 +1393,7 @@ void SwatchesPanel::_defsChanged() eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), SP_GROUP(it))); lbl = Gtk::manage(new Gtk::Label(it->label() ? it->label() : it->getId())); eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); } Gtk::TreeModel::iterator rowiter; @@ -1436,9 +1436,9 @@ void SwatchesPanel::_defsChanged() item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } i++; } @@ -2072,7 +2072,7 @@ bool SwatchesPanel::_handleDragDropDoc(const Glib::RefPtr& con SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, ""), _scroller(), - _insideTable(1, 2), + _insideTable(1, 1), _insideV(), _insideH(), _buttonsRow(), -- cgit v1.2.3 From 8db893813e5974793db85bad0eb6b32468d29c45 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 19:31:15 -0500 Subject: Makefile fix (bzr r13090.1.18) --- src/ui/dialog/swatches.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 91d859f90..ceda27885 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -1448,9 +1448,11 @@ void SwatchesPanel::_defsChanged() } } } - + //_scroller.resize(1,1); + _insideTable.resize(1,1); _scroller.show_all_children(); _scroller.queue_draw(); + } Gtk::MenuItem* SwatchesPanel::_addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow) @@ -2258,6 +2260,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : rootWatcher = new SwatchWatcher(this, SwatchDocument->getDefs(), true); SwatchDocument->getDefs()->getRepr()->addObserver(*rootWatcher); _swatchesChanged(); + _insideTable.resize(1,1); } SwatchesPanel::~SwatchesPanel() -- cgit v1.2.3 From 50a5b62b327c55b8038b5031d35bf6ae48705485 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 21:08:09 -0500 Subject: Fixed size of swatches widget (bzr r13090.1.19) --- src/ui/dialog/swatches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index ceda27885..c3889db46 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -2102,7 +2102,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : _insideV.pack_start(_insideH, Gtk::PACK_SHRINK); _scroller.add(_insideV); } else { - _scroller.property_height_request() = 45; + _scroller.property_height_request() = 20; _scroller.add(_insideH); } -- cgit v1.2.3 From c3edf2beebfdf0cbb505d2accbddc4fec17dff7d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 6 Mar 2014 21:05:19 -0500 Subject: Start cleanup for merge into trunk (bzr r13090.1.20) --- src/ui/dialog/color-item.cpp | 2 +- src/ui/dialog/dialog-manager.cpp | 4 +- src/ui/dialog/lpe-powerstroke-properties.cpp | 8 + src/ui/dialog/swatches.cpp | 1 - src/ui/dialog/tags.cpp | 1182 -------------------------- src/ui/dialog/tags.h | 181 ---- 6 files changed, 11 insertions(+), 1367 deletions(-) delete mode 100644 src/ui/dialog/tags.cpp delete mode 100644 src/ui/dialog/tags.h (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 6eece0c17..a1951ec48 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -12,7 +12,6 @@ */ #include -#include #include #include #include @@ -40,6 +39,7 @@ #include "color.h" // for SP_RGBA32_U_COMPOSE +#include namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 1fddbf007..ddf41e0c8 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -111,7 +111,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - //registerFactory("TagsPanel", &create); +// registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -147,7 +147,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - //registerFactory("TagsPanel", &create); +// registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp index cef6f494e..c34351511 100644 --- a/src/ui/dialog/lpe-powerstroke-properties.cpp +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -13,6 +13,14 @@ * Released under GNU GPL. Read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include "lpe-powerstroke-properties.h" #include #include diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index c3889db46..34885a971 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -43,7 +43,6 @@ #include "path-prefix.h" #include "preferences.h" #include "sp-item.h" -#include "sp-gradient-fns.h" #include "sp-gradient.h" #include "sp-gradient-vector.h" #include "style.h" diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp deleted file mode 100644 index 116f9eb0b..000000000 --- a/src/ui/dialog/tags.cpp +++ /dev/null @@ -1,1182 +0,0 @@ -/* - * A simple panel for tags - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "tags.h" -#include -#include -#include -#include - -#include - -#include "desktop.h" -#include "desktop-style.h" -#include "document.h" -#include "document-undo.h" -#include "helper/action.h" -#include "inkscape.h" -#include "layer-fns.h" -#include "layer-manager.h" -#include "preferences.h" -#include "sp-item.h" -#include "sp-object.h" -#include "sp-shape.h" -#include "svg/css-ostringstream.h" -#include "ui/icon-names.h" -#include "ui/widget/layertypeicon.h" -#include "ui/widget/addtoicon.h" -#include "verbs.h" -#include "widgets/icon.h" -#include "xml/node.h" -#include "xml/node-observer.h" -#include "xml/repr.h" -#include "sp-root.h" -//#include "event-context.h" -#include "selection.h" -#include "dialogs/dialog-events.h" -#include "widgets/sp-color-notebook.h" -#include "style.h" -#include "filter-chemistry.h" -#include "filters/blend.h" -#include "filters/gaussian-blur.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "sp-tag.h" -#include "sp-defs.h" -#include "sp-tag-use.h" -#include "sp-tag-use-reference.h" - -//#define DUMP_LAYERS 1 - -namespace Inkscape { -namespace UI { -namespace Dialog { - -using Inkscape::XML::Node; - -TagsPanel& TagsPanel::getInstance() -{ - return *new TagsPanel(); -} - -enum { - COL_ADD = 1 -}; - -enum { - BUTTON_NEW = 0, - BUTTON_TOP, - BUTTON_BOTTOM, - BUTTON_UP, - BUTTON_DOWN, - BUTTON_DELETE, - DRAGNDROP -}; - -class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { -public: - ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) : - _pnl(pnl), - _obj(obj), - _repr(repr), - _labelAttr(g_quark_from_string("inkscape:label")) - {} - - ObjectWatcher(TagsPanel* pnl, SPObject* obj) : - _pnl(pnl), - _obj(obj), - _repr(obj->getRepr()), - _labelAttr(g_quark_from_string("inkscape:label")) - {} - - virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) - { - if ( _pnl && _obj ) { - _pnl->_objectsChanged( _obj ); - } - } - virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) - { - if ( _pnl && _obj ) { - _pnl->_objectsChanged( _obj ); - } - } - virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) - { - if ( _pnl && _obj ) { - _pnl->_objectsChanged( _obj ); - } - } - virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if ( _pnl && _obj ) { - if ( name == _labelAttr ) { - _pnl->_updateObject( _obj); - } - } - } - - TagsPanel* _pnl; - SPObject* _obj; - Inkscape::XML::Node* _repr; - GQuark _labelAttr; -}; - -class TagsPanel::InternalUIBounce -{ -public: - int _actionCode; -}; - -void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) -{ - bool set = false; - - if ( iconName ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - btn.set_relief(Gtk::RELIEF_NONE); - set = true; - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !set && action && action->image ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - set = true; - } - } - } - - btn.set_tooltip_text (tooltip); -} - - -Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) -{ - GtkWidget* iconWidget = 0; - const char* label = 0; - - if ( iconName ) { - iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !iconWidget && action && action->image ) { - iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); - } - - if ( action ) { - label = action->name; - } - } - } - - if ( !label && fallback ) { - label = fallback; - } - - Gtk::Widget* wrapped = 0; - if ( iconWidget ) { - wrapped = manage(Glib::wrap(iconWidget)); - wrapped->show(); - } - - - Gtk::MenuItem* item = 0; - - if (wrapped) { - item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); - } else { - item = Gtk::manage(new Gtk::MenuItem(label, true)); - } - - item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id)); - _popupMenu.append(*item); - - return *item; -} - -void TagsPanel::_fireAction( unsigned int code ) -{ - if ( _desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(_desktop); - if ( action ) { - sp_action_perform( action, NULL ); - } - } - } -} - -void TagsPanel::_takeAction( int val ) -{ - if ( !_pending ) { - _pending = new InternalUIBounce(); - _pending->_actionCode = val; - Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 ); - } -} - -bool TagsPanel::_executeAction() -{ - // Make sure selected layer hasn't changed since the action was triggered - if ( _pending) - { - int val = _pending->_actionCode; -// SPObject* target = _pending->_target; - - switch ( val ) { - case BUTTON_NEW: - { - _fireAction( SP_VERB_TAG_NEW ); - } - break; - case BUTTON_TOP: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_TOP ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_FRONT); - } - } - break; - case BUTTON_BOTTOM: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_BOTTOM ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_BACK); - } - } - break; - case BUTTON_UP: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_RAISE ); - } - else - { - _fireAction( SP_VERB_SELECTION_RAISE ); - } - } - break; - case BUTTON_DOWN: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_LOWER ); - } - else - { - _fireAction( SP_VERB_SELECTION_LOWER ); - } - } - break; - case BUTTON_DELETE: - { - std::vector todelete; - _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); - for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { - SPObject * obj = *iter; - if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); - } - } - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); - } - break; - case DRAGNDROP: - { - _doTreeMove( ); - } - break; - } - - delete _pending; - _pending = 0; - } - - return false; -} - - -class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord -{ -public: - - ModelColumns() - { - add(_colParentObject); - add(_colObject); - add(_colLabel); - add(_colAddRemove); - add(_colAllowAddRemove); - } - virtual ~ModelColumns() {} - - Gtk::TreeModelColumn _colParentObject; - Gtk::TreeModelColumn _colObject; - Gtk::TreeModelColumn _colLabel; - Gtk::TreeModelColumn _colAddRemove; - Gtk::TreeModelColumn _colAllowAddRemove; -}; - -void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete) -{ - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj && obj->parent) { - todelete->push_back(obj); - } -} - -void TagsPanel::_updateObject( SPObject *obj ) { - _store->foreach( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) ); -} - -bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) -{ - Gtk::TreeModel::Row row = *iter; - if ( obj == row[_model->_colObject] ) - { - /* - * We get notified of layer update here (from layer->setLabel()) before layer->label() is set - * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which - * has the correct value (bug #168351) - */ - //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId(); - gchar const *label; - SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0; - if (use && use->ref->isAttached()) { - label = use->ref->getObject()->getAttribute("inkscape:label"); - } else { - label = obj->getAttribute("inkscape:label"); - } - row[_model->_colLabel] = label ? label : obj->getId(); - row[_model->_colAddRemove] = SP_IS_TAG(obj); - } - - return false; -} - -void TagsPanel::_objectsSelected( Selection *sel ) { - - _selectedConnection.block(); - _tree.get_selection()->unselect_all(); - for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next) - { - SPObject *obj = reinterpret_cast(iter->data); - _store->foreach(sigc::bind( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); - } - _selectedConnection.unblock(); - _checkTreeSelection(); -} - -bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) -{ - Gtk::TreeModel::Row row = *iter; - SPObject * it = row[_model->_colObject]; - if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj ) - { - Glib::RefPtr select = _tree.get_selection(); - - select->select(iter); - } - return false; -} - -void TagsPanel::_objectsChanged(SPObject* root) -{ - while (!_objectWatchers.empty()) - { - TagsPanel::ObjectWatcher *w = _objectWatchers.back(); - w->_repr->removeObserver(*w); - _objectWatchers.pop_back(); - delete w; - } - - if (_desktop) { - SPDocument* document = _desktop->doc(); - SPDefs* root = document->getDefs(); - if ( root ) { - _selectedConnection.block(); - _store->clear(); - _addObject( document, root, 0 ); - _selectedConnection.unblock(); - _objectsSelected(_desktop->selection); - _checkTreeSelection(); - } - } -} - -void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) -{ - if ( _desktop && obj ) { - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG(child)) - { - Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); - Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = child; - row[_model->_colParentObject] = NULL; - row[_model->_colLabel] = child->label() ? child->label() : child->getId(); - row[_model->_colAddRemove] = true; - row[_model->_colAllowAddRemove] = true; - - _tree.expand_to_path( _store->get_path(iter) ); - - TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); - child->getRepr()->addObserver(*w); - _objectWatchers.push_back(w); - _addObject( doc, child, &row ); - } - } - if (SP_IS_TAG(obj) && obj->children) - { - Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); - Gtk::TreeModel::Row rowitems = *iteritems; - rowitems[_model->_colObject] = NULL; - rowitems[_model->_colParentObject] = obj; - rowitems[_model->_colLabel] = _("Items"); - rowitems[_model->_colAddRemove] = false; - rowitems[_model->_colAllowAddRemove] = false; - - _tree.expand_to_path( _store->get_path(iteritems) ); - - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG_USE(child)) - { - SPItem *item = SP_TAG_USE(child)->ref->getObject(); - Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); - Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = child; - row[_model->_colParentObject] = NULL; - row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; - row[_model->_colAddRemove] = false; - row[_model->_colAllowAddRemove] = true; - - if (SP_TAG(obj)->expanded()) { - _tree.expand_to_path( _store->get_path(iter) ); - } - - if (item) { - TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); - item->getRepr()->addObserver(*w); - _objectWatchers.push_back(w); - } - } - } - } - } -} - -void TagsPanel::_select_tag( SPTag * tag ) -{ - for (SPObject * child = tag->children; child != NULL; child = child->next) - { - if (SP_IS_TAG(child)) { - _select_tag(SP_TAG(child)); - } else if (SP_IS_TAG_USE(child)) { - SPObject * obj = SP_TAG_USE(child)->ref->getObject(); - if (obj) { - if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); - _desktop->selection->add(obj); - } - } - } -} - -void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter ) -{ - if (iter) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_model->_colObject]; - if (obj) { - if (SP_IS_TAG(obj)) { - _select_tag(SP_TAG(obj)); - } else if (SP_IS_TAG_USE(obj)) { - SPObject * item = SP_TAG_USE(obj)->ref->getObject(); - if (item) { - if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); - _desktop->selection->add(item); - } - } - } - } -} - -void TagsPanel::_pushTreeSelectionToCurrent() -{ - _selectionChangedConnection.block(); - // TODO hunt down the possible API abuse in getting NULL - if ( _desktop && _desktop->currentRoot() ) { - _desktop->selection->clear(); - _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback)); - } - _selectionChangedConnection.unblock(); - - _checkTreeSelection(); -} - -void TagsPanel::_checkTreeSelection() -{ - bool sensitive = _tree.get_selection()->count_selected_rows() > 0; - bool sensitiveNonTop = true; - bool sensitiveNonBottom = true; -// if ( _tree.get_selection()->count_selected_rows() > 0 ) { -// sensitive = true; -// -// SPObject* inTree = _selectedLayer(); -// if ( inTree ) { -// -// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0); -// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); -// -// } -// } - - - for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { - (*it)->set_sensitive( sensitive ); - } - for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { - (*it)->set_sensitive( sensitiveNonTop ); - } - for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { - (*it)->set_sensitive( sensitiveNonBottom ); - } -} - -bool TagsPanel::_handleKeyEvent(GdkEventKey *event) -{ - - switch (get_group0_keyval(event)) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_F2: { - Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); - if (iter && !_text_renderer->property_editable()) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj && SP_IS_TAG(obj)) { - Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); - // Edit the layer label - _text_renderer->property_editable() = true; - _tree.set_cursor(*path, *_name_column, true); - grab_focus(); - return true; - } - } - } - case GDK_KEY_Delete: { - std::vector todelete; - _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); - if (!todelete.empty()) { - for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { - SPObject * obj = *iter; - if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); - } - } - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); - } - return true; - } - break; - } - return false; -} - -bool TagsPanel::_handleButtonEvent(GdkEventButton* event) -{ - static unsigned doubleclick = 0; - - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { - // TODO - fix to a better is-popup function - Gtk::TreeModel::Path path; - int x = static_cast(event->x); - int y = static_cast(event->y); - if ( _tree.get_path_at_pos( x, y, path ) ) { - _checkTreeSelection(); - _popupMenu.popup(event->button, event->time); - if (_tree.get_selection()->is_selected(path)) { - return true; - } - } - } - - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { - // 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(event->x); - int y = static_cast(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_ADD-1)) { - down_at_add = true; - return true; - } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { - _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection)); - _defer_target = path; - } else { - down_at_add = false; - } - } else { - down_at_add = false; - } - } - - if ( event->type == GDK_BUTTON_RELEASE) { - _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction)); - } - - // 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)) { - - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { - if (_defer_target) { - if (_defer_target == path && !(event->x == 0 && event->y == 0)) - { - _tree.set_cursor(path, *col, false); - } - _defer_target = Gtk::TreeModel::Path(); - } else { - Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_model->_colObject]; - - if (obj) { - if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { - if (SP_IS_TAG(obj)) { - bool wasadded = false; - for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next) - { - SPObject *newobj = reinterpret_cast(iter->data); - bool addchild = true; - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { - addchild = false; - } - } - if (addchild) { - Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref"); - clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false); - obj->appendChild(clone); - wasadded = true; - } - } - if (wasadded) { - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to tag")); - } - } else { - std::vector todelete; - _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); - if (!todelete.empty()) { - for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { - SPObject * tobj = *iter; - if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { - tobj->parent->getRepr()->removeChild(tobj->getRepr()); - } - } - } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); - } - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); - } - } - } - } - } - } - - - if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { - doubleclick = 1; - } - - if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { - doubleclick = 0; - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { - Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_model->_colObject]; - if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) { - // Double click on the Layer name, enable editing - _text_renderer->property_editable() = true; - _tree.set_cursor (path, *_name_column, true); - grab_focus(); - } - } - } - - return false; -} - -void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) -{ - Gtk::TreeModel::Row row = *iter; - SPObject* obj = row[_model->_colObject]; - SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0; - if (item) - { - _dnd_source.push_back(item); - } -} - -/* - * Drap and drop within the tree - * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer - */ -bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) -{ - int cell_x = 0, cell_y = 0; - Gtk::TreeModel::Path target_path; - Gtk::TreeView::Column *target_column; - - _dnd_into = true; - _dnd_target = _document->getDefs(); - _dnd_source.clear(); - _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource)); - - if (_dnd_source.empty()) { - return true; - } - - if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { - // Are we before, inside or after the drop layer - Gdk::Rectangle rect; - _tree.get_background_area (target_path, *target_column, rect); - int cell_height = rect.get_height(); - _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); - if (cell_y > (int)(cell_height * 2/3)) { - Gtk::TreeModel::Path next_path = target_path; - next_path.next(); - if (_store->iter_is_valid(_store->get_iter(next_path))) { - target_path = next_path; - } else { - // Dragging to the "end" - Gtk::TreeModel::Path up_path = target_path; - up_path.up(); - if (_store->iter_is_valid(_store->get_iter(up_path))) { - // Drop into parent - target_path = up_path; - _dnd_into = true; - } else { - // Drop into the top level - _dnd_target = _document->getDefs(); - _dnd_into = true; - } - } - } - Gtk::TreeModel::iterator iter = _store->get_iter(target_path); - if (_store->iter_is_valid(iter)) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_model->_colObject]; - SPObject *pobj = row[_model->_colParentObject]; - if (obj) { - if (SP_IS_TAG(obj)) { - _dnd_target = SP_TAG(obj); - } else if (SP_IS_TAG(obj->parent)) { - _dnd_target = SP_TAG(obj->parent); - _dnd_into = true; - } - } else if (pobj && SP_IS_TAG(pobj)) { - _dnd_target = SP_TAG(pobj); - _dnd_into = true; - } else { - return true; - } - } - } - - _takeAction(DRAGNDROP); - - return false; -} - -/* - * Move a layer in response to a drag & drop action - */ -void TagsPanel::_doTreeMove( ) -{ - if (_dnd_target) { - for (std::vector::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter) - { - SPTag *src = *iter; - if (src != _dnd_target) { - src->moveTo(_dnd_target, _dnd_into); - } - } - _desktop->selection->clear(); - while (!_dnd_source.empty()) - { - SPTag *src = _dnd_source.back(); - _select_tag(src); - _dnd_source.pop_back(); - } - DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS, - _("Moved tags")); - } -} - - -void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) -{ - Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - _renameObject(row, new_text); - _text_renderer->property_editable() = false; -} - -void TagsPanel::_handleEditingCancelled() -{ - _text_renderer->property_editable() = false; -} - -void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) -{ - if ( row && _desktop) { - SPObject* obj = row[_model->_colObject]; - if ( obj ) { - if (SP_IS_TAG(obj)) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, - _("Rename object")); - } - } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, - _("Rename object")); - } - } - } - } -} - -bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) -{ - return false; -} - -bool TagsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) -{ - bool val = true; - if ( !currentlySelected && _toggleEvent ) - { - GdkEvent* event = gtk_get_current_event(); - if ( event ) { - // (keep these checks separate, so we know when to call gdk_event_free() - if ( event->type == GDK_BUTTON_PRESS ) { - GdkEventButton const* target = reinterpret_cast(_toggleEvent); - GdkEventButton const* evtb = reinterpret_cast(event); - - if ( (evtb->window == target->window) - && (evtb->send_event == target->send_event) - && (evtb->time == target->time) - && (evtb->state == target->state) - ) - { - // Ooooh! It's a magic one - val = false; - } - } - gdk_event_free(event); - } - } - return val; -} - -void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) -{ - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_model->_colParentObject]; - if (obj && SP_IS_TAG(obj)) - { - SP_TAG(obj)->setExpanded(isexpanded); - obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - } -} - -/** - * Constructor - */ -TagsPanel::TagsPanel() : - UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS), - _rootWatcher(0), - deskTrack(), - _desktop(0), - _document(0), - _model(0), - _pending(0), - _toggleEvent(0), - _defer_target(), - desktopChangeConn() -{ - //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - ModelColumns *zoop = new ModelColumns(); - _model = zoop; - - _store = Gtk::TreeStore::create( *zoop ); - - _tree.set_model( _store ); - _tree.set_headers_visible(false); - _tree.set_reorderable(true); - _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); - - Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon()); - int addColNum = _tree.append_column("type", *addRenderer) - 1; - Gtk::TreeViewColumn *col = _tree.get_column(addColNum); - if ( col ) { - col->add_attribute( addRenderer->property_active(), _model->_colAddRemove ); - col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove ); - } - - _text_renderer = manage(new Gtk::CellRendererText()); - int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; - _name_column = _tree.get_column(nameColNum); - _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); - - _tree.set_expander_column( *_tree.get_column(nameColNum) ); - - _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); - _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) ); - _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) ); - - _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false); - _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false)); - _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true)); - - _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) ); - _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) ); - - _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); - _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); - _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false ); - - _scroller.add( _tree ); - _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scroller.set_shadow_type(Gtk::SHADOW_IN); - Gtk::Requisition sreq; -#if WITH_GTKMM_3_0 - Gtk::Requisition sreq_natural; - _scroller.get_preferred_size(sreq_natural, sreq); -#else - sreq = _scroller.size_request(); -#endif - int minHeight = 70; - if (sreq.height < minHeight) { - // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar - _scroller.set_size_request(sreq.width, minHeight); - } - - _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); - - _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK); - - _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET); - - SPDesktop* targetDesktop = getDesktop(); - - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new tag") ); - btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); - _buttonsSecondary.pack_start(*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) ); -// _buttonsRow.add( *btn ); - - btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Tag") ); - btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); - _watching.push_back( btn ); - _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); - - _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); - _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); - - // ------------------------------------------------------- - { - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); - - _popupMenu.show_all_children(); - } - // ------------------------------------------------------- - - - - for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { - (*it)->set_sensitive( false ); - } - for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { - (*it)->set_sensitive( false ); - } - for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { - (*it)->set_sensitive( false ); - } - - setDesktop( targetDesktop ); - - show_all_children(); - - // restorePanelPrefs(); - - // Connect this up last - desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) ); - deskTrack.connect(GTK_WIDGET(gobj())); -} - -TagsPanel::~TagsPanel() -{ - - setDesktop(NULL); - - if ( _model ) - { - delete _model; - _model = 0; - } - - if (_pending) { - delete _pending; - _pending = 0; - } - - if ( _toggleEvent ) - { - gdk_event_free( _toggleEvent ); - _toggleEvent = 0; - } - - desktopChangeConn.disconnect(); - deskTrack.disconnect(); -} - -void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) -{ - while (!_objectWatchers.empty()) - { - TagsPanel::ObjectWatcher *w = _objectWatchers.back(); - w->_repr->removeObserver(*w); - _objectWatchers.pop_back(); - delete w; - } - - if (_rootWatcher) - { - _rootWatcher->_repr->removeObserver(*_rootWatcher); - delete _rootWatcher; - _rootWatcher = NULL; - } - - _document = document; - - if (document && document->getDefs() && document->getDefs()->getRepr()) - { - _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs()); - document->getDefs()->getRepr()->addObserver(*_rootWatcher); - _objectsChanged(document->getDefs()); - } -} - -void TagsPanel::setDesktop( SPDesktop* desktop ) -{ - Panel::setDesktop(desktop); - - if ( desktop != _desktop ) { - _documentChangedConnection.disconnect(); - _selectionChangedConnection.disconnect(); - if ( _desktop ) { - _desktop = 0; - } - - _desktop = Panel::getDesktop(); - if ( _desktop ) { - //setLabel( _desktop->doc()->name ); - _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument)); - _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected)); - - setDocument(_desktop, _desktop->doc()); - } - } -/* - GSList const *layers = _desktop->doc()->getResourceList( "layer" ); - g_message( "layers list starts at %p", layers ); - for ( GSList const *iter=layers ; iter ; iter = iter->next ) { - SPObject *layer=static_cast(iter->data); - g_message(" {%s} [%s]", layer->id, layer->label() ); - } -*/ - deskTrack.setBase(desktop); -} - - - - - -} //namespace Dialogs -} //namespace UI -} //namespace Inkscape - - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h deleted file mode 100644 index d35dfba01..000000000 --- a/src/ui/dialog/tags.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * A simple dialog for tags UI. - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef SEEN_TAGS_PANEL_H -#define SEEN_TAGS_PANEL_H - -#include -#include -#include -#include -#include -#include "ui/widget/spinbutton.h" -#include "ui/widget/panel.h" -#include "ui/widget/object-composite-settings.h" -#include "desktop-tracker.h" -#include "ui/widget/style-subject.h" -#include "selection.h" -#include "ui/widget/filter-effect-chooser.h" - -class SPObject; -class SPTag; -struct SPColorSelector; - -namespace Inkscape { - -namespace UI { -namespace Dialog { - - -/** - * A panel that displays layers. - */ -class TagsPanel : public UI::Widget::Panel -{ -public: - TagsPanel(); - virtual ~TagsPanel(); - - //virtual void setOrientation( Gtk::AnchorType how ); - - static TagsPanel& getInstance(); - - void setDesktop( SPDesktop* desktop ); - void setDocument( SPDesktop* desktop, SPDocument* document); - -protected: - //virtual void _handleAction( int setId, int itemId ); - friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); -private: - class ModelColumns; - class InternalUIBounce; - class ObjectWatcher; - - TagsPanel(TagsPanel const &); // no copy - TagsPanel &operator=(TagsPanel const &); // no assign - - void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); - void _fireAction( unsigned int code ); - Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); - - bool _handleButtonEvent(GdkEventButton *event); - bool _handleKeyEvent(GdkEventKey *event); - - void _storeDragSource(const Gtk::TreeModel::iterator& iter); - bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); - void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); - void _handleEditingCancelled(); - - void _doTreeMove(); - void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); - - void _pushTreeSelectionToCurrent(); - void _selected_row_callback( const Gtk::TreeModel::iterator& iter ); - void _select_tag( SPTag * tag ); - - void _checkTreeSelection(); - - void _takeAction( int val ); - bool _executeAction(); - - void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); - - bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); - bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); - - void _updateObject(SPObject *obj); - bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj); - - void _objectsSelected(Selection *sel); - bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); - - void _objectsChanged(SPObject *root); - void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ); - - void _checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete); - -// std::vector groupConnections; - TagsPanel::ObjectWatcher* _rootWatcher; - std::vector _objectWatchers; - - // Hooked to the layer manager: - sigc::connection _documentChangedConnection; - sigc::connection _selectionChangedConnection; - - sigc::connection _changedConnection; - sigc::connection _addedConnection; - sigc::connection _removedConnection; - - // Internal - sigc::connection _selectedConnection; - sigc::connection _expandedConnection; - sigc::connection _collapsedConnection; - - DesktopTracker deskTrack; - SPDesktop* _desktop; - SPDocument* _document; - ModelColumns* _model; - InternalUIBounce* _pending; - gboolean _dnd_into; - std::vector _dnd_source; - SPObject* _dnd_target; - - GdkEvent* _toggleEvent; - bool down_at_add; - - Gtk::TreeModel::Path _defer_target; - - Glib::RefPtr _store; - std::vector _watching; - std::vector _watchingNonTop; - std::vector _watchingNonBottom; - - Gtk::TreeView _tree; - Gtk::CellRendererText *_text_renderer; - Gtk::TreeView::Column *_name_column; -#if WITH_GTKMM_3_0 - Gtk::Box _buttonsRow; - Gtk::Box _buttonsPrimary; - Gtk::Box _buttonsSecondary; -#else - Gtk::HBox _buttonsRow; - Gtk::HBox _buttonsPrimary; - Gtk::HBox _buttonsSecondary; -#endif - Gtk::ScrolledWindow _scroller; - Gtk::Menu _popupMenu; - Inkscape::UI::Widget::SpinButton _spinBtn; - Gtk::VBox _layersPage; - - sigc::connection desktopChangeConn; - -}; - - - -} //namespace Dialogs -} //namespace UI -} //namespace Inkscape - - - -#endif // SEEN_OBJECTS_PANEL_H - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From fd36e8d406b5ca3bfdc575a949351c6ae4a45c57 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 8 Mar 2014 20:52:27 -0500 Subject: Remove all trace of the Tags dialog Fixed Attach Path and Fill Between Many LPEs Enabled Gradient Meshes (bzr r13090.1.21) --- src/ui/dialog/swatches.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 34885a971..2a8471b55 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -6,6 +6,7 @@ * Jon A. Cruz * John Bintz * Abhishek Sharma + * Theodore Janezcko * * Copyright (C) 2005 Jon A. Cruz * Copyright (C) 2008 John Bintz -- cgit v1.2.3 From 13c192e2fa564c0a743e13e30b1cf6de9b1a39a6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 12 Mar 2014 08:56:04 -0400 Subject: Reverted swatches Removed a toy effect (not ready yet) Fixed a bug with Livarot General cleanup (bzr r13090.1.23) --- src/ui/dialog/color-item.cpp | 862 ++++++++-- src/ui/dialog/color-item.h | 108 +- src/ui/dialog/object-properties.cpp | 1 + src/ui/dialog/objects.cpp | 227 +-- src/ui/dialog/swatches.cpp | 2944 +++++++++++------------------------ src/ui/dialog/swatches.h | 153 +- 6 files changed, 1825 insertions(+), 2470 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index a1951ec48..bab7e18e1 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -11,8 +11,18 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include +#include #include #include @@ -35,216 +45,766 @@ #include "xml/repr.h" #include "verbs.h" #include "widgets/gradient-vector.h" -#include "sp-paint-server.h" #include "color.h" // for SP_RGBA32_U_COMPOSE -#include namespace Inkscape { namespace UI { namespace Dialogs { +static std::vector mimeStrings; +static std::map mimeToInt; + -bool ColorItem::on_enter_notify_event(GdkEventCrossing* event) +#if ENABLE_MAGIC_COLORS +// TODO remove this soon: +extern std::vector possible; +#endif // ENABLE_MAGIC_COLORS + + +#if ENABLE_MAGIC_COLORS +static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"),def); - desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); - g_free(msg); + bool changed = false; + + if ( node ) { + gchar const * val = node->attribute("inkscape:x-fill-tag"); + if ( val && (match == val) ) { + SPObject *obj = document->getObjectByRepr( node ); + + gchar c[64] = {0}; + sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, "fill", c ); + + sp_desktop_apply_css_recursive( obj, css, true ); + static_cast(obj)->updateRepr(); + + changed = true; + } + + val = node->attribute("inkscape:x-stroke-tag"); + if ( val && (match == val) ) { + SPObject *obj = document->getObjectByRepr( node ); + + gchar c[64] = {0}; + sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, "stroke", c ); + + sp_desktop_apply_css_recursive( (SPItem*)obj, css, true ); + ((SPItem*)obj)->updateRepr(); + + changed = true; + } + + Inkscape::XML::Node* first = node->firstChild(); + changed |= bruteForce( document, first, match, r, g, b ); + + changed |= bruteForce( document, node->next(), match, r, g, b ); } - return Gtk::Widget::on_enter_notify_event(event); + + return changed; +} +#endif // ENABLE_MAGIC_COLORS + +static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(false); + } +} + +static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(true); + } +} + +static gboolean handleEnterNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"), + item->def.descr.c_str()); + desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); + g_free(msg); + } + } + return FALSE; +} + +static gboolean handleLeaveNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + desktop->tipsMessageContext()->clear(); + } + } + return FALSE; } -bool ColorItem::on_leave_notify_event(GdkEventCrossing* event) +static void dieDieDie( GObject *obj, gpointer user_data ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - desktop->tipsMessageContext()->clear(); + g_message("die die die %p %p", obj, user_data ); +} + +static bool getBlock( std::string& dst, guchar ch, std::string const & str ) +{ + bool good = false; + std::string::size_type pos = str.find(ch); + if ( pos != std::string::npos ) + { + std::string::size_type pos2 = str.find( '(', pos ); + if ( pos2 != std::string::npos ) { + std::string::size_type endPos = str.find( ')', pos2 ); + if ( endPos != std::string::npos ) { + dst = str.substr( pos2 + 1, (endPos - pos2 - 1) ); + good = true; + } + } } - return Gtk::Widget::on_leave_notify_event(event); + return good; } -void ColorItem::selection_modified(Selection* selection, guint flags) +static bool popVal( guint64& numVal, std::string& str ) { - selection_changed(selection); + bool good = false; + std::string::size_type endPos = str.find(','); + if ( endPos == std::string::npos ) { + endPos = str.length(); + } + + if ( endPos != std::string::npos && endPos > 0 ) { + std::string xxx = str.substr( 0, endPos ); + const gchar* ptr = xxx.c_str(); + gchar* endPtr = 0; + numVal = g_ascii_strtoull( ptr, &endPtr, 10 ); + if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { + // overflow + } else if ( (numVal == 0) && (endPtr == ptr) ) { + // failed conversion + } else { + good = true; + str.erase( 0, endPos + 1 ); + } + } + + return good; } -void ColorItem::selection_changed(Selection* selection) +// TODO resolve this more cleanly: +extern gboolean colorItemHandleButtonPress( GtkWidget* /*widget*/, GdkEventButton* event, gpointer user_data); + +static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpointer data ) { - SPItem* item = selection->singleItem(); - SPPaintServer* grad; - if (item && - ( - (item->style->fill.isPaintserver() && - SP_IS_GRADIENT( (grad = item->style->getFillPaintServer()) ) - && SP_GRADIENT(grad)->getVector() == gradient) || - - (item->style->stroke.isPaintserver() && - SP_IS_GRADIENT( (grad = item->style->getStrokePaintServer()) ) && - SP_GRADIENT(grad)->getVector() == gradient) - ) - ) + ColorItem* item = reinterpret_cast(data); + if ( item ) { - if (!_isSelected) { - _isSelected = true; - queue_draw(); + using Inkscape::IO::Resource::get_path; + using Inkscape::IO::Resource::ICONS; + using Inkscape::IO::Resource::SYSTEM; + int width = 32; + int height = 24; + + if (item->def.getType() != ege::PaintDef::RGB){ + GError *error = NULL; + gsize bytesRead = 0; + gsize bytesWritten = 0; + gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), + -1, + &bytesRead, + &bytesWritten, + &error); + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_scale(localFilename, width, height, FALSE, &error); + g_free(localFilename); + gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); + } else { + GdkPixbuf* pixbuf = 0; + if ( item->getGradient() ){ + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(item->getGradient(), width); + cairo_t *ct = cairo_create(s); + cairo_set_source(ct, gradient); + cairo_paint(ct); + cairo_destroy(ct); + cairo_pattern_destroy(gradient); + cairo_surface_flush(s); + + pixbuf = ink_pixbuf_create_from_cairo_surface(s); + } else { + Glib::RefPtr thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); + guint32 fillWith = (0xff000000 & (item->def.getR() << 24)) + | (0x00ff0000 & (item->def.getG() << 16)) + | (0x0000ff00 & (item->def.getB() << 8)); + thumb->fill( fillWith ); + pixbuf = thumb->gobj(); + g_object_ref(G_OBJECT(pixbuf)); + } + gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); } - } else if (_isSelected) { - _isSelected = false; - queue_draw(); } + +} + +//"drag-drop" +// gboolean dragDropColorData( GtkWidget *widget, +// GdkDragContext *drag_context, +// gint x, +// gint y, +// guint time, +// gpointer user_data) +// { +// // TODO finish + +// return TRUE; +// } + + +SwatchPage::SwatchPage() + : _prefWidth(0) +{ } -ColorItem::ColorItem( SPGradient* grad, const gchar* name, SPDesktop* desktop ) : - Glib::ObjectBase("coloritem"), - Gtk::Widget(), - def( name ), - gradient(grad), - _isSelected(false) +SwatchPage::~SwatchPage() { - set_has_window(true); - add_events(Gdk::BUTTON_PRESS_MASK); - add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); - sel_connection = desktop->selection->connectChanged(sigc::mem_fun(*this, &ColorItem::selection_changed)); - mod_connection = desktop->selection->connectModified(sigc::mem_fun(*this, &ColorItem::selection_modified)); - selection_changed(desktop->selection); } -void ColorItem::on_size_request(Gtk::Requisition* requisition) + +ColorItem::ColorItem(ege::PaintDef::ColorType type) : + def(type), + _isFill(false), + _isStroke(false), + _isLive(false), + _linkIsTone(false), + _linkPercent(0), + _linkGray(0), + _linkSrc(0), + _grad(0), + _pattern(0) { - requisition->height = 20; - requisition->width = 20; } -void ColorItem::on_size_allocate(Gtk::Allocation& allocation) +ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) : + def( r, g, b, name ), + _isFill(false), + _isStroke(false), + _isLive(false), + _linkIsTone(false), + _linkPercent(0), + _linkGray(0), + _linkSrc(0), + _grad(0), + _pattern(0) { - set_allocation(allocation); - if (m_refGdkWindow) - { - m_refGdkWindow->move_resize( allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height() ); +} + +ColorItem::~ColorItem() +{ + if (_pattern != NULL) { + cairo_pattern_destroy(_pattern); + } +} + +ColorItem::ColorItem(ColorItem const &other) : + Inkscape::UI::Previewable() +{ + if ( this != &other ) { + *this = other; + } +} + +ColorItem &ColorItem::operator=(ColorItem const &other) +{ + if ( this != &other ) { + def = other.def; + + // TODO - correct linkage + _linkSrc = other._linkSrc; + g_message("Erk!"); + } + return *this; +} + +void ColorItem::setState( bool fill, bool stroke ) +{ + if ( (_isFill != fill) || (_isStroke != stroke) ) { + _isFill = fill; + _isStroke = stroke; + + for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { + Gtk::Widget* widget = *it; + if ( IS_EEK_PREVIEW(widget->gobj()) ) { + EekPreview * preview = EEK_PREVIEW(widget->gobj()); + + int val = eek_preview_get_linked( preview ); + val &= ~(PREVIEW_FILL | PREVIEW_STROKE); + if ( _isFill ) { + val |= PREVIEW_FILL; + } + if ( _isStroke ) { + val |= PREVIEW_STROKE; + } + eek_preview_set_linked( preview, static_cast(val) ); + } + } + } +} + +void ColorItem::setGradient(SPGradient *grad) +{ + if (_grad != grad) { + _grad = grad; + // TODO regen and push to listeners } + + setName( gr_prepare_label(_grad) ); } -void ColorItem::on_map() +void ColorItem::setName(const Glib::ustring name) { - Gtk::Widget::on_map(); + //def.descr = name; + + for ( std::vector::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::on_unmap() +void ColorItem::setPattern(cairo_pattern_t *pattern) { - Gtk::Widget::on_unmap(); + if (pattern) { + cairo_pattern_reference(pattern); + } + if (_pattern) { + cairo_pattern_destroy(_pattern); + } + _pattern = pattern; + + _updatePreviews(); } -void ColorItem::on_realize() +void ColorItem::_dragGetColorData( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + GtkSelectionData *data, + guint info, + guint /*time*/, + gpointer user_data) +{ + ColorItem* item = reinterpret_cast(user_data); + std::string key; + if ( info < mimeStrings.size() ) { + key = mimeStrings[info]; + } else { + g_warning("ERROR: unknown value (%d)", info); + } + + if ( !key.empty() ) { + char* tmp = 0; + int len = 0; + int format = 0; + item->def.getMIMEData(key, tmp, len, format); + if ( tmp ) { + GdkAtom dataAtom = gdk_atom_intern( key.c_str(), FALSE ); + gtk_selection_data_set( data, dataAtom, format, (guchar*)tmp, len ); + delete[] tmp; + } + } +} + +void ColorItem::_dropDataIn( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + gint /*x*/, gint /*y*/, + GtkSelectionData */*data*/, + guint /*info*/, + guint /*event_time*/, + gpointer /*user_data*/) { - set_realized(); - ensure_style(); - - if(!m_refGdkWindow) - { - //Create the GdkWindow: - - GdkWindowAttr attributes; - memset(&attributes, 0, sizeof(attributes)); - - Gtk::Allocation allocation = get_allocation(); - - //Set initial position and size of the Gdk::Window: - attributes.x = allocation.get_x(); - attributes.y = allocation.get_y(); - attributes.width = allocation.get_width(); - attributes.height = allocation.get_height(); - - attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - - m_refGdkWindow = Gdk::Window::create(get_parent_window(), &attributes, - GDK_WA_X | GDK_WA_Y); - set_window(m_refGdkWindow); - - //Attach this widget's style to its Gdk::Window. - style_attach(); - - //make the widget receive expose events - m_refGdkWindow->set_user_data(gobj()); - } } -void ColorItem::on_unrealize() +void ColorItem::_colorDefChanged(void* data) { - m_refGdkWindow.reset(); - - Gtk::Widget::on_unrealize(); + ColorItem* item = reinterpret_cast(data); + if ( item ) { + item->_updatePreviews(); + } } -bool ColorItem::on_expose_event(GdkEventExpose* event) +void ColorItem::_updatePreviews() { - if(m_refGdkWindow) + for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { + Gtk::Widget* widget = *it; + if ( IS_EEK_PREVIEW(widget->gobj()) ) { + EekPreview * preview = EEK_PREVIEW(widget->gobj()); + + _regenPreview(preview); + + widget->queue_draw(); + } + } + + for ( std::vector::iterator it = _listeners.begin(); it != _listeners.end(); ++it ) { + guint r = def.getR(); + guint g = def.getG(); + guint b = def.getB(); + + if ( (*it)->_linkIsTone ) { + r = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * r) ) / 100; + g = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * g) ) / 100; + b = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * b) ) / 100; + } else { + r = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * r) ) / 100; + g = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * g) ) / 100; + b = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * b) ) / 100; + } + + (*it)->def.setRGB( r, g, b ); + } + + +#if ENABLE_MAGIC_COLORS + // Look for objects using this color { - Cairo::RefPtr cr = m_refGdkWindow->create_cairo_context(); - if(event) + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + SPDocument* document = sp_desktop_document( desktop ); + Inkscape::XML::Node *rroot = document->getReprRoot(); + if ( rroot ) { + + // Find where this thing came from + Glib::ustring paletteName; + bool found = false; + int index = 0; + for ( std::vector::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) { + SwatchPage* curr = *it2; + index = 0; + for ( boost::ptr_vector::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) { + if ( this == &*zz ) { + found = true; + paletteName = curr->_name; + break; + } else { + index++; + } + } + } + + if ( !paletteName.empty() ) { + gchar* str = g_strdup_printf("%d|", index); + paletteName.insert( 0, str ); + g_free(str); + str = 0; + + if ( bruteForce( document, rroot, paletteName, def.getR(), def.getG(), def.getB() ) ) { + SPDocumentUndo::done( document , SP_VERB_DIALOG_SWATCHES, + _("Change color definition")); + } + } + } + } + } +#endif // ENABLE_MAGIC_COLORS + +} + +void ColorItem::_regenPreview(EekPreview * preview) +{ + if ( def.getType() != ege::PaintDef::RGB ) { + using Inkscape::IO::Resource::get_path; + using Inkscape::IO::Resource::ICONS; + using Inkscape::IO::Resource::SYSTEM; + GError *error = NULL; + gsize bytesRead = 0; + gsize bytesWritten = 0; + gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), + -1, + &bytesRead, + &bytesWritten, + &error); + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(localFilename, &error); + if (!pixbuf) { + g_warning("Null pixbuf for %p [%s]", localFilename, localFilename ); + } + g_free(localFilename); + + eek_preview_set_pixbuf( preview, pixbuf ); + } + else if ( !_pattern ){ + eek_preview_set_color( preview, + (def.getR() << 8) | def.getR(), + (def.getG() << 8) | def.getG(), + (def.getB() << 8) | def.getB() ); + } else { + // These correspond to PREVIEW_PIXBUF_WIDTH and VBLOCK from swatches.cpp + // TODO: the pattern to draw should be in the widget that draws the preview, + // so the preview can be scalable + int w = 128; + int h = 16; + + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); + cairo_t *ct = cairo_create(s); + cairo_set_source(ct, _pattern); + cairo_paint(ct); + cairo_destroy(ct); + cairo_surface_flush(s); + + GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s); + eek_preview_set_pixbuf( preview, pixbuf ); + } + + eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0) + | (_listeners.empty() ? 0:PREVIEW_LINK_OUT) + | (_isLive ? PREVIEW_LINK_OTHER:0)) ); +} + +Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio, guint border) +{ + Gtk::Widget* widget = 0; + if ( style == PREVIEW_STYLE_BLURB) { + Gtk::Label *lbl = new Gtk::Label(def.descr); + lbl->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + widget = lbl; + } else { + GtkWidget* eekWidget = eek_preview_new(); + EekPreview * preview = EEK_PREVIEW(eekWidget); + Gtk::Widget* newBlot = Glib::wrap(eekWidget); + _regenPreview(preview); + + eek_preview_set_details( preview, + (::ViewType)view, + (::PreviewSize)size, + ratio, + border ); + + def.addCallback( _colorDefChanged, this ); + eek_preview_set_focus_on_click(preview, FALSE); + newBlot->set_tooltip_text(def.descr); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "clicked", + G_CALLBACK(handleClick), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "alt-clicked", + G_CALLBACK(handleSecondaryClick), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "button-press-event", + G_CALLBACK(colorItemHandleButtonPress), + this); + { - // clip to the area that needs to be re-exposed so we don't draw any - // more than we need to. - cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); - cr->clip(); + std::vector listing = def.getMIMETypes(); + int entryCount = listing.size(); + GtkTargetEntry* entries = new GtkTargetEntry[entryCount]; + GtkTargetEntry* curr = entries; + for ( std::vector::iterator it = listing.begin(); it != listing.end(); ++it ) { + curr->target = g_strdup(it->c_str()); + curr->flags = 0; + if ( mimeToInt.find(*it) == mimeToInt.end() ){ + // these next lines are order-dependent: + mimeToInt[*it] = mimeStrings.size(); + mimeStrings.push_back(*it); + } + curr->info = mimeToInt[curr->target]; + curr++; + } + gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()), + GDK_BUTTON1_MASK, + entries, entryCount, + GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) ); + for ( int i = 0; i < entryCount; i++ ) { + g_free(entries[i].target); + } + delete[] entries; } - if (gradient) { - cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); - - Cairo::RefPtr checkpat(new Cairo::Pattern(check)); - - cr->set_source(checkpat); - cr->paint(); - - cairo_pattern_t *g = sp_gradient_create_preview_pattern(gradient, get_allocation().get_width()); - Cairo::RefPtr gpat(new Cairo::Pattern(g)); - cr->set_source(gpat); - cr->paint(); - gpat.clear(); - cairo_pattern_destroy(g); - - checkpat.clear(); - - cairo_pattern_destroy(check); - - if (_isSelected) { - cr->set_source_rgb(0, 0, 0); - cr->set_line_width(3); - cr->move_to(0, get_allocation().get_height()); - cr->line_to(0,0); - cr->line_to(get_allocation().get_width(), 0); - cr->stroke(); - cr->move_to(get_allocation().get_width(), 0); - cr->set_source_rgb(1, 1, 1); - cr->line_to(get_allocation().get_width(), get_allocation().get_height()); - cr->line_to(0, get_allocation().get_height()); - //cr->rectangle(0, 0, get_allocation().get_width(), get_allocation().get_height()); - cr->stroke(); + g_signal_connect( G_OBJECT(newBlot->gobj()), + "drag-data-get", + G_CALLBACK(ColorItem::_dragGetColorData), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "drag-begin", + G_CALLBACK(colorItemDragBegin), + this ); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "enter-notify-event", + G_CALLBACK(handleEnterNotify), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "leave-notify-event", + G_CALLBACK(handleLeaveNotify), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "destroy", + G_CALLBACK(dieDieDie), + this); + + + widget = newBlot; + } + + _previews.push_back( widget ); + + return widget; +} + +void ColorItem::buttonClicked(bool secondary) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + char const * attrName = secondary ? "stroke" : "fill"; + + SPCSSAttr *css = sp_repr_css_attr_new(); + Glib::ustring descr; + switch (def.getType()) { + case ege::PaintDef::CLEAR: { + // TODO actually make this clear + sp_repr_css_set_property( css, attrName, "none" ); + descr = secondary? _("Remove stroke color") : _("Remove fill color"); + break; + } + case ege::PaintDef::NONE: { + sp_repr_css_set_property( css, attrName, "none" ); + descr = secondary? _("Set stroke color to none") : _("Set fill color to none"); + break; + } +//mark + case ege::PaintDef::RGB: { + Glib::ustring colorspec; + if ( _grad ){ + colorspec = "url(#"; + colorspec += _grad->getId(); + colorspec += ")"; + } else { + gchar c[64]; + guint32 rgba = (def.getR() << 24) | (def.getG() << 16) | (def.getB() << 8) | 0xff; + sp_svg_write_color(c, sizeof(c), rgba); + colorspec = c; + } +//end mark + sp_repr_css_set_property( css, attrName, colorspec.c_str() ); + descr = secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"); + break; } - } else { - cr->set_source_rgb(1, 1, 1); - cr->paint(); - cr->set_source_rgb(1, 0, 0); - cr->set_line_width(3); - cr->move_to(0,0); - cr->line_to(get_allocation().get_width(), get_allocation().get_height()); - cr->move_to(get_allocation().get_width(), 0); - cr->line_to(0, get_allocation().get_height()); - cr->stroke(); } + sp_desktop_set_style(desktop, css); + sp_repr_css_attr_unref(css); + + DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); } - return true; } -ColorItem::~ColorItem() +void ColorItem::_wireMagicColors( SwatchPage *colorSet ) +{ + if ( colorSet ) + { + for ( boost::ptr_vector::iterator it = colorSet->_colors.begin(); it != colorSet->_colors.end(); ++it ) + { + std::string::size_type pos = it->def.descr.find("*{"); + if ( pos != std::string::npos ) + { + std::string subby = it->def.descr.substr( pos + 2 ); + std::string::size_type endPos = subby.find("}*"); + if ( endPos != std::string::npos ) + { + subby.erase( endPos ); + //g_message("FOUND MAGIC at '%s'", (*it)->def.descr.c_str()); + //g_message(" '%s'", subby.c_str()); + + if ( subby.find('E') != std::string::npos ) + { + it->def.setEditable( true ); + } + + if ( subby.find('L') != std::string::npos ) + { + it->_isLive = true; + } + + std::string part; + // Tint. index + 1 more val. + if ( getBlock( part, 'T', subby ) ) { + guint64 colorIndex = 0; + if ( popVal( colorIndex, part ) ) { + guint64 percent = 0; + if ( popVal( percent, part ) ) { + it->_linkTint( colorSet->_colors[colorIndex], percent ); + } + } + } + + // Shade/tone. index + 1 or 2 more val. + if ( getBlock( part, 'S', subby ) ) { + guint64 colorIndex = 0; + if ( popVal( colorIndex, part ) ) { + guint64 percent = 0; + if ( popVal( percent, part ) ) { + guint64 grayLevel = 0; + if ( !popVal( grayLevel, part ) ) { + grayLevel = 0; + } + it->_linkTone( colorSet->_colors[colorIndex], percent, grayLevel ); + } + } + } + + } + } + } + } +} + + +void ColorItem::_linkTint( ColorItem& other, int percent ) +{ + if ( !_linkSrc ) + { + other._listeners.push_back(this); + _linkIsTone = false; + _linkPercent = percent; + if ( _linkPercent > 100 ) + _linkPercent = 100; + if ( _linkPercent < 0 ) + _linkPercent = 0; + _linkGray = 0; + _linkSrc = &other; + + ColorItem::_colorDefChanged(&other); + } +} + +void ColorItem::_linkTone( ColorItem& other, int percent, int grayLevel ) { - sel_connection.disconnect(); - mod_connection.disconnect(); + if ( !_linkSrc ) + { + other._listeners.push_back(this); + _linkIsTone = true; + _linkPercent = percent; + if ( _linkPercent > 100 ) + _linkPercent = 100; + if ( _linkPercent < 0 ) + _linkPercent = 0; + _linkGray = grayLevel; + _linkSrc = &other; + + ColorItem::_colorDefChanged(&other); + } } } // namespace Dialogs diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h index 5d97d8803..3a0b33193 100644 --- a/src/ui/dialog/color-item.h +++ b/src/ui/dialog/color-item.h @@ -15,11 +15,7 @@ #include #include "widgets/ege-paint-def.h" -#include "widgets/eek-preview.h" -#include -#include -#include "desktop.h" -#include "selection.h" +#include "ui/previewable.h" class SPGradient; @@ -27,43 +23,89 @@ namespace Inkscape { namespace UI { namespace Dialogs { +class ColorItem; + +class SwatchPage +{ +public: + SwatchPage(); + ~SwatchPage(); + + Glib::ustring _name; + int _prefWidth; + boost::ptr_vector _colors; +}; + /** * The color swatch you see on screen as a clickable box. */ -class ColorItem : public Gtk::Widget +class ColorItem : public Inkscape::UI::Previewable { + friend void _loadPaletteFile( gchar const *filename ); public: - ColorItem( SPGradient * grad, const gchar* name, SPDesktop* desktop ); + ColorItem( ege::PaintDef::ColorType type ); + ColorItem( unsigned int r, unsigned int g, unsigned int b, + Glib::ustring& name ); virtual ~ColorItem(); - - SPGradient * getGradient() { return gradient; } - -protected: - - const gchar* def; - SPGradient * gradient; - virtual bool on_enter_notify_event(GdkEventCrossing* event); - virtual bool on_leave_notify_event(GdkEventCrossing* event); - - virtual void on_size_request(Gtk::Requisition* requisition); - virtual void on_size_allocate(Gtk::Allocation& allocation); - virtual void on_map(); - virtual void on_unmap(); - virtual void on_realize(); - virtual void on_unrealize(); - virtual bool on_expose_event(GdkEventExpose* event); - - Glib::RefPtr m_refGdkWindow; - - + ColorItem(ColorItem const &other); + virtual ColorItem &operator=(ColorItem const &other); + virtual Gtk::Widget* getPreview(PreviewStyle style, + ViewType view, + ::PreviewSize size, + guint ratio, + guint border); + void buttonClicked(bool secondary = false); + + 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; } + bool isStroke() { return _isStroke; } + + ege::PaintDef def; + private: - void selection_changed(Selection* selection); - void selection_modified(Selection* selection, guint flags); - sigc::connection sel_connection; - sigc::connection mod_connection; - bool _isSelected; + static void _dropDataIn( GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint event_time, + gpointer user_data); + + static void _dragGetColorData( GtkWidget *widget, + GdkDragContext *drag_context, + GtkSelectionData *data, + guint info, + guint time, + gpointer user_data); + + static void _wireMagicColors( SwatchPage *colorSet ); + static void _colorDefChanged(void* data); + + void _updatePreviews(); + void _regenPreview(EekPreview * preview); + + void _linkTint( ColorItem& other, int percent ); + void _linkTone( ColorItem& other, int percent, int grayLevel ); + + std::vector _previews; + + bool _isFill; + bool _isStroke; + bool _isLive; + bool _linkIsTone; + int _linkPercent; + int _linkGray; + ColorItem* _linkSrc; + SPGradient* _grad; + cairo_pattern_t *_pattern; + std::vector _listeners; }; } // namespace Dialogs diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 82b2cf6b1..8f36cba43 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -467,6 +467,7 @@ void ObjectProperties::label_changed(void) blocked = true; /* Retrieve the label widget for the object's id */ + //bug 1290573: getId() crashes after undo (cannot create string from NULL ptr) gchar *id = g_strdup(EntryID.get_text().c_str()); g_strcanon (id, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.:", '_'); if (!strcmp (id, item->getId())) { diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index ebfa16f02..2095546fb 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -3,6 +3,7 @@ * * Authors: * Theodore Janeczko + * Tweaked by Liam P White for use in Inkscape * * Copyright (C) Theodore Janeczko 2012 * @@ -17,20 +18,31 @@ #include #include #include +#include #include #include "desktop.h" #include "desktop-style.h" +#include "dialogs/dialog-events.h" #include "document.h" #include "document-undo.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" #include "helper/action.h" #include "inkscape.h" +#include "layer-manager.h" #include "preferences.h" +#include "selection.h" +#include "sp-clippath.h" +#include "sp-mask.h" #include "sp-item.h" #include "sp-object.h" +#include "sp-root.h" #include "sp-shape.h" -#include "svg/css-ostringstream.h" +#include "style.h" +#include "tools-switch.h" #include "ui/icon-names.h" #include "ui/widget/imagetoggler.h" #include "ui/widget/layertypeicon.h" @@ -38,29 +50,16 @@ #include "ui/widget/clipmaskicon.h" #include "ui/widget/highlight-picker.h" #include "ui/tools/node-tool.h" +#include "ui/tools/tool-base.h" #include "verbs.h" +#include "widgets/sp-color-notebook.h" #include "widgets/icon.h" #include "xml/node.h" #include "xml/node-observer.h" #include "xml/repr.h" -#include "sp-root.h" -//#include "event-context.h" -#include "selection.h" -#include "dialogs/dialog-events.h" -#include "widgets/sp-color-notebook.h" -#include "style.h" -#include "filter-chemistry.h" -#include "filters/blend.h" -#include "filters/gaussian-blur.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "layer-manager.h" -#include "tools-switch.h" //#define DUMP_LAYERS 1 -guint get_group0_keyval(GdkEventKey *event); - namespace Inkscape { namespace UI { namespace Dialog { @@ -82,7 +81,7 @@ enum { COL_VISIBLE = 1, COL_LOCKED, COL_TYPE, - COL_INSERTORDER, +// COL_INSERTORDER, COL_CLIPMASK, COL_HIGHLIGHT }; @@ -106,8 +105,8 @@ enum { BUTTON_LOCK_ALL, BUTTON_UNLOCK_ALL, BUTTON_SETCLIP, - BUTTON_CLIPGROUP, - BUTTON_SETINVCLIP, +// BUTTON_CLIPGROUP, +// BUTTON_SETINVCLIP, BUTTON_UNSETCLIP, BUTTON_SETMASK, BUTTON_UNSETMASK, @@ -214,7 +213,7 @@ public: add(_colType); add(_colHighlight); add(_colClipMask); - add(_colInsertOrder); + //add(_colInsertOrder); } virtual ~ModelColumns() {} @@ -225,7 +224,7 @@ public: Gtk::TreeModelColumn _colType; Gtk::TreeModelColumn _colHighlight; Gtk::TreeModelColumn _colClipMask; - Gtk::TreeModelColumn _colInsertOrder; + //Gtk::TreeModelColumn _colInsertOrder; }; /** @@ -352,13 +351,19 @@ void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); Gtk::TreeModel::Row row = *iter; row[_model->_colObject] = item; - row[_model->_colLabel] = item->label() ? item->label() : item->getId(); + //this seems to crash on convert stroke to path then undo (probably no ID?) + try { + row[_model->_colLabel] = item->label() ? item->label() : item->getId(); + } catch (...) { + row[_model->_colLabel] = Glib::ustring("getId_failure"); + g_critical("item->getId() failed, using \"getId_failure\""); + } row[_model->_colVisible] = !item->isHidden(); row[_model->_colLocked] = !item->isSensitive(); row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00; row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0); - row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + //row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; //If our parent object is a group and it's expanded, expand the tree if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded()) @@ -388,7 +393,10 @@ void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) */ void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) { //Find the object in the tree store and update it + + //mark _store->foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_checkForUpdated), obj) ); + //end mark if (recurse) { for (SPObject * iter = obj->children; iter != NULL; iter = iter->next) @@ -419,7 +427,7 @@ bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; - row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + //row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; return true; } @@ -685,7 +693,9 @@ void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const b bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + bool empty = _desktop->selection->isEmpty(); + + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: @@ -702,68 +712,33 @@ bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) } break; case GDK_Home: - { //Move item(s) to top of containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_TOP ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_FRONT ); - } - return true; - } + _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT ); + break; case GDK_End: - { //Move item(s) to bottom of containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_BOTTOM ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_BACK ); - } - return true; - } + _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK ); + break; case GDK_KEY_Page_Up: { //Move item(s) up in containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_RAISE ); - } - else - { - if (event->state & GDK_SHIFT_MASK) { - _fireAction( SP_VERB_LAYER_MOVE_TO_NEXT ); - } else { - _fireAction( SP_VERB_SELECTION_RAISE ); - } - } - return true; + int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_NEXT : SP_VERB_SELECTION_RAISE; + _fireAction( empty ? SP_VERB_LAYER_RAISE : ch ); + break; } case GDK_KEY_Page_Down: { //Move item(s) down in containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_LOWER ); - } - else - { - if (event->state & GDK_SHIFT_MASK) { - _fireAction( SP_VERB_LAYER_MOVE_TO_PREV ); - } else { - _fireAction( SP_VERB_SELECTION_LOWER ); - } - } - return true; + int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_PREV : SP_VERB_SELECTION_LOWER; + _fireAction( empty ? SP_VERB_LAYER_LOWER : ch ); + break; } + //TODO: Handle Ctrl-A, etc. + default: + return false; } - return false; + return true; } /** @@ -809,7 +784,7 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) return true; } else if (col == _tree.get_column(COL_LOCKED-1) || col == _tree.get_column(COL_TYPE-1) || - col == _tree.get_column(COL_INSERTORDER - 1) || + //col == _tree.get_column(COL_INSERTORDER - 1) || col == _tree.get_column(COL_HIGHLIGHT-1)) { //Click on an icon column, eat this event to keep row selection return true; @@ -926,7 +901,7 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, newValue? _("Layer to group") : _("Group to layer")); } - } else if (col == _tree.get_column(COL_INSERTORDER - 1)) { + } /*else if (col == _tree.get_column(COL_INSERTORDER - 1)) { if (SP_IS_GROUP(item)) { //Toggle the current item's insert order @@ -938,7 +913,7 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, newValue? _("Set insert mode bottom") : _("Set insert mode top")); } - } else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { + }*/ else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { //Clear the highlight targets _highlight_target.clear(); if (_tree.get_selection()->is_selected(path)) @@ -1474,7 +1449,7 @@ void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) target->setHighlightColor(rgba); target->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); } - DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); + DocumentUndo::maybeDone(SP_ACTIVE_DOCUMENT, "highlight", SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); } /** @@ -1689,13 +1664,13 @@ ObjectsPanel::ObjectsPanel() : col->add_attribute( typeRenderer->property_active(), _model->_colType ); } - //Insert order - Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon()); + //Insert order (LiamW: unused) + /*Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon()); int insertColNum = _tree.append_column("type", *insertRenderer) - 1; col = _tree.get_column(insertColNum); if ( col ) { col->add_attribute( insertRenderer->property_active(), _model->_colInsertOrder ); - } + }*/ //Clip/mask Inkscape::UI::Widget::ClipMaskIcon * clipRenderer = Gtk::manage( new Inkscape::UI::Widget::ClipMaskIcon()); @@ -1807,43 +1782,102 @@ ObjectsPanel::ObjectsPanel() : SPDesktop* targetDesktop = getDesktop(); //Set up the button row + + + //Add object/layer Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_ADD, _("New Layer") ); + btn->set_tooltip_text(_("Add layer...")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + Gtk::Image *image_add = Gtk::manage(new Gtk::Image()); + image_add->set_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_add); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + //Remove object btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_REMOVE, _("Remove") ); + btn->set_tooltip_text(_("Remove object")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + Gtk::Image *image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) ); _watching.push_back( btn ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + //Move to bottom btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GOTO_BOTTOM, _("Move To Bottom") ); + btn->set_tooltip_text(_("Move To Bottom")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - + + //Move down btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GO_DOWN, _("Move Down") ); + btn->set_tooltip_text(_("Move Down")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + //Move up btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GO_UP, _("Move Up") ); + btn->set_tooltip_text(_("Move Up")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + //Move to top btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GOTO_TOP, _("Move To Top") ); + btn->set_tooltip_text(_("Move To Top")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_UNINDENT, _("Collapse All") ); + //Collapse all + btn = Gtk::manage( new Gtk::Button(Gtk::Stock::UNINDENT) ); + btn->set_tooltip_text(_("Collapse All")); + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); @@ -2042,15 +2076,6 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop ) //should be okay to put these here because they are never referenced anywhere else using namespace Inkscape::UI::Tools; -guint get_group0_keyval(GdkEventKey *event) { - guint keyval = 0; - gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( - gdk_display_get_default()), event->hardware_keycode, - (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, - NULL, NULL, NULL); - return keyval; -} - void SPItem::setHighlightColor(guint32 const color) { g_free(_highlightColor); @@ -2065,7 +2090,7 @@ void SPItem::setHighlightColor(guint32 const color) NodeTool *tool = 0; if (SP_ACTIVE_DESKTOP ) { - ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; if (INK_IS_NODE_TOOL(ec)) { tool = static_cast(ec); tools_switch(tool->desktop, TOOLS_NODES); @@ -2079,7 +2104,7 @@ void SPItem::unsetHighlightColor() _highlightColor = NULL; NodeTool *tool = 0; if (SP_ACTIVE_DESKTOP ) { - ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; if (INK_IS_NODE_TOOL(ec)) { tool = static_cast(ec); tools_switch(tool->desktop, TOOLS_NODES); diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 2a8471b55..807618b4d 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -6,7 +6,6 @@ * Jon A. Cruz * John Bintz * Abhishek Sharma - * Theodore Janezcko * * Copyright (C) 2005 Jon A. Cruz * Copyright (C) 2008 John Bintz @@ -21,7 +20,6 @@ #include "swatches.h" #include -#include #include #include @@ -47,6 +45,7 @@ #include "sp-gradient.h" #include "sp-gradient-vector.h" #include "style.h" +#include "ui/previewholder.h" #include "widgets/desktop-widget.h" #include "widgets/gradient-vector.h" #include "widgets/eek-preview.h" @@ -57,2305 +56,1130 @@ #include "verbs.h" #include "gradient-chemistry.h" #include "helper/action.h" -#include "xml/node-observer.h" -#include "xml/repr.h" -#include "sp-pattern.h" -#include "icon-size.h" -#include "widgets/icon.h" -#include "filedialog.h" -#include "sp-stop.h" -#include "svg/svg-color.h" -#include "sp-radial-gradient.h" -#include "color-rgba.h" -#include "ui/tools/tool-base.h" -#include "svg/css-ostringstream.h" -#include -#ifdef WIN32 -#include -#endif - -//lazy! -void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); +#include "helper/action-context.h" namespace Inkscape { namespace UI { namespace Dialogs { -#define SWATCHES_FILE_NAME "swatches.svg" - -static char* trim( char* str ) { - char* ret = str; - while ( *str && (*str == ' ' || *str == '\t') ) { - str++; - } - ret = str; - while ( *str ) { - str++; - } - str--; - while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { - *str-- = 0; - } - return ret; -} - -static void skipWhitespace( char*& str ) { - while ( *str == ' ' || *str == '\t' ) { - str++; - } -} - -static bool parseNum( char*& str, int& val ) { - val = 0; - while ( '0' <= *str && *str <= '9' ) { - val = val * 10 + (*str - '0'); - str++; - } - bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); - return retval; -} - -static char * SwatchFile; -static SPDocument * SwatchDocument; -static unsigned int page_suffix; - -static void loadPalletFile() -{ - if (!SwatchDocument) { - SwatchFile=g_build_filename(INKSCAPE_PALETTESDIR, _("swatches.svg"), NULL); - SwatchDocument=SPDocument::createNewDoc (SwatchFile, TRUE); - if (!SwatchDocument) { - SwatchDocument = SPDocument::createNewDoc(NULL, TRUE, true); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } - } -} - -static void addStop( Inkscape::XML::Node *parent, Glib::ustring const &color, gfloat opacity, gchar const *offset ) -{ -#ifdef SP_GR_VERBOSE - g_message("addStop(%p, %s, %d, %s)", parent, color.c_str(), opacity, offset); -#endif - Inkscape::XML::Node *stop = parent->document()->createElement("svg:stop"); - { - gchar *tmp = g_strdup_printf( "stop-color:%s;stop-opacity:%f;", color.c_str(), opacity < 0.0 ? 0.0 : (opacity > 1.0 ? 1.0 : opacity) ); - stop->setAttribute( "style", tmp ); - g_free(tmp); - } - - stop->setAttribute( "offset", offset ); - - parent->appendChild(stop); - Inkscape::GC::release(stop); -} - -static SPGroup* importGPL(SPDocument* doc, const gchar* full) -{ - SPGroup* ret = NULL; - if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { - - /*Load the pallet file here*/ - char block[1024]; - FILE *f = Inkscape::IO::fopen_utf8name( full, "r" ); - if ( f ) { - char* result = fgets( block, sizeof(block), f ); - if ( result ) { - if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { - bool inHeader = true; - bool hasErr = false; - - Inkscape::XML::Node * page = doc->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (doc->getObjectById(id)); - - page->setAttribute("id", id); - - do { - result = fgets( block, sizeof(block), f ); - block[sizeof(block) - 1] = 0; - if ( result ) { - if ( block[0] == '#' ) { - // ignore comment - } else { - char *ptr = block; - // very simple check for header versus entry - while ( *ptr == ' ' || *ptr == '\t' ) { - ptr++; - } - if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { - // blank line. skip it. - } else if ( '0' <= *ptr && *ptr <= '9' ) { - // should be an entry link - inHeader = false; - ptr = block; - Glib::ustring name(""); - skipWhitespace(ptr); - if ( *ptr ) { - int r = 0; - int g = 0; - int b = 0; - hasErr = parseNum(ptr, r); - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, g); - } - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, b); - } - if ( !hasErr && *ptr ) { - char* n = trim(ptr); - if (n != NULL) { - name = g_dpgettext2(NULL, "Palette", n); - } - } - if ( !hasErr ) { - // Add the entry now - - Inkscape::XML::Node *grad = doc->getReprDoc()->createElement("svg:linearGradient"); - grad->setAttribute("inkscape:label", name.c_str()); - grad->setAttribute( "osb:paint", "solid", 0 ); - SPColor color((float)r / 255, (float)g / 255, (float)b / 255); - addStop(grad, color.toString(), 1, "0"); - page->appendChild(grad); - Inkscape::GC::release(grad); - } - } else { - hasErr = true; - } - } else { - if ( !inHeader ) { - // Hmmm... probably bad. Not quite the format we want? - hasErr = true; - } else { - char* sep = strchr(result, ':'); - if ( sep ) { - *sep = 0; - char* val = trim(sep + 1); - char* name = trim(result); - if ( *name ) { - if ( strcmp( "Name", name ) == 0 ) - { - page->setAttribute("inkscape:label", val); - } - } else { - // error - hasErr = true; - } - } else { - // error - hasErr = true; - } - } - } - } - } - } while ( result && !hasErr ); - if ( !hasErr ) { - doc->getDefs()->appendChild(page); - Inkscape::GC::release(page); - SPObject* obj = doc->getObjectByRepr(page); - if (SP_IS_GROUP(obj)) { - ret = SP_GROUP(obj); - } - #if ENABLE_MAGIC_COLORS - ColorItem::_wireMagicColors( onceMore ); - #endif // ENABLE_MAGIC_COLORS - } else { - delete page; - } - } - } - - fclose(f); - } - /* end loading the pallet file*/ - } - return ret; -} - -SwatchesPanel& SwatchesPanel::getInstance() -{ - return *new SwatchesPanel(); -} - -class SwatchesPanel::StopWatcher : public Inkscape::XML::NodeObserver { -public: - StopWatcher(SwatchesPanel* pnl, SPStop* obj) : - _pnl(pnl), - _obj(obj), - _repr(obj->getRepr()) - { - _repr->addObserver(*this); - } - - ~StopWatcher() { - _repr->removeObserver(*this); - } - - virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} - virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} - virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ){} - virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - - virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if (_pnl && _obj) { - _pnl->_defsChanged( ); - } - } +#define VBLOCK 16 +#define PREVIEW_PIXBUF_WIDTH 128 - SwatchesPanel* _pnl; - SPStop* _obj; - Inkscape::XML::Node* _repr; -}; +void _loadPaletteFile( gchar const *filename, gboolean user=FALSE ); -class SwatchesPanel::GradientWatcher : public Inkscape::XML::NodeObserver { -public: - GradientWatcher(SwatchesPanel* pnl, SPGradient* obj) : - _pnl(pnl), - _obj(obj), - _repr(obj->getRepr()), - _labelAttr(g_quark_from_string("inkscape:label")), - _swatchAttr(g_quark_from_string("osb:paint")) - { - _repr->addObserver(*this); - } - - ~GradientWatcher() { - _repr->removeObserver(*this); - } - - virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj && _obj->isSwatch()) { - _pnl->_defsChanged( ); - } - } - virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj && _obj->isSwatch() ) { - _pnl->_defsChanged( ); - } - } - virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) - { - if ( _pnl && _obj && _obj->isSwatch() ) { - _pnl->_defsChanged( ); - } - } - virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if (_pnl && _obj && ((_obj->isSwatch() && name == _labelAttr) || name == _swatchAttr)) { - _pnl->_defsChanged( ); - } - } - - SwatchesPanel* _pnl; - SPGradient* _obj; - Inkscape::XML::Node* _repr; - GQuark _labelAttr; - GQuark _swatchAttr; -}; - -class SwatchesPanel::SwatchWatcher : public Inkscape::XML::NodeObserver { -public: - SwatchWatcher(SwatchesPanel* pnl, SPObject* obj, bool builtIn) : - _pnl(pnl), - _obj(obj), - _builtIn(builtIn), - _repr(obj->getRepr()), - _labelAttr(g_quark_from_string("inkscape:label")), - _swatchAttr(g_quark_from_string("osb:paint")) - { - _repr->addObserver(*this); - } - - ~SwatchWatcher() { - _repr->removeObserver(*this); - } - - virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj) { - SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); - if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } - } - virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } - virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) - { - if ( _pnl && _obj) { - SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); - if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } - } - virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if (_pnl && _obj && name == _labelAttr) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } +std::list userSwatchPages; +std::list systemSwatchPages; +static std::map docPalettes; +static std::vector docTrackings; +static std::map docPerPanel; - SwatchesPanel* _pnl; - SPObject* _obj; - bool _builtIn; - Inkscape::XML::Node* _repr; - GQuark _labelAttr; - GQuark _swatchAttr; -}; -class SwatchesPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +class SwatchesPanelHook : public SwatchesPanel { public: - - ModelColumns() - { - add(_colObject); - add(_colLabel); - } - virtual ~ModelColumns() {} - - Gtk::TreeModelColumn _colObject; - Gtk::TreeModelColumn _colLabel; + static void convertGradient( GtkMenuItem *menuitem, gpointer userData ); + static void deleteGradient( GtkMenuItem *menuitem, gpointer userData ); }; -class SwatchesPanel::ModelColumnsDoc : public Gtk::TreeModel::ColumnRecord -{ -public: - - ModelColumnsDoc() - { - add(_colObject); - add(_colLabel); - add(_colPixbuf); +static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(false); } - virtual ~ModelColumnsDoc() {} - - Gtk::TreeModelColumn _colObject; - Gtk::TreeModelColumn _colLabel; - Gtk::TreeModelColumn > _colPixbuf; -}; +} -static void StripChildGroups(Inkscape::XML::Node * node, SPObject* addTo) -{ - for (Inkscape::XML::Node * it = node->firstChild(); it != NULL;) { - if (!strcmp(it->name(), "svg:g")) { - Inkscape::XML::Node * todel = it; - it = it->next(); - node->removeChild(todel); - } else { - it = it->next(); - } +static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(true); } - addTo->appendChildRepr(node); } -static void BubbleChildGroups(Inkscape::XML::Node * node, SPObject* addTo) +static GtkWidget* popupMenu = 0; +static GtkWidget *popupSubHolder = 0; +static GtkWidget *popupSub = 0; +static std::vector popupItems; +static std::vector popupExtras; +static ColorItem* bounceTarget = 0; +static SwatchesPanel* bouncePanel = 0; + +static void redirClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) { - std::queue groups; - for (Inkscape::XML::Node * it = node->firstChild(); it != NULL; ) { - if (!strcmp(it->name(), "svg:g")) { - groups.push(it->duplicate(addTo->document->getReprDoc())); - Inkscape::XML::Node * todel = it; - it = it->next(); - node->removeChild(todel); - } else { - it = it->next(); - } - } - addTo->appendChildRepr(node); - while (!groups.empty()) { - Inkscape::XML::Node * it = groups.front(); - groups.pop(); - BubbleChildGroups(it, addTo); - Inkscape::GC::release(it); + if ( bounceTarget ) { + handleClick( GTK_WIDGET(menuitem), bounceTarget ); } } -void SwatchesPanel::_addSwatchButtonClicked(SPGroup* swatch, bool recurse) +static void redirSecondaryClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) { - if (_currentDocument) { - if (swatch && SP_IS_GROUP(swatch) ) { - Inkscape::XML::Node * copy = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); - if (recurse) { - BubbleChildGroups(copy, _currentDocument->getDefs()); - } else { - StripChildGroups(copy, _currentDocument->getDefs()); - } - Inkscape::GC::release(copy); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); - } + if ( bounceTarget ) { + handleSecondaryClick( GTK_WIDGET(menuitem), 0, bounceTarget ); } } -void SwatchesPanel::_importButtonClicked(bool addToDoc, bool addToBI) +static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) { - if (addToDoc || addToBI) { - //# Get the current directory for finding files - static Glib::ustring open_path; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - if(open_path.empty()) - { - Glib::ustring attr = prefs->getString("/dialogs/open/path"); - if (!attr.empty()) open_path = attr; - } - - //# Test if the open_path directory exists - if (!Inkscape::IO::file_test(open_path.c_str(), - (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) - open_path = ""; - - #ifdef WIN32 - //# If no open path, default to our win32 documents folder - if (open_path.empty()) - { - // The path to the My Documents folder is read from the - // value "HKEY_CURRENT_USER\Software\Windows\CurrentVersion\Explorer\Shell Folders\Personal" - HKEY key = NULL; - if(RegOpenKeyExA(HKEY_CURRENT_USER, - "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", - 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) - { - WCHAR utf16path[_MAX_PATH]; - DWORD value_type; - DWORD data_size = sizeof(utf16path); - if(RegQueryValueExW(key, L"Personal", NULL, &value_type, - (BYTE*)utf16path, &data_size) == ERROR_SUCCESS) - { - g_assert(value_type == REG_SZ); - gchar *utf8path = g_utf16_to_utf8( - (const gunichar2*)utf16path, -1, NULL, NULL, NULL); - if(utf8path) - { - open_path = Glib::ustring(utf8path); - g_free(utf8path); + if ( gr ) { + bool shown = false; + if ( desktop && desktop->doc() ) { + Inkscape::Selection *selection = sp_desktop_selection( desktop ); + GSList const *items = selection->itemList(); + if (items) { + SPStyle *query = sp_style_new( desktop->doc() ); + int result = objects_query_fillstroke(const_cast(items), query, true); + if ( (result == QUERY_STYLE_MULTIPLE_SAME) || (result == QUERY_STYLE_SINGLE) ) { + // could be pertinent + if (query->fill.isPaintserver()) { + SPPaintServer* server = query->getFillPaintServer(); + if ( SP_IS_GRADIENT(server) ) { + SPGradient* grad = SP_GRADIENT(server); + if ( grad->isSwatch() && grad->getId() == gr->getId()) { + desktop->_dlg_mgr->showDialog("FillAndStroke"); + shown = true; + } + } } } + sp_style_unref(query); } } - #endif - - //# If no open path, default to our home directory - if (open_path.empty()) - { - open_path = g_get_home_dir(); - open_path.append(G_DIR_SEPARATOR_S); - } - Gtk::Window * parent = SP_ACTIVE_DESKTOP->getToplevel(); - //# Create a dialog - Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance = - Inkscape::UI::Dialog::FileOpenDialog::create( - *parent, open_path, - Inkscape::UI::Dialog::SWATCH_TYPES, - _("Select file to open")); - - //# Show the dialog - bool const success = openDialogInstance->show(); - - //# Save the folder the user selected for later - open_path = openDialogInstance->getCurrentDirectory(); - - if (!success) - { - delete openDialogInstance; - return; - } - - //# User selected something. Get name and type - Glib::ustring fileName = openDialogInstance->getFilename(); - - //# We no longer need the file dialog object - delete it - delete openDialogInstance; - openDialogInstance = NULL; - - - if (!fileName.empty()) - { - Glib::ustring newFileName = Glib::filename_to_utf8(fileName); - - if ( newFileName.size() > 0) - fileName = newFileName; - else - g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); - - open_path = Glib::path_get_dirname (fileName); - open_path.append(G_DIR_SEPARATOR_S); - prefs->setString("/dialogs/open/path", open_path); - - SPDocument* importdoc = SPDocument::createNewDoc(fileName.c_str(), true); - Inkscape::XML::Node * page = NULL; - if (importdoc && importdoc->getDefs()) { - if (addToBI) { - page = SwatchDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (SwatchDocument->getObjectById(id)); - - page->setAttribute("id", id); - gchar* name = g_path_get_basename(importdoc->getName()); - page->setAttribute("inkscape:label", name); - g_free(name); - } - - for (SPObject* it = importdoc->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GROUP(it)) { - if (page) { - Inkscape::XML::Node * copy = it->getRepr()->duplicate(SwatchDocument->getReprDoc()); - page->appendChild(copy); - } - if (addToDoc) { - _addSwatchButtonClicked(SP_GROUP(it), false); - } - } - } - if (page) { - SwatchDocument->getDefs()->appendChildRepr(page); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } - - importdoc->doUnref(); + if (!shown) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getBool("/dialogs/gradienteditor/showlegacy", false)) { + // Legacy gradient dialog + GtkWidget *dialog = sp_gradient_vector_editor_new( gr ); + gtk_widget_show( dialog ); } else { - SPGroup* g = importGPL(addToBI ? SwatchDocument : _currentDocument, fileName.c_str()); - if (addToBI) { - if (addToDoc) { - _addSwatchButtonClicked(g, false); + // Invoke the gradient tool + Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT ); + if ( verb ) { + SPAction *action = verb->get_action( Inkscape::ActionContext( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP ) ); + if ( action ) { + sp_action_perform( action, NULL ); } - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } else { - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); } } } } } -void SwatchesPanel::SetSelectedFill(SPGradient* swatch) +static void editGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ ) { - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->fill.isSet()) { - if (it->style->fill.isPaintserver()) { - SPPaintServer * server = it->style->getFillPaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = swatch->getRepr(); - if (repr != drepr && grad != swatch) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { - Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); - swatch->appendChildRepr(clone); - Inkscape::GC::release(clone); - } - swatch->setSwatch(); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); - } - } - } else if (it->style->fill.isColor()) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - addStop(swatch->getRepr(), it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); - swatch->setSwatch(); - if (!_noLink.get_active()) { - SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); + if ( bounceTarget ) { + SwatchesPanel* swp = bouncePanel; + SPDesktop* desktop = swp ? swp->getDesktop() : 0; + SPDocument *doc = desktop ? desktop->doc() : 0; + if (doc) { + std::string targetName(bounceTarget->def.descr); + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( targetName == grad->getId() ) { + editGradientImpl( desktop, grad ); + break; } } } } } -void SwatchesPanel::SetSelectedStroke(SPGradient* swatch) +void SwatchesPanelHook::convertGradient( GtkMenuItem * /*menuitem*/, gpointer userData ) { - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->stroke.isSet()) { - if (it->style->stroke.isPaintserver()) { - SPPaintServer * server = it->style->getStrokePaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = swatch->getRepr(); - if (repr != drepr && grad != swatch) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { - Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); - swatch->appendChildRepr(clone); - Inkscape::GC::release(clone); - } - swatch->setSwatch(); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); - } - } - } else if (it->style->stroke.isColor()) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - addStop(swatch->getRepr(), it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); - swatch->setSwatch(); - if (!_noLink.get_active()) { - SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); + if ( bounceTarget ) { + SwatchesPanel* swp = bouncePanel; + SPDesktop* desktop = swp ? swp->getDesktop() : 0; + SPDocument *doc = desktop ? desktop->doc() : 0; + gint index = GPOINTER_TO_INT(userData); + if ( doc && (index >= 0) && (static_cast(index) < popupItems.size()) ) { + Glib::ustring targetName = popupItems[index]; + + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( targetName == grad->getId() ) { + grad->setSwatch(); + DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT, + _("Add gradient stop")); + break; } } } } } -void SwatchesPanel::MoveSwatchDown(SPGradient* swatch) +void SwatchesPanelHook::deleteGradient( GtkMenuItem */*menuitem*/, gpointer /*userData*/ ) { - if (_currentDocument && swatch) { - SPObject* next = swatch->next; - while (next && (!SP_IS_GRADIENT(next) || !(SP_GRADIENT(next)->isSwatch()))) { - next = next->next; - } - if (next) { - Inkscape::XML::Node* repr = swatch->getRepr(); - repr->parent()->changeOrder(repr, next->getRepr()); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Right")); - } + if ( bounceTarget ) { + SwatchesPanel* swp = bouncePanel; + SPDesktop* desktop = swp ? swp->getDesktop() : 0; + sp_gradient_unset_swatch(desktop, bounceTarget->def.descr); } } -void SwatchesPanel::MoveSwatchUp(SPGradient* swatch) +static SwatchesPanel* findContainingPanel( GtkWidget *widget ) { - if (_currentDocument && swatch) { - SPObject* g = NULL; - SPObject* next = swatch->parent->firstChild(); - while (next && next != swatch) { - if (SP_IS_GRADIENT(next) && SP_GRADIENT(next)->isSwatch()) { - g = next; - } - next = next->next; - } - if (g) { - g = g->getPrev(); - Inkscape::XML::Node* repr = swatch->getRepr(); - repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Left")); - } - } -} + SwatchesPanel *swp = 0; -void SwatchesPanel::RemoveSwatch(SPGradient* swatch) -{ - if (_currentDocument) { - if (swatch->isReferenced()) { - Inkscape::XML::Node * repr = swatch->getRepr(); - repr->parent()->removeChild(repr); - _currentDocument->getDefs()->getRepr()->appendChild(repr); - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); - } else { - swatch->deleteObject(false); - } + std::map rawObjects; + for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { + rawObjects[GTK_WIDGET(it->first->gobj())] = it->first; } -} -void SwatchesPanel::_setSelectionSwatch(SPGradient* swatch, bool isStroke) -{ - if (_currentDocument) { - if (swatch) { - if (_noLink.get_active()) { - if (swatch->isSolid()) { - ColorRGBA rgba(swatch->getFirstStop()->getEffectiveColor().toRGBA32(swatch->getFirstStop()->opacity)); - sp_desktop_set_color(_currentDesktop, rgba, false, !isStroke); - } else { - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); - - Inkscape::XML::Node * clone = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); - _currentDocument->getDefs()->appendChildRepr(clone); - SPGradient* grad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); - Inkscape::GC::release(clone); - grad->setSwatch(false); - SPGradient* normalized = sp_gradient_ensure_vector_normalized(grad); -// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { -// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); -// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); -// } - sp_desktop_set_style(_currentDesktop, css); - sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); - sp_repr_css_attr_unref (css); - } - } else { - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); - - SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); -// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { -// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); -// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); -// } - sp_desktop_set_style(_currentDesktop, css); - sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); - sp_repr_css_attr_unref (css); - } - } else { - SPCSSAttr *css = sp_repr_css_attr_new (); - sp_repr_css_set_property (css, isStroke ? "stroke" : "fill", "none"); - sp_desktop_set_style(_currentDesktop, css); - } - if (isStroke) { - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item stroke swatch")); - } else { - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item fill swatch")); + for (GtkWidget* curr = widget; curr && !swp; curr = gtk_widget_get_parent(curr)) { + if (rawObjects.find(curr) != rawObjects.end()) { + swp = rawObjects[curr]; } } -} - -void SwatchesPanel::_swatchClicked(GdkEventButton* event, SPGradient* swatch) -{ - if (_currentDesktop) { - if (event->button == 3) { - Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); - - Gtk::MenuItem* mi; - - Glib::ustring us = Glib::ustring::compose("%1", swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]")); - mi = Gtk::manage(new Gtk::MenuItem(swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]"))); - Gtk::Label* namelbl = dynamic_cast(mi->get_child()); - if (namelbl) { - namelbl->set_markup(us); - } - mi->show(); - mi->set_sensitive(false); - menu->append(*mi); - - Gtk::SeparatorMenuItem* sep; - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set Fill"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, false)); - mi->show(); - mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set Stroke"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, true)); - mi->show(); - mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); - menu->append(*mi); - - if (swatch) { - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Fill"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedFill), swatch)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Stroke"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedStroke), swatch)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Left"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchUp), swatch)); - mi->show(); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Right"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchDown), swatch)); - mi->show(); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::RemoveSwatch), swatch)); - mi->show(); - menu->append(*mi); - } - menu->popup(event->button, event->time); - } else if (!_currentDesktop->selection->isEmpty()) { - _setSelectionSwatch(swatch, event->state & GDK_SHIFT_MASK); - } - } + return swp; } -void SwatchesPanel::MoveDown(SPGroup* page) +static void removeit( GtkWidget *widget, gpointer data ) { - if (_currentDocument && page) { - SPObject* next = page->next; - while (next && !SP_IS_GROUP(next)) { - next = next->next; - } - if (next) { - Inkscape::XML::Node* repr = page->getRepr(); - repr->parent()->changeOrder(repr, next->getRepr()); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Down")); - } - } + gtk_container_remove( GTK_CONTAINER(data), widget ); } -void SwatchesPanel::MoveUp(SPGroup* page) -{ - if (_currentDocument && page) { - SPObject* g = NULL; - SPObject* next = page->parent->firstChild(); - while (next && next != page) { - if (SP_IS_GROUP(next)) { - g = next; - } - next = next->next; - } - if (g) { - g = g->getPrev(); - Inkscape::XML::Node* repr = page->getRepr(); - repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Up")); - } - } -} +/* extern'ed from colot-item.cpp */ +gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ); -void SwatchesPanel::Remove(SPGroup* page) +gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ) { - if (_currentDocument && page) { - std::vector toMove; - for(SPObject* obj = page->firstChild(); obj != NULL; obj = obj->next) { - if (SP_IS_GRADIENT(obj)) { - SPGradient* grad = SP_GRADIENT(obj); - if (grad->isReferenced()) { - toMove.push_back(grad->getRepr()); - } + gboolean handled = FALSE; + + if ( event && (event->button == 3) && (event->type == GDK_BUTTON_PRESS) ) { + SwatchesPanel* swp = findContainingPanel( widget ); + + if ( !popupMenu ) { + popupMenu = gtk_menu_new(); + GtkWidget* child = 0; + + //TRANSLATORS: An item in context menu on a colour in the swatches + child = gtk_menu_item_new_with_label(_("Set fill")); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(redirClick), + user_data); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + + //TRANSLATORS: An item in context menu on a colour in the swatches + child = gtk_menu_item_new_with_label(_("Set stroke")); + + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(redirSecondaryClick), + user_data); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + + child = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + + child = gtk_menu_item_new_with_label(_("Delete")); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(SwatchesPanelHook::deleteGradient), + user_data ); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + gtk_widget_set_sensitive( child, FALSE ); + + child = gtk_menu_item_new_with_label(_("Edit...")); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(editGradient), + user_data ); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + + child = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + + child = gtk_menu_item_new_with_label(_("Convert")); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + //popupExtras.push_back(child); + //gtk_widget_set_sensitive( child, FALSE ); + { + popupSubHolder = child; + popupSub = gtk_menu_new(); + gtk_menu_item_set_submenu( GTK_MENU_ITEM(child), popupSub ); } + + gtk_widget_show_all(popupMenu); } - while (!toMove.empty()) { - Inkscape::XML::Node * repr = toMove.back(); - toMove.pop_back(); - repr->parent()->removeChild(repr); - _currentDocument->getDefs()->getRepr()->appendChild(repr); - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); - } - page->deleteObject(false); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Remove Swatch Group")); - } -} -void SwatchesPanel::AddSelectedFill(SPGroup* page) -{ - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->fill.isSet()) { - if (it->style->fill.isPaintserver()) { - SPPaintServer * server = it->style->getFillPaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - if (_noLink.get_active()) { - Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); - clone->setAttribute( "osb:paint", "gradient", 0 ); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); - } - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else if (grad->isSwatch()) { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); - } - SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); - - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); - if (repr->parent() != drepr) { - repr->parent()->removeChild(repr); - drepr->appendChild(repr); - } - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } - } - } else if (it->style->fill.isColor()) { - Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); - grad->setAttribute( "osb:paint", "solid", 0 ); - addStop(grad, it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); - if (page) { - page->appendChild(grad); - } else { - _currentDocument->getDefs()->appendChild(grad); - } - SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); - Inkscape::GC::release(grad); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); - } + if ( user_data ) { + ColorItem* item = reinterpret_cast(user_data); + bool show = swp && (swp->getSelectedIndex() == 0); + for ( std::vector::iterator it = popupExtras.begin(); it != popupExtras.end(); ++ it) { + gtk_widget_set_sensitive(*it, show); } - } - } -} -void SwatchesPanel::AddSelectedStroke(SPGroup* page) -{ - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->stroke.isSet()) { - if (it->style->stroke.isPaintserver()) { - SPPaintServer * server = it->style->getStrokePaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - if (_noLink.get_active()) { - Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); - clone->setAttribute( "osb:paint", "gradient", 0 ); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); + bounceTarget = item; + bouncePanel = swp; + popupItems.clear(); + if ( popupMenu ) { + gtk_container_foreach(GTK_CONTAINER(popupSub), removeit, popupSub); + bool processed = false; + GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); + if ( wdgt ) { + SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt); + if ( dtw && dtw->desktop ) { + // Pick up all gradients with vectors + const GSList *gradients = (dtw->desktop->doc())->getResourceList("gradient"); + gint index = 0; + for (const GSList *curr = gradients; curr; curr = curr->next) { + SPGradient* grad = SP_GRADIENT(curr->data); + if ( grad->hasStops() && !grad->isSwatch() ) { + //gl = g_slist_prepend(gl, curr->data); + processed = true; + GtkWidget *child = gtk_menu_item_new_with_label(grad->getId()); + gtk_menu_shell_append(GTK_MENU_SHELL(popupSub), child); + + popupItems.push_back(grad->getId()); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(SwatchesPanelHook::convertGradient), + GINT_TO_POINTER(index) ); + index++; } - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else if (grad->isSwatch()) { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); - } - SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); - - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); - if (repr->parent() != drepr) { - repr->parent()->removeChild(repr); - drepr->appendChild(repr); - } - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); } + + gtk_widget_show_all(popupSub); } - } else if (it->style->stroke.isColor()) { - Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); - grad->setAttribute( "osb:paint", "solid", 0 ); - addStop(grad, it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); - if (page) { - page->appendChild(grad); - } else { - _currentDocument->getDefs()->appendChild(grad); - } - SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); - Inkscape::GC::release(grad); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); } + gtk_widget_set_sensitive( popupSubHolder, processed ); + + gtk_menu_popup(GTK_MENU(popupMenu), NULL, NULL, NULL, NULL, event->button, event->time); + handled = TRUE; } } } -} -void SwatchesPanel::_addBIButtonClicked(GdkEventButton* event) -{ - if (popUpImportMenu) { - popUpImportMenu->popup(event->button, event->time); - } + return handled; } -void SwatchesPanel::NewGroupBI() -{ - if (_currentDocument) { - Inkscape::XML::Node * page = SwatchDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (SwatchDocument->getObjectById(id)); - - page->setAttribute("id", id); - - SwatchDocument->getDefs()->appendChild(page); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } -} -void SwatchesPanel::NewGroup() -{ - if (_currentDocument) { - Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (_currentDocument->getObjectById(id)); - - page->setAttribute("id", id); - - _currentDocument->getDefs()->appendChild(page); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("New Swatch Group")); +static char* trim( char* str ) { + char* ret = str; + while ( *str && (*str == ' ' || *str == '\t') ) { + str++; } -} - -void SwatchesPanel::SaveAs() -{ - if (_currentDocument) { - Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (_currentDocument->getObjectById(id)); - - page->setAttribute("id", id); - - std::vector toMove; - for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GRADIENT(it)) { - SPGradient* grad = SP_GRADIENT(it); - if (grad->isSwatch()) { - toMove.push_back(grad->getRepr()); - } - } - } - while (!toMove.empty()) { - Inkscape::XML::Node* repr = toMove.back(); - toMove.pop_back(); - repr->parent()->removeChild(repr); - page->appendChild(repr); - } - _currentDocument->getDefs()->appendChild(page); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Save Swatch Group")); + ret = str; + while ( *str ) { + str++; } -} - -void SwatchesPanel::Duplicate(SPGroup* oldpage) -{ - if (_currentDocument) { - Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (_currentDocument->getObjectById(id)); - - page->setAttribute("id", id); - if (oldpage->label()) page->setAttribute("inkscape:label", oldpage->label()); - - for (SPObject *it = oldpage->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GRADIENT(it)) { - SPGradient* grad = SP_GRADIENT(it); - if (grad->isSwatch()) { - Inkscape::XML::Node * copy = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); - page->appendChild(copy); - Inkscape::GC::release(copy); - } - } - } - _currentDocument->getDefs()->appendChild(page); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Duplicate Swatch Group")); + str--; + while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { + *str-- = 0; } + return ret; } -void SwatchesPanel::_lblClick(GdkEventButton* event, SPGroup* page) -{ - Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); - - Gtk::MenuItem* mi; - Glib::ustring us = Glib::ustring::compose("%1", page ? (page->label() ? page->label() : page->getId()) : _("[Base]")); - mi = Gtk::manage(new Gtk::MenuItem(page ? (page->label() ? page->label() : page->getId()) : _("[Base]"))); - Gtk::Label* namelbl = dynamic_cast(mi->get_child()); - if (namelbl) { - namelbl->set_markup(us); - } - mi->show(); - mi->set_sensitive(false); - menu->append(*mi); - - Gtk::SeparatorMenuItem* sep; - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Fill"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedFill), page)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Stroke"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedStroke), page)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - if (page) { - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Up"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveUp), page)); - mi->show(); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Down"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveDown), page)); - mi->show(); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Duplicate"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Duplicate), page)); - mi->show(); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Remove), page)); - mi->show(); - menu->append(*mi); - } else { - mi = Gtk::manage(new Gtk::MenuItem(_("Create New Group"))); - mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); - mi->show(); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Save As New Group"))); - mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::SaveAs)); - mi->show(); - menu->append(*mi); +static void skipWhitespace( char*& str ) { + while ( *str == ' ' || *str == '\t' ) { + str++; } - - menu->popup(event->button, event->time); } -void SwatchesPanel::_defsChanged() -{ - if (_storeDoc) { - _storeDoc->clear(); - } - - while (!docWatchers.empty()) { - Inkscape::XML::NodeObserver* w = docWatchers.back(); - docWatchers.pop_back(); - delete w; - } - - std::vector tableChildren = _insideTable.get_children(); - for (std::vector::iterator c = tableChildren.begin(); c != tableChildren.end(); ++c) { - _insideTable.remove(**c); +static bool parseNum( char*& str, int& val ) { + val = 0; + while ( '0' <= *str && *str <= '9' ) { + val = val * 10 + (*str - '0'); + str++; } - - if (_currentDocument) { - Gtk::EventBox* eb; - Gtk::Label* lbl; - if (_showlabels) { - eb = Gtk::manage(new Gtk::EventBox()); - eb->add_events(Gdk::BUTTON_PRESS_MASK); - eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), NULL)); - - lbl = Gtk::manage(new Gtk::Label(_("[Base]"))); - eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); - } - - ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); - item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); - item->set_tooltip_text(_("[None]")); - _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); - - unsigned int i = 1; - for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GRADIENT(it)) { - SPGradient* grad = SP_GRADIENT(it); - if (grad->hasStops()) { - - GradientWatcher* w = new GradientWatcher(this, grad); - docWatchers.push_back(w); - - if (grad->isSwatch()) { - - for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { - StopWatcher* sw = new StopWatcher(this, s); - docWatchers.push_back(sw); - } + bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); + return retval; +} - if (_storeDoc) { - Gtk::TreeModel::iterator iter = _storeDoc->append(); - Gtk::TreeModel::Row row = *iter; - row[_modelDoc->_colObject] = grad; - row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); - GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); - row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); - } - item = Gtk::manage(new ColorItem(grad, it->label() ? it->label() : it->getId(), _currentDesktop)); - item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->set_tooltip_text(it->label() ? it->label() : it->getId()); - if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); +void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ ) +{ + char block[1024]; + FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" ); + if ( f ) { + char* result = fgets( block, sizeof(block), f ); + if ( result ) { + if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { + bool inHeader = true; + bool hasErr = false; + + SwatchPage *onceMore = new SwatchPage(); + + do { + result = fgets( block, sizeof(block), f ); + block[sizeof(block) - 1] = 0; + if ( result ) { + if ( block[0] == '#' ) { + // ignore comment } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); - } - - i++; - } - } - } - } - - for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GROUP(it)) { - SwatchWatcher* w = new SwatchWatcher(this, it, false); - docWatchers.push_back(w); - - if (_showlabels) { - i += 20 - (i % 20); - eb = Gtk::manage(new Gtk::EventBox()); - eb->add_events(Gdk::BUTTON_PRESS_MASK); - eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), SP_GROUP(it))); - lbl = Gtk::manage(new Gtk::Label(it->label() ? it->label() : it->getId())); - eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); - } - - Gtk::TreeModel::iterator rowiter; - - if (_storeDoc) { - rowiter = _storeDoc->append(); - Gtk::TreeModel::Row row = *rowiter; - row[_modelDoc->_colObject] = it; - row[_modelDoc->_colLabel] = it->label() ? it->label() : it->getId(); - } - - for (SPObject *cit = it->firstChild(); cit != NULL; cit = cit->next) { - if (SP_IS_GRADIENT(cit)) { - SPGradient* grad = SP_GRADIENT(cit); - - if (grad->hasStops()) { - - GradientWatcher* w = new GradientWatcher(this, grad); - docWatchers.push_back(w); - - if (grad->isSwatch()) { - - for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { - StopWatcher* sw = new StopWatcher(this, s); - docWatchers.push_back(sw); - } - - if (_storeDoc && rowiter) { - Gtk::TreeModel::iterator iter = _storeDoc->append(rowiter->children()); - Gtk::TreeModel::Row row = *iter; - row[_modelDoc->_colObject] = grad; - row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); - GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); - row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); - - _editDoc.expand_to_path(_storeDoc->get_path(iter)); + char *ptr = block; + // very simple check for header versus entry + while ( *ptr == ' ' || *ptr == '\t' ) { + ptr++; + } + if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { + // blank line. skip it. + } else if ( '0' <= *ptr && *ptr <= '9' ) { + // should be an entry link + inHeader = false; + ptr = block; + Glib::ustring name(""); + skipWhitespace(ptr); + if ( *ptr ) { + int r = 0; + int g = 0; + int b = 0; + hasErr = parseNum(ptr, r); + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, g); + } + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, b); + } + if ( !hasErr && *ptr ) { + char* n = trim(ptr); + if (n != NULL) { + name = g_dpgettext2(NULL, "Palette", n); + } + } + if ( !hasErr ) { + // Add the entry now + Glib::ustring nameStr(name); + ColorItem* item = new ColorItem( r, g, b, nameStr ); + onceMore->_colors.push_back(item); + } + } else { + hasErr = true; } - - item = Gtk::manage(new ColorItem(grad, cit->label() ? cit->label() : cit->getId(), _currentDesktop)); - item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); - if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); + } else { + if ( !inHeader ) { + // Hmmm... probably bad. Not quite the format we want? + hasErr = true; } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); + char* sep = strchr(result, ':'); + if ( sep ) { + *sep = 0; + char* val = trim(sep + 1); + char* name = trim(result); + if ( *name ) { + if ( strcmp( "Name", name ) == 0 ) + { + onceMore->_name = val; + } + else if ( strcmp( "Columns", name ) == 0 ) + { + gchar* endPtr = 0; + guint64 numVal = g_ascii_strtoull( val, &endPtr, 10 ); + if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { + // overflow + } else if ( (numVal == 0) && (endPtr == val) ) { + // failed conversion + } else { + onceMore->_prefWidth = numVal; + } + } + } else { + // error + hasErr = true; + } + } else { + // error + hasErr = true; + } } - i++; } } } + } while ( result && !hasErr ); + if ( !hasErr ) { + if (user) + userSwatchPages.push_back(onceMore); + else + systemSwatchPages.push_back(onceMore); +#if ENABLE_MAGIC_COLORS + ColorItem::_wireMagicColors( onceMore ); +#endif // ENABLE_MAGIC_COLORS + } else { + delete onceMore; } } } - } - //_scroller.resize(1,1); - _insideTable.resize(1,1); - _scroller.show_all_children(); - _scroller.queue_draw(); - -} -Gtk::MenuItem* SwatchesPanel::_addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow) -{ - Gtk::MenuItem* mi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId(),1)); - Gtk::Menu* m = NULL; - - Gtk::TreeModel::Row* r; - if (_store) { - Gtk::TreeModel::iterator iter = parentRow ? _store->append(parentRow->children()) : _store->append(); - Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = group; - row[_model->_colLabel] = group->label() ? group->label() : group->getId(); - - if (SP_IS_GROUP(group->parent) && SP_GROUP(group->parent)->expanded()) { - _editBI.expand_to_path(_store->get_path(iter)); - } - r = &row; - } else { - r = NULL; - } - - bool hasswatches = false; - for (SPObject * obj = group->firstChild(); obj != NULL; obj = obj->next) - { - if (SP_IS_GROUP(obj)) { - if (!m) { - m = manage(new Gtk::Menu()); - m->show_all(); - mi->set_submenu(*m); - - Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(_("[All]"))); - basemi->show(); - Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); - if (namelbl) { - namelbl->set_markup(_("[All]")); - } - basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, true)); - m->append(*basemi); - - Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - m->append(*sep); - } - SwatchWatcher* w = new SwatchWatcher(this, obj, true); - rootWatchers.push_back(w); - m->append(*_addSwatchGroup(SP_GROUP(obj), r)); - } else if (SP_IS_GRADIENT(obj)) { - hasswatches = true; - } + fclose(f); } - if (!m) { - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); - } else if (hasswatches) { - Glib::ustring us = Glib::ustring::compose("%1", group->label() ? group->label() : group->getId()); - Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId())); - basemi->show(); - Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); - if (namelbl) { - namelbl->set_markup(us); - } - basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); - m->prepend(*basemi); - } - mi->show(); - return mi; } -void SwatchesPanel::_swatchesChanged() -{ - while (!rootWatchers.empty()) { - Inkscape::XML::NodeObserver* w = rootWatchers.back(); - rootWatchers.pop_back(); - delete w; - } +static bool +compare_swatch_names(SwatchPage const *a, SwatchPage const *b) { - std::vector menuChildren = popUpMenu->get_children(); - for (std::vector::iterator c = menuChildren.begin(); c != menuChildren.end(); ++c) { - popUpMenu->remove(**c); - } - - if (_store) { - _store->clear(); - } - - Gtk::MenuItem* mi; - - for (SPObject * obj = SwatchDocument->getDefs()->firstChild(); obj != NULL; obj = obj->next) - { - if (SP_IS_GROUP(obj)) { - SwatchWatcher* w = new SwatchWatcher(this, obj, true); - rootWatchers.push_back(w); - popUpMenu->append(*_addSwatchGroup(SP_GROUP(obj), NULL)); - - } - } - Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - popUpMenu->append(*sep); - - mi = manage(new Gtk::MenuItem(_("New Swatch Group..."),1)); - mi->signal_activate().connect(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); - mi->show(); - popUpMenu->append(*mi); - - mi = manage(new Gtk::MenuItem(_("Add Swatch File..."),1)); - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, false)); - mi->show(); - popUpMenu->append(*mi); - - mi = manage(new Gtk::MenuItem(_("Import Swatch File..."),1)); - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, true)); - mi->show(); - popUpMenu->append(*mi); + return g_utf8_collate(a->_name.c_str(), b->_name.c_str()) < 0; } -void SwatchesPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ) +static void loadEmUp() { - bool set = false; - - if ( iconName ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - btn.set_relief(Gtk::RELIEF_NONE); - set = true; - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !set && action && action->image ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - set = true; + static bool beenHere = false; + gboolean userPalete = true; + if ( !beenHere ) { + beenHere = true; + + std::list sources; + sources.push_back( profile_path("palettes") ); + sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) ); + sources.push_back( g_strdup(CREATE_PALETTESDIR) ); + + // Use this loop to iterate through a list of possible document locations. + while (!sources.empty()) { + gchar *dirname = sources.front(); + if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS ) + && Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) { + GError *err = 0; + GDir *directory = g_dir_open(dirname, 0, &err); + if (!directory) { + gchar *safeDir = Inkscape::IO::sanitizeString(dirname); + g_warning(_("Palettes directory (%s) is unavailable."), safeDir); + g_free(safeDir); + } else { + gchar *filename = 0; + while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) { + gchar* lower = g_ascii_strdown( filename, -1 ); +// if ( g_str_has_suffix(lower, ".gpl") ) { + if ( !g_str_has_suffix(lower, "~") ) { + gchar* full = g_build_filename(dirname, filename, NULL); + if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { + _loadPaletteFile(full, userPalete); + } + g_free(full); + } +// } + g_free(lower); + } + g_dir_close(directory); + } } + + // toss the dirname + g_free(dirname); + sources.pop_front(); + userPalete = false; } } - - btn.set_tooltip_text (fallback); - if ( !set ) { - btn.set_label( fallback ); - } -} + // Sort the list of swatches by name, grouped by user/system + userSwatchPages.sort(compare_swatch_names); + systemSwatchPages.sort(compare_swatch_names); -void SwatchesPanel::_addButtonClicked(GdkEventButton* event) { - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3 || event->button == 1) ) { - if (popUpMenu) { - popUpMenu->popup(event->button, event->time); - } - } } -void SwatchesPanel::NoLinkToggled() { - static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring nolink = Glib::ustring::compose("%1/nolink", _prefs_path); - prefs->setBool(nolink, _noLink.get_active()); -} -bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) -{ - static unsigned doubleclick = 0; - if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { - doubleclick = 1; - } - if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { - doubleclick = 0; - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _editBI.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnBI) { - // Double click on the Layer name, enable editing - _text_rendererBI->property_editable() = true; - _editBI.set_cursor (path, *_name_columnBI, true); - grab_focus(); - } - } - - return false; +SwatchesPanel& SwatchesPanel::getInstance() +{ + return *new SwatchesPanel(); } -bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) + +/** + * Constructor + */ +SwatchesPanel::SwatchesPanel(gchar const* prefsPath) : + Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, "", true), + _holder(0), + _clear(0), + _remove(0), + _currentIndex(0), + _currentDesktop(0), + _currentDocument(0) { - switch (Inkscape::UI::Tools::get_group0_keyval(event)) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_F2: { - Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); - if (iter && !_text_rendererBI->property_editable()) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj) { - Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); - // Edit the layer label - _text_rendererBI->property_editable() = true; - _editBI.set_cursor(*path, *_name_columnBI, true); - grab_focus(); - return true; + Gtk::RadioMenuItem* hotItem = 0; + _holder = new PreviewHolder(); + _clear = new ColorItem( ege::PaintDef::CLEAR ); + _remove = new ColorItem( ege::PaintDef::NONE ); + if (docPalettes.empty()) { + SwatchPage *docPalette = new SwatchPage(); + + docPalette->_name = "Auto"; + docPalettes[0] = docPalette; + } + + loadEmUp(); + if ( !systemSwatchPages.empty() ) { + SwatchPage* first = 0; + int index = 0; + Glib::ustring targetName; + if ( !_prefs_path.empty() ) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + targetName = prefs->getString(_prefs_path + "/palette"); + if (!targetName.empty()) { + if (targetName == "Auto") { + first = docPalettes[0]; + } else { + //index++; + std::vector pages = _getSwatchSets(); + for ( std::vector::iterator iter = pages.begin(); iter != pages.end(); ++iter ) { + if ( (*iter)->_name == targetName ) { + first = *iter; + break; + } + index++; + } } } } - case GDK_KEY_Delete: { - - Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); - if (iter) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj) { - obj->deleteObject(false); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } + + if ( !first ) { + first = docPalettes[0]; + _currentIndex = 0; + } else { + _currentIndex = index; + } + + _rebuild(); + + Gtk::RadioMenuItem::Group groupOne; + + int i = 0; + std::vector swatchSets = _getSwatchSets(); + for ( std::vector::iterator it = swatchSets.begin(); it != swatchSets.end(); ++it) { + SwatchPage* curr = *it; + Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); + if ( curr == first ) { + hotItem = single; } - return true; + _regItem( single, 3, i ); + + i++; } - break; } - return false; -} -void SwatchesPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) -{ - Gtk::TreeModel::iterator iter = _editBI.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; + if (Glib::ustring(prefsPath) == "/dialogs/swatches") { + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + get_preferred_size(sreq_natural, sreq); +#else + sreq = size_request(); +#endif + int minHeight = 60; + if (sreq.height < minHeight) { + set_size_request(70, minHeight); + } + } - _renameObject(row, new_text); - _text_rendererBI->property_editable() = false; -} + _getContents()->pack_start(*_holder, Gtk::PACK_EXPAND_WIDGET); + _setTargetFillable(_holder); -void SwatchesPanel::_handleEditingCancelled() -{ - _text_rendererBI->property_editable() = false; -} + show_all_children(); -void SwatchesPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) -{ - if ( row && SwatchDocument) { - SPObject* obj = row[_model->_colObject]; - if ( obj ) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } - } + restorePanelPrefs(); + if ( hotItem ) { + hotItem->set_active(); } } -void SwatchesPanel::_setCollapsed(SPGroup * group) +SwatchesPanel::~SwatchesPanel() { - group->setExpanded(false); - group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - for (SPObject *iter = group->children; iter != NULL; iter = iter->next) - { - if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + _trackDocument( this, 0 ); + + _documentConnection.disconnect(); + _selChanged.disconnect(); + + if ( _clear ) { + delete _clear; + } + if ( _remove ) { + delete _remove; + } + if ( _holder ) { + delete _holder; } } -void SwatchesPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +void SwatchesPanel::setOrientation(SPAnchorType how) { - Gtk::TreeModel::Row row = *iter; + // Must call the parent class or bad things might happen + Inkscape::UI::Widget::Panel::setOrientation( how ); - SPObject* obj = row[_model->_colObject]; - if (obj && SP_IS_GROUP(obj)) + if ( _holder ) { - if (isexpanded) - { - SP_GROUP(obj)->setExpanded(isexpanded); - obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - } - else - { - _setCollapsed(SP_GROUP(obj)); - } + _holder->setOrientation(SP_ANCHOR_SOUTH); } - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } -void SwatchesPanel::_deleteButtonClicked() +void SwatchesPanel::setDesktop( SPDesktop* desktop ) { - Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); - if (iter) { - Gtk::TreeModel::Row row = *iter; - SPObject* obj = row[_model->_colObject]; - if (obj) { - obj->deleteObject(false); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + if ( desktop != _currentDesktop ) { + if ( _currentDesktop ) { + _documentConnection.disconnect(); + _selChanged.disconnect(); } - } -} -bool SwatchesPanel::_handleButtonEventDoc(GdkEventButton* event) -{ - static unsigned doubleclick = 0; - - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { - // TODO - fix to a better is-popup function - Gtk::TreeModel::Path path; - int x = static_cast(event->x); - int y = static_cast(event->y); - if ( _editDoc.get_path_at_pos( x, y, path ) ) { - Gtk::TreeModel::Children::iterator iter = _editDoc.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_modelDoc->_colObject]; - if (SP_IS_GRADIENT(obj)) { - _swatchClicked(event, SP_GRADIENT(obj)); - } else if (SP_IS_GROUP(obj)) { - _lblClick(event, SP_GROUP(obj)); - } else { - _lblClick(event, NULL); - } - } else { - _lblClick(event, NULL); - } - } - - if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { - doubleclick = 1; - } + _currentDesktop = desktop; - if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { - doubleclick = 0; - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _editDoc.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnDoc) { - // Double click on the Layer name, enable editing - _text_rendererDoc->property_editable() = true; - _editDoc.set_cursor (path, *_name_columnDoc, true); - grab_focus(); + if ( desktop ) { + _currentDesktop->selection->connectChanged( + sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + + _currentDesktop->selection->connectModified( + sigc::hide(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection)))); + + _currentDesktop->connectToolSubselectionChanged( + sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + + sigc::bound_mem_functor1 first = sigc::mem_fun(*this, &SwatchesPanel::_setDocument); + sigc::slot base2 = first; + sigc::slot slot2 = sigc::hide<0>( base2 ); + _documentConnection = desktop->connectDocumentReplaced( slot2 ); + + _setDocument( desktop->doc() ); + } else { + _setDocument(0); } } - - return false; } -void SwatchesPanel::_deleteButtonClickedDoc() + +class DocTrack { - Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); - if (iter) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_modelDoc->_colObject]; - if (SP_IS_GRADIENT(obj)) { - RemoveSwatch(SP_GRADIENT(obj)); - } else if (SP_IS_GROUP(obj)) { - Remove(SP_GROUP(obj)); +public: + DocTrack(SPDocument *doc, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : + doc(doc->doRef()), + updatePending(false), + lastGradientUpdate(0.0), + gradientRsrcChanged(gradientRsrcChanged), + defsChanged(defsChanged), + defsModified(defsModified) + { + if ( !timer ) { + timer = new Glib::Timer(); + refreshTimer = Glib::signal_timeout().connect( sigc::ptr_fun(handleTimerCB), 33 ); } + timerRefCount++; } -} -bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) -{ - switch (Inkscape::UI::Tools::get_group0_keyval(event)) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_F2: { - Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); - if (iter && !_text_rendererDoc->property_editable()) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_modelDoc->_colObject]; - if (obj) { - Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); - // Edit the layer label - _text_rendererDoc->property_editable() = true; - _editDoc.set_cursor(*path, *_name_columnDoc, true); - grab_focus(); - return true; - } + ~DocTrack() + { + timerRefCount--; + if ( timerRefCount <= 0 ) { + refreshTimer.disconnect(); + timerRefCount = 0; + if ( timer ) { + timer->stop(); + delete timer; + timer = 0; } } - case GDK_KEY_Delete: { - - _deleteButtonClickedDoc(); - return true; + if (doc) { + gradientRsrcChanged.disconnect(); + defsChanged.disconnect(); + defsModified.disconnect(); + doc->doUnref(); + doc = NULL; } - break; } - return false; -} -void SwatchesPanel::_renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name) -{ - if ( row && SwatchDocument) { - SPObject* obj = row[_modelDoc->_colObject]; - if ( obj ) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - } - } - } -} + static bool handleTimerCB(); -void SwatchesPanel::_handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text) -{ - Gtk::TreeModel::iterator iter = _editDoc.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; + /** + * Checks if update should be queued or executed immediately. + * + * @return true if the update was queued and should not be immediately executed. + */ + static bool queueUpdateIfNeeded(SPDocument *doc); - _renameObjectDoc(row, new_text); - _text_rendererDoc->property_editable() = false; -} + static Glib::Timer *timer; + static int timerRefCount; + static sigc::connection refreshTimer; -void SwatchesPanel::_handleEditingCancelledDoc() -{ - _text_rendererDoc->property_editable() = false; -} + SPDocument *doc; + bool updatePending; + double lastGradientUpdate; + sigc::connection gradientRsrcChanged; + sigc::connection defsChanged; + sigc::connection defsModified; -/* - * Drap and drop within the tree - * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer - */ -bool SwatchesPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +private: + DocTrack(DocTrack const &); // no copy + DocTrack &operator=(DocTrack const &); // no assign +}; + +Glib::Timer *DocTrack::timer = 0; +int DocTrack::timerRefCount = 0; +sigc::connection DocTrack::refreshTimer; + +static const double DOC_UPDATE_THREASHOLD = 0.090; + +bool DocTrack::handleTimerCB() { - int cell_x = 0, cell_y = 0; - Gtk::TreeModel::Path target_path; - Gtk::TreeView::Column *target_column; - - bool _dnd_top = false; - _dnd_into = false; - _dnd_target = SwatchDocument->getDefs()->lastChild(); - Gtk::TreeModel::iterator itersel = _editBI.get_selection()->get_selected(); - if (!itersel) { - return true; - } - Gtk::TreeModel::Row rowsel = *itersel; - _dnd_source = rowsel[_model->_colObject]; + double now = timer->elapsed(); - if (!_dnd_source) { - return true; - } - - if (_editBI.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { - // Are we before, inside or after the drop layer - Gdk::Rectangle rect; - _editBI.get_background_area (target_path, *target_column, rect); - int cell_height = rect.get_height(); - _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); - if (cell_y < (int)(cell_height * 1/3)) { - Gtk::TreeModel::Path next_path = target_path; - if (next_path.prev()) { - target_path = next_path; - } else { - // Dragging to the "end" - Gtk::TreeModel::Path up_path = target_path; - up_path.up(); - if (_store->iter_is_valid(_store->get_iter(up_path))) { - // Drop into parent - target_path = up_path; - _dnd_into = true; - } else { - _dnd_top = true; - // Drop into the top level - _dnd_target = NULL; - } - } - } - if (!_dnd_top) { - Gtk::TreeModel::iterator iter = _store->get_iter(target_path); - if (_store->iter_is_valid(iter)) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_model->_colObject]; - if (obj) { - _dnd_target = obj; - } - } + std::vector needCallback; + for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { + DocTrack *track = *it; + if ( track->updatePending && ( (now - track->lastGradientUpdate) >= DOC_UPDATE_THREASHOLD) ) { + needCallback.push_back(track); } } - - if (_dnd_source != _dnd_target) { - - Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; - Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); - - if (target_ref != our_ref) { - if (!target_ref) { - target_ref = SwatchDocument->getDefs()->getRepr(); - if (target_ref != our_ref->parent()) { - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else { - our_ref->parent()->changeOrder(our_ref, NULL); - } - } else if (_dnd_into) { - // Move this inside of the target at the end - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else if (target_ref->parent() != our_ref->parent()) { - // Change in parent, need to remove and add - our_ref->parent()->removeChild(our_ref); - target_ref->parent()->addChild(our_ref, target_ref); - } else { - // Same parent, just move - our_ref->parent()->changeOrder(our_ref, target_ref); - } + + for (std::vector::iterator it = needCallback.begin(); it != needCallback.end(); ++it) { + DocTrack *track = *it; + if ( std::find(docTrackings.begin(), docTrackings.end(), track) != docTrackings.end() ) { // Just in case one gets deleted while we are looping + // Note: calling handleDefsModified will call queueUpdateIfNeeded and thus update the time and flag. + SwatchesPanel::handleDefsModified(track->doc); } - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } return true; } -/* - * Drap and drop within the tree - * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer - */ -bool SwatchesPanel::_handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time) +bool DocTrack::queueUpdateIfNeeded( SPDocument *doc ) { - int cell_x = 0, cell_y = 0; - Gtk::TreeModel::Path target_path; - Gtk::TreeView::Column *target_column; - - bool _dnd_top = false; - _dnd_into = false; - _dnd_target = _currentDocument->getDefs()->lastChild(); - Gtk::TreeModel::iterator itersel = _editDoc.get_selection()->get_selected(); - if (!itersel) { - return true; - } - Gtk::TreeModel::Row rowsel = *itersel; - _dnd_source = rowsel[_modelDoc->_colObject]; - - if (!_dnd_source) { - return true; - } - - if (_editDoc.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { - // Are we before, inside or after the drop layer - Gdk::Rectangle rect; - _editDoc.get_background_area (target_path, *target_column, rect); - int cell_height = rect.get_height(); - _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); - if (cell_y < (int)(cell_height * 1/3)) { - Gtk::TreeModel::Path next_path = target_path; - if (next_path.prev()) { - target_path = next_path; + bool deferProcessing = false; + for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { + DocTrack *track = *it; + if ( track->doc == doc ) { + double now = timer->elapsed(); + double elapsed = now - track->lastGradientUpdate; + + if ( elapsed < DOC_UPDATE_THREASHOLD ) { + deferProcessing = true; + track->updatePending = true; } else { - // Dragging to the "end" - Gtk::TreeModel::Path up_path = target_path; - up_path.up(); - if (_storeDoc->iter_is_valid(_storeDoc->get_iter(up_path))) { - // Drop into parent - target_path = up_path; - _dnd_into = true; - } else { - _dnd_top = true; - // Drop into the top level - _dnd_target = NULL; - } + track->lastGradientUpdate = now; + track->updatePending = false; } + + break; } - if (!_dnd_top) { - Gtk::TreeModel::iterator iter = _storeDoc->get_iter(target_path); - if (_storeDoc->iter_is_valid(iter)) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_modelDoc->_colObject]; - if (obj) { - _dnd_target = obj; - if (SP_IS_GRADIENT(obj)) { - _dnd_into = false; - if (SP_IS_GROUP(_dnd_source)) { - _dnd_target = obj->parent; - } - } else if (SP_IS_GROUP(_dnd_source)) { - _dnd_into = false; + } + return deferProcessing; +} + +void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) +{ + SPDocument *oldDoc = NULL; + if (docPerPanel.find(panel) != docPerPanel.end()) { + oldDoc = docPerPanel[panel]; + if (!oldDoc) { + docPerPanel.erase(panel); // Should not be needed, but clean up just in case. + } + } + if (oldDoc != document) { + if (oldDoc) { + docPerPanel[panel] = NULL; + bool found = false; + for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { + found = (it->second == document); + } + if (!found) { + for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ + if ((*it)->doc == oldDoc) { + delete *it; + docTrackings.erase(it); + break; } } } } - } - - if (_dnd_source != _dnd_target) { - - Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; - Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); - - if (target_ref != our_ref) { - if (!target_ref) { - target_ref = _currentDocument->getDefs()->getRepr(); - if (target_ref != our_ref->parent()) { - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else { - our_ref->parent()->changeOrder(our_ref, NULL); + + if (document) { + bool found = false; + for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { + found = (it->second == document); + } + docPerPanel[panel] = document; + if (!found) { + sigc::connection conn1 = document->connectResourcesChanged( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) ); + sigc::connection conn2 = document->getDefs()->connectRelease( sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document)) ); + sigc::connection conn3 = document->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document))) ); + + DocTrack *dt = new DocTrack(document, conn1, conn2, conn3); + docTrackings.push_back(dt); + + if (docPalettes.find(document) == docPalettes.end()) { + SwatchPage *docPalette = new SwatchPage(); + docPalette->_name = "Auto"; + docPalettes[document] = docPalette; } - } else if (_dnd_into) { - // Move this inside of the target at the end - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else if (target_ref->parent() != our_ref->parent()) { - // Change in parent, need to remove and add - our_ref->parent()->removeChild(our_ref); - target_ref->parent()->addChild(our_ref, target_ref); - } else { - // Same parent, just move - our_ref->parent()->changeOrder(our_ref, target_ref); } } - DocumentUndo::done( _currentDocument , SP_VERB_DIALOG_SWATCHES, - _("Moved Swatches")); } - - return true; } +void SwatchesPanel::_setDocument( SPDocument *document ) +{ + if ( document != _currentDocument ) { + _trackDocument(this, document); + _currentDocument = document; + handleGradientsChange( document ); + } +} -/** - * Constructor - */ -SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : - Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, ""), - _scroller(), - _insideTable(1, 1), - _insideV(), - _insideH(), - _buttonsRow(), - _outsideV(), - _noLink(_("Don't Link")), - _showlabels(showLabels), - _store(0), - _scrollerBI(), - _editBI(), - _buttonsRowBI(), - _editBIV(), - _storeDoc(0), - _scrollerDoc(), - _editDoc(), - _buttonsRowDoc(), - _editDocV(), - _notebook(), - rootWatcher(0), - docWatcher(0), - _currentDesktop(0), - _currentDocument(0) +static void recalcSwatchContents(SPDocument* doc, + boost::ptr_vector &tmpColors, + std::map &previewMappings, + std::map &gradMappings) { - _insideH.pack_start(_insideTable, Gtk::PACK_SHRINK); - if (_showlabels) { - _insideV.pack_start(_insideH, Gtk::PACK_SHRINK); - _scroller.add(_insideV); - } else { - _scroller.property_height_request() = 20; - _scroller.add(_insideH); + std::vector newList; + + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( grad->isSwatch() ) { + newList.push_back(SP_GRADIENT(item->data)); + } } - - popUpMenu = manage( new Gtk::Menu() ); - popUpMenu->show_all_children(); - - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Add Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked) ); - _buttonsRow.pack_start(*btn, Gtk::PACK_SHRINK); - -// btn = manage( new Gtk::Button() ); -// _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_DISCONNECT, C_("Unlink", "New") ); -// _buttonsRow.pack_end(*btn, Gtk::PACK_SHRINK); - - static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring nolink = Glib::ustring::compose("%1/nolink", prefsPath); - _noLink.set_tooltip_text(_("Don't link swatches")); - _noLink.set_active(prefs->getBool(nolink, false)); - _noLink.signal_toggled().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NoLinkToggled)); - _buttonsRow.pack_end(_noLink, Gtk::PACK_SHRINK); - - _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scroller.set_shadow_type(Gtk::SHADOW_NONE); - - if (_showlabels) { - _outsideV.pack_end(_buttonsRow, Gtk::PACK_SHRINK); - _outsideV.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); - - _notebook.append_page(_outsideV, "Use"); - + + if ( !newList.empty() ) { + std::reverse(newList.begin(), newList.end()); + for ( std::vector::iterator it = newList.begin(); it != newList.end(); ++it ) { - ModelColumnsDoc *zoop = new ModelColumnsDoc(); - _modelDoc = zoop; + SPGradient* grad = *it; - _storeDoc = Gtk::TreeStore::create( *zoop ); + cairo_surface_t *preview = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + PREVIEW_PIXBUF_WIDTH, VBLOCK); + cairo_t *ct = cairo_create(preview); - _editDoc.set_model( _storeDoc ); - _editDoc.set_headers_visible(false); - _editDoc.set_reorderable(true); - _editDoc.enable_model_drag_dest (Gdk::ACTION_MOVE); + Glib::ustring name( grad->getId() ); + ColorItem* item = new ColorItem( 0, 0, 0, name ); - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked)); - _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); + cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(grad, PREVIEW_PIXBUF_WIDTH); + cairo_set_source(ct, check); + cairo_paint(ct); + cairo_set_source(ct, gradient); + cairo_paint(ct); - btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClickedDoc))); - _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + cairo_destroy(ct); + cairo_pattern_destroy(gradient); + cairo_pattern_destroy(check); - _pixbuf_rendererDoc = manage(new Gtk::CellRendererPixbuf()); - int pixbufColNum = _editDoc.append_column("Pixbuf", *_pixbuf_rendererDoc) - 1; - _pixbuf_columnDoc = _editDoc.get_column(pixbufColNum); - _pixbuf_columnDoc->add_attribute(_pixbuf_rendererDoc->property_pixbuf(), _modelDoc->_colPixbuf); - - _text_rendererDoc = manage(new Gtk::CellRendererText()); - int nameColNum = _editDoc.append_column("Name", *_text_rendererDoc) - 1; - _name_columnDoc = _editDoc.get_column(nameColNum); - _name_columnDoc->add_attribute(_text_rendererDoc->property_text(), _modelDoc->_colLabel); + cairo_pattern_t *prevpat = cairo_pattern_create_for_surface(preview); + cairo_surface_destroy(preview); - _text_rendererDoc->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditedDoc) ); - _text_rendererDoc->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelledDoc) ); + previewMappings[item] = prevpat; + + tmpColors.push_back(item); + gradMappings[item] = grad; + } + } +} - _editDoc.set_expander_column( *_editDoc.get_column(nameColNum) ); +void SwatchesPanel::handleGradientsChange(SPDocument *document) +{ + SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; + if (docPalette) { + boost::ptr_vector tmpColors; + std::map tmpPrevs; + std::map tmpGrads; + recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - _editDoc.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); - _editDoc.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); - _editDoc.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEventDoc), false ); + for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { + it->first->setPattern(it->second); + cairo_pattern_destroy(it->second); + } - _editDoc.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDropDoc), false); + for (std::map::iterator it = tmpGrads.begin(); it != tmpGrads.end(); ++it) { + it->first->setGradient(it->second); + } - _scrollerDoc.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scrollerDoc.set_shadow_type(Gtk::SHADOW_IN); - _scrollerDoc.add(_editDoc); + docPalette->_colors.swap(tmpColors); - _editDocV.pack_start(_scrollerDoc, Gtk::PACK_EXPAND_WIDGET); - _editDocV.pack_end(_buttonsRowDoc, Gtk::PACK_SHRINK); + // Figure out which SwatchesPanel instances are affected and update them. - _notebook.append_page(_editDocV, "Edit"); - } - - { - popUpImportMenu = Gtk::manage(new Gtk::Menu()); - - Gtk::MenuItem* mi = Gtk::manage(new Gtk::MenuItem(_("New Swatch Group..."))); - mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroupBI)); - mi->show(); - popUpImportMenu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Import Swatch File..."))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), false, true)); - mi->show(); - popUpImportMenu->append(*mi); - - ModelColumns *zoop = new ModelColumns(); - _model = zoop; - - _store = Gtk::TreeStore::create( *zoop ); - - _editBI.set_model( _store ); - _editBI.set_headers_visible(false); - _editBI.set_reorderable(true); - _editBI.enable_model_drag_dest (Gdk::ACTION_MOVE); - - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); - btn->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::_addBIButtonClicked)); - _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); - - btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClicked))); - _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); - - _text_rendererBI = manage(new Gtk::CellRendererText()); - int nameColNum = _editBI.append_column("Name", *_text_rendererBI) - 1; - _name_columnBI = _editBI.get_column(nameColNum); - _name_columnBI->add_attribute(_text_rendererBI->property_text(), _model->_colLabel); - - _text_rendererBI->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEdited) ); - _text_rendererBI->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelled) ); - - _editBI.set_expander_column( *_editBI.get_column(nameColNum) ); - - _editBI.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); - _editBI.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); - _editBI.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEvent), false ); - - _editBI.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDrop), false); - _editBI.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), false)); - _editBI.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), true)); - - _scrollerBI.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scrollerBI.set_shadow_type(Gtk::SHADOW_IN); - _scrollerBI.add(_editBI); - - _editBIV.pack_start(_scrollerBI, Gtk::PACK_EXPAND_WIDGET); - _editBIV.pack_end(_buttonsRowBI, Gtk::PACK_SHRINK); - - _notebook.append_page(_editBIV, "Edit Built-In"); + for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { + if (it->second == document) { + SwatchesPanel* swp = it->first; + std::vector pages = swp->_getSwatchSets(); + SwatchPage* curr = pages[swp->_currentIndex]; + if (curr == docPalette) { + swp->_rebuild(); + } + } } - - _getContents()->pack_end(_notebook, Gtk::PACK_EXPAND_WIDGET); - } else { - //_outsideV.pack_end(_scroller, Gtk::PACK_SHRINK); - _buttonsRow.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); - //_getContents()->pack_end(_outsideV, Gtk::PACK_SHRINK); - _getContents()->pack_end(_buttonsRow, Gtk::PACK_SHRINK); } - - loadPalletFile(); - - rootWatcher = new SwatchWatcher(this, SwatchDocument->getDefs(), true); - SwatchDocument->getDefs()->getRepr()->addObserver(*rootWatcher); - _swatchesChanged(); - _insideTable.resize(1,1); } -SwatchesPanel::~SwatchesPanel() +void SwatchesPanel::handleDefsModified(SPDocument *document) { - if (rootWatcher) { - rootWatcher->_repr->removeObserver(*rootWatcher); - delete rootWatcher; + SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; + if (docPalette && !DocTrack::queueUpdateIfNeeded(document) ) { + boost::ptr_vector tmpColors; + std::map tmpPrevs; + std::map tmpGrads; + recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); + + if ( tmpColors.size() != docPalette->_colors.size() ) { + handleGradientsChange(document); + } else { + int cap = std::min(docPalette->_colors.size(), tmpColors.size()); + for (int i = 0; i < cap; i++) { + ColorItem *newColor = &tmpColors[i]; + ColorItem *oldColor = &docPalette->_colors[i]; + if ( (newColor->def.getType() != oldColor->def.getType()) || + (newColor->def.getR() != oldColor->def.getR()) || + (newColor->def.getG() != oldColor->def.getG()) || + (newColor->def.getB() != oldColor->def.getB()) ) { + oldColor->def.setRGB(newColor->def.getR(), newColor->def.getG(), newColor->def.getB()); + } + if (tmpGrads.find(newColor) != tmpGrads.end()) { + oldColor->setGradient(tmpGrads[newColor]); + } + if ( tmpPrevs.find(newColor) != tmpPrevs.end() ) { + oldColor->setPattern(tmpPrevs[newColor]); + } + } + } + + for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { + cairo_pattern_destroy(it->second); + } } - - if (docWatcher) { - docWatcher->_repr->removeObserver(*docWatcher); - delete docWatcher; +} + + +std::vector SwatchesPanel::_getSwatchSets() const +{ + std::vector tmp; + if (docPalettes.find(_currentDocument) != docPalettes.end()) { + tmp.push_back(docPalettes[_currentDocument]); } - _documentConnection.disconnect(); - _selChanged.disconnect(); + tmp.insert(tmp.end(), userSwatchPages.begin(), userSwatchPages.end()); + tmp.insert(tmp.end(), systemSwatchPages.begin(), systemSwatchPages.end()); + + return tmp; } -void SwatchesPanel::setDesktop( SPDesktop* desktop ) +void SwatchesPanel::_updateFromSelection() { - Inkscape::UI::Widget::Panel::setDesktop(desktop); - if ( desktop != _currentDesktop ) { - if ( _currentDesktop ) { - _documentConnection.disconnect(); - _selChanged.disconnect(); + SwatchPage *docPalette = (docPalettes.find(_currentDocument) != docPalettes.end()) ? docPalettes[_currentDocument] : 0; + if ( docPalette ) { + Glib::ustring fillId; + Glib::ustring strokeId; + + SPStyle *tmpStyle = sp_style_new( sp_desktop_document(_currentDesktop) ); + int result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_FILL ); + switch (result) { + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: + case QUERY_STYLE_MULTIPLE_SAME: + { + if (tmpStyle->fill.set && tmpStyle->fill.isPaintserver()) { + SPPaintServer* server = tmpStyle->getFillPaintServer(); + if ( SP_IS_GRADIENT(server) ) { + SPGradient* target = 0; + SPGradient* grad = SP_GRADIENT(server); + + if ( grad->isSwatch() ) { + target = grad; + } else if ( grad->ref ) { + SPGradient *tmp = grad->ref->getObject(); + if ( tmp && tmp->isSwatch() ) { + target = tmp; + } + } + if ( target ) { + //XML Tree being used directly here while it shouldn't be + gchar const* id = target->getRepr()->attribute("id"); + if ( id ) { + fillId = id; + } + } + } + } + break; + } } - _currentDesktop = desktop; + result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); + switch (result) { + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: + case QUERY_STYLE_MULTIPLE_SAME: + { + if (tmpStyle->stroke.set && tmpStyle->stroke.isPaintserver()) { + SPPaintServer* server = tmpStyle->getStrokePaintServer(); + if ( SP_IS_GRADIENT(server) ) { + SPGradient* target = 0; + SPGradient* grad = SP_GRADIENT(server); + if ( grad->isSwatch() ) { + target = grad; + } else if ( grad->ref ) { + SPGradient *tmp = grad->ref->getObject(); + if ( tmp && tmp->isSwatch() ) { + target = tmp; + } + } + if ( target ) { + //XML Tree being used directly here while it shouldn't be + gchar const* id = target->getRepr()->attribute("id"); + if ( id ) { + strokeId = id; + } + } + } + } + break; + } + } + sp_style_unref(tmpStyle); - if ( desktop ) { - //_currentDesktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + for ( boost::ptr_vector::iterator it = docPalette->_colors.begin(); it != docPalette->_colors.end(); ++it ) { + ColorItem* item = &*it; + bool isFill = (fillId == item->def.descr); + bool isStroke = (strokeId == item->def.descr); + item->setState( isFill, isStroke ); + } + } +} - _documentConnection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &SwatchesPanel::_setDocument)); +void SwatchesPanel::_handleAction( int setId, int itemId ) +{ + switch( setId ) { + case 3: + { + std::vector pages = _getSwatchSets(); + if ( itemId >= 0 && itemId < static_cast(pages.size()) ) { + _currentIndex = itemId; - _setDocument( desktop, desktop->doc() ); - } else { - _setDocument(0, 0); + if ( !_prefs_path.empty() ) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name); + } + + _rebuild(); + } } + break; } } -void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) +void SwatchesPanel::_rebuild() { - if ( document != _currentDocument ) { - if (docWatcher) { - docWatcher->_repr->removeObserver(*docWatcher); - delete docWatcher; - docWatcher = NULL; - } - _currentDocument = document; - - if (_currentDocument) { - docWatcher = new SwatchWatcher(this, _currentDocument->getDefs(), false); - _currentDocument->getDefs()->getRepr()->addObserver(*docWatcher); - } - _defsChanged(); + std::vector pages = _getSwatchSets(); + SwatchPage* curr = pages[_currentIndex]; + _holder->clear(); + + if ( curr->_prefWidth > 0 ) { + _holder->setColumnPref( curr->_prefWidth ); } + _holder->freezeUpdates(); + // TODO restore once 'clear' works _holder->addPreview(_clear); + _holder->addPreview(_remove); + for ( boost::ptr_vector::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) { + _holder->addPreview(&*it); + } + _holder->thawUpdates(); } } //namespace Dialogs } //namespace UI } //namespace Inkscape -//really lazy! -void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) -{ - - bool intercepted = false; - - if (gradient->isSolid()) { - ColorRGBA color(gradient->getFirstStop()->getEffectiveColor().toRGBA32(gradient->getFirstStop()->opacity)); - guint32 rgba = SP_RGBA32_F_COMPOSE(color[0], color[1], color[2], color[3]); - gchar b[64]; - sp_svg_write_color(b, sizeof(b), rgba); - SPCSSAttr *css = sp_repr_css_attr_new(); - if (fill) { - sp_repr_css_set_property(css, "fill", b); - Inkscape::CSSOStringStream osalpha; - osalpha << color[3]; - sp_repr_css_set_property(css, "fill-opacity", osalpha.str().c_str()); - } else { - sp_repr_css_set_property(css, "stroke", b); - Inkscape::CSSOStringStream osalpha; - osalpha << color[3]; - sp_repr_css_set_property(css, "stroke-opacity", osalpha.str().c_str()); - } - intercepted = desktop->_set_style_signal.emit(css); - } - - if (!intercepted) { - for (const GSList *it = desktop->selection->itemList(); it != NULL; it = it->next) { - sp_item_set_gradient(SP_ITEM(it->data), gradient, SP_IS_RADIALGRADIENT(gradient) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, !fill ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); - } - } -} /* Local Variables: diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h index cb8f87962..ca4c1687d 100644 --- a/src/ui/dialog/swatches.h +++ b/src/ui/dialog/swatches.h @@ -12,161 +12,64 @@ #include "ui/widget/panel.h" #include "enums.h" -#include "sp-object.h" -#include "sp-item-group.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sp-gradient.h" -#include "xml/node-observer.h" namespace Inkscape { namespace UI { +class PreviewHolder; + namespace Dialogs { +class ColorItem; +class SwatchPage; +class DocTrack; + /** * A panel that displays paint swatches. */ class SwatchesPanel : public Inkscape::UI::Widget::Panel { public: - SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches", bool showLabels = true); + SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches"); virtual ~SwatchesPanel(); - + static SwatchesPanel& getInstance(); + virtual void setOrientation(SPAnchorType how); + virtual void setDesktop( SPDesktop* desktop ); virtual SPDesktop* getDesktop() {return _currentDesktop;} + virtual int getSelectedIndex() {return _currentIndex;} // temporary + protected: + static void handleGradientsChange(SPDocument *document); + + virtual void _updateFromSelection(); + virtual void _handleAction( int setId, int itemId ); + virtual void _setDocument( SPDocument *document ); + virtual void _rebuild(); - virtual void _setDocument( SPDesktop* desktop, SPDocument *document ); + virtual std::vector _getSwatchSets() const; private: - class ModelColumns; - class ModelColumnsDoc; - - class StopWatcher; - class GradientWatcher; - class SwatchWatcher; - SwatchesPanel(SwatchesPanel const &); // no copy SwatchesPanel &operator=(SwatchesPanel const &); // no assign - - void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ); - - void _setSelectionSwatch(SPGradient* swatchItem, bool isStroke); - - void NoLinkToggled(); - void NewGroup(); - void NewGroupBI(); - void _addBIButtonClicked(GdkEventButton* event); - void Duplicate(SPGroup* page); - void SaveAs(); - void AddSelectedFill(SPGroup* page); - void AddSelectedStroke(SPGroup* page); - void MoveUp(SPGroup* page); - void MoveDown(SPGroup* page); - void Remove(SPGroup* page); - - void SetSelectedFill(SPGradient* swatch); - void SetSelectedStroke(SPGradient* swatch); - void MoveSwatchUp(SPGradient* swatch); - void MoveSwatchDown(SPGradient* swatch); - void RemoveSwatch(SPGradient* swatch); - - void _lblClick(GdkEventButton* event, SPGroup* page); - void _addSwatchButtonClicked(SPGroup* swatch, bool recurse); - void _defsChanged(); - void _importButtonClicked(bool addToDoc, bool addToBI); - void _deleteButtonClicked(); - void _addButtonClicked(GdkEventButton* event); - void _swatchClicked(GdkEventButton* event, SPGradient* swatchItem); - - Gtk::MenuItem* _addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow); - void _swatchesChanged(); - - bool _handleButtonEvent(GdkEventButton *event); - bool _handleKeyEvent(GdkEventKey *event); - - void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); - void _handleEditingCancelled(); - void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); - - void _setCollapsed(SPGroup * group); - void _setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded); - - void _deleteButtonClickedDoc(); - bool _handleButtonEventDoc(GdkEventButton* event); - bool _handleKeyEventDoc(GdkEventKey *event); - - void _handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text); - void _handleEditingCancelledDoc(); - void _renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name); - - bool _handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time); - bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); - - Gtk::Menu *popUpMenu; - Gtk::Menu *popUpImportMenu; - - Gtk::ScrolledWindow _scroller; - Gtk::Table _insideTable; - Gtk::VBox _insideV; - Gtk::HBox _insideH; - Gtk::HBox _buttonsRow; - Gtk::VBox _outsideV; - Gtk::CheckButton _noLink; - bool _showlabels; - - SwatchesPanel::ModelColumns* _model; - Glib::RefPtr _store; - - Gtk::CellRendererText *_text_rendererBI; - Gtk::TreeView::Column *_name_columnBI; - Gtk::ScrolledWindow _scrollerBI; - Gtk::TreeView _editBI; - Gtk::HBox _buttonsRowBI; - Gtk::VBox _editBIV; - - SwatchesPanel::ModelColumnsDoc* _modelDoc; - Glib::RefPtr _storeDoc; - - Gtk::CellRendererText *_text_rendererDoc; - Gtk::CellRendererPixbuf *_pixbuf_rendererDoc; - Gtk::TreeView::Column *_name_columnDoc; - Gtk::TreeView::Column *_pixbuf_columnDoc; - Gtk::ScrolledWindow _scrollerDoc; - Gtk::TreeView _editDoc; - Gtk::HBox _buttonsRowDoc; - Gtk::VBox _editDocV; - - Gtk::Notebook _notebook; - - SwatchWatcher* rootWatcher; - std::vector rootWatchers; - - std::vector docWatchers; - SwatchWatcher* docWatcher; + static void _trackDocument( SwatchesPanel *panel, SPDocument *document ); + static void handleDefsModified(SPDocument *document); + + PreviewHolder* _holder; + ColorItem* _clear; + ColorItem* _remove; + int _currentIndex; SPDesktop* _currentDesktop; SPDocument* _currentDocument; - - bool _dnd_into; - SPObject* _dnd_source; - SPObject* _dnd_target; sigc::connection _documentConnection; sigc::connection _selChanged; + + friend class DocTrack; }; } //namespace Dialogs -- cgit v1.2.3 From 9a04c985ec628dc749a8a82d94bcf47d482a4f63 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 20 Mar 2014 17:09:57 -0400 Subject: Fix a linker error ("static") (hopefully) Resolve compiler errors with GTK3+ (bzr r13090.1.28) --- src/ui/dialog/objects.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 338233042..85583a0e7 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -1887,8 +1887,9 @@ ObjectsPanel::ObjectsPanel() : btn = Gtk::manage( new Gtk::Button() ); btn->set_tooltip_text(_("Collapse All")); #if GTK_CHECK_VERSION(3,10,0) - btn->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else + image_remove = Gtk::manage(new Gtk::Image()); image_remove->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); btn->set_image(*image_remove); #endif -- cgit v1.2.3 From 1185cce53f3e490c6bb7939b1d9f42272a2e2f4f Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 3 Apr 2014 14:49:00 +0200 Subject: Try and explain what selection means when aligning. Changed Selection to Selection Area (bzr r13257) --- src/ui/dialog/align-and-distribute.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 6b4aeebb9..e02ccd3f1 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -1002,7 +1002,7 @@ AlignAndDistribute::AlignAndDistribute() _combo.append(_("Smallest object")); _combo.append(_("Page")); _combo.append(_("Drawing")); - _combo.append(_("Selection")); + _combo.append(_("Selection Area")); _combo.set_active(prefs->getInt("/dialogs/align/align-to", 6)); _combo.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_ref_change)); -- cgit v1.2.3 From 94226a90e4ba925c940f69059249836edfcd54e8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 4 Apr 2014 15:16:22 +0200 Subject: XMLTree and InkscapePreferences are not dockable windows, don't treat them like one. (bzr r13262) --- src/ui/dialog/dialog-manager.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 47e1fdd30..4be796e67 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -96,6 +96,9 @@ DialogManager::DialogManager() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1); + registerFactory("InkscapePreferences", &create); + registerFactory("XmlTree", &create); + if (dialogs_type == FLOATING) { registerFactory("AlignAndDistribute", &create); registerFactory("DocumentMetadata", &create); @@ -106,7 +109,6 @@ DialogManager::DialogManager() { registerFactory("Find", &create); registerFactory("Glyphs", &create); registerFactory("IconPreviewPanel", &create); - registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); @@ -126,7 +128,6 @@ DialogManager::DialogManager() { registerFactory("TextFont", &create); registerFactory("SpellCheck", &create); registerFactory("Export", &create); - registerFactory("XmlTree", &create); registerFactory("CloneTiler", &create); } else { @@ -140,7 +141,6 @@ DialogManager::DialogManager() { registerFactory("Find", &create); registerFactory("Glyphs", &create); registerFactory("IconPreviewPanel", &create); - registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); @@ -160,7 +160,6 @@ DialogManager::DialogManager() { registerFactory("TextFont", &create); registerFactory("SpellCheck", &create); registerFactory("Export", &create); - registerFactory("XmlTree", &create); registerFactory("CloneTiler", &create); } -- cgit v1.2.3 From f337f7705f290ecef1790c75f8f94c85e13777b2 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 4 Apr 2014 20:12:04 +0200 Subject: fix crash. Iterating through a list to find an object is not necessary, SPDoc provides method for obtaining SPObj from idstring. The crash probably happened because deleting the object invalidated the list iterated (partly). Fixed bugs: - https://launchpad.net/bugs/1302079 (bzr r13265) --- src/ui/dialog/document-properties.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 67e788e21..2674efc1e 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1236,23 +1236,16 @@ void DocumentProperties::removeEmbeddedScript(){ } } - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - while ( current ) { - if (current->data && SP_IS_OBJECT(current->data)) { - SPObject* obj = SP_OBJECT(current->data); - if (id == obj->getId()){ - - //XML Tree being used directly here while it shouldn't be. - Inkscape::XML::Node *repr = obj->getRepr(); - if (repr){ - sp_repr_unparent(repr); - - // inform the document, so we can undo - DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script")); - } - } + SPObject* obj = SP_ACTIVE_DOCUMENT->getObjectById(id); + if (obj) { + //XML Tree being used directly here while it shouldn't be. + Inkscape::XML::Node *repr = obj->getRepr(); + if (repr){ + sp_repr_unparent(repr); + + // inform the document, so we can undo + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script")); } - current = g_slist_next(current); } populate_script_lists(); -- cgit v1.2.3 From 749e8b0ee6b95f7c704fd326ebe948f9f4a076d2 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 5 Apr 2014 09:22:29 +0200 Subject: Revert the xml editor to it's dockable behaviour and add a comment for the preferences. (bzr r13269) --- src/ui/dialog/dialog-manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 4be796e67..d427e3590 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -96,8 +96,8 @@ DialogManager::DialogManager() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1); + // The preferences dialog is broken, the DockBehavior code resizes it's floating window to the smallest size registerFactory("InkscapePreferences", &create); - registerFactory("XmlTree", &create); if (dialogs_type == FLOATING) { registerFactory("AlignAndDistribute", &create); @@ -129,6 +129,7 @@ DialogManager::DialogManager() { registerFactory("SpellCheck", &create); registerFactory("Export", &create); registerFactory("CloneTiler", &create); + registerFactory("XmlTree", &create); } else { @@ -161,6 +162,7 @@ DialogManager::DialogManager() { registerFactory("SpellCheck", &create); registerFactory("Export", &create); registerFactory("CloneTiler", &create); + registerFactory("XmlTree", &create); } } -- cgit v1.2.3 From 7744bd7a4bdfedd8d0d04b647fd6c0e80a603cb7 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 18 Apr 2014 19:08:21 -0400 Subject: Add image rendering option for outlines. Setup desktop preferences observer. (bzr r13291.1.1) --- src/ui/dialog/inkscape-preferences.cpp | 5 +++++ src/ui/dialog/inkscape-preferences.h | 1 + 2 files changed, 6 insertions(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index d826ece09..940f105d0 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1463,6 +1463,11 @@ void InkscapePreferences::initPageBitmaps() _page_bitmaps.add_line( false, "", _importexport_import_res_override, "", _("Use default bitmap resolution in favor of information from file")); + _page_bitmaps.add_group_header( _("Render")); + // rendering outlines for pixmap image tags + _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", true); + _page_bitmaps.add_line(false, _(""), _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); + this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); } diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index da85b805d..1c2151605 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -292,6 +292,7 @@ protected: UI::Widget::PrefCheckButton _show_filters_info_box; UI::Widget::PrefCombo _dockbar_style; UI::Widget::PrefCombo _switcher_style; + UI::Widget::PrefCheckButton _rendering_image_outline; UI::Widget::PrefSpinButton _rendering_cache_size; UI::Widget::PrefSpinButton _filter_multi_threaded; -- cgit v1.2.3 From 47abc2d2947692786bb402cedc107e40b9cd21e5 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 19 Apr 2014 00:52:30 -0400 Subject: Fix remaining issue with prefs updating (bzr r13291.1.2) --- src/ui/dialog/inkscape-preferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 940f105d0..559398a84 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1465,7 +1465,7 @@ void InkscapePreferences::initPageBitmaps() _page_bitmaps.add_group_header( _("Render")); // rendering outlines for pixmap image tags - _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", true); + _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", false); _page_bitmaps.add_line(false, _(""), _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); -- cgit v1.2.3 From 67c3fc5586ae05506f75bb30fe46a071e20613d2 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 24 Apr 2014 14:04:31 +0200 Subject: Clean up of style code, removal of SPFontStyle. Step 2. (bzr r13300) --- src/ui/dialog/font-substitution.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index bf9133086..6e9ecc3c8 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -200,16 +200,16 @@ GSList * FontSubstitution::getFontReplacedItems(SPDocument* doc, Glib::ustring * } } - if (style && style->text) { + if (style) { gchar const *style_font = NULL; - if (style->text->font_family.set) - style_font = style->text->font_family.value; - else if (style->text->font_specification.set) - style_font = style->text->font_specification.value; - else if (style->text->font_family.value) - style_font = style->text->font_family.value; - else if (style->text->font_specification.value) - style_font = style->text->font_specification.value; + if (style->font_family.set) + style_font = style->font_family.value; + else if (style->font_specification.set) + style_font = style->font_specification.value; + else if (style->font_family.value) + style_font = style->font_family.value; + else if (style->font_specification.value) + style_font = style->font_specification.value; if (style_font) { if (has_visible_text(item)) { -- cgit v1.2.3 From b9f02c6200865e24150ce14a1e480c4283b0472a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 25 Apr 2014 12:49:54 -0700 Subject: Improve keyboard navigation in LPE dialog. Fixed bugs: - https://launchpad.net/bugs/1310688 (bzr r13305) --- src/ui/dialog/livepatheffect-add.cpp | 14 ++++++++++++++ src/ui/dialog/livepatheffect-add.h | 4 ++++ 2 files changed, 18 insertions(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/livepatheffect-add.cpp b/src/ui/dialog/livepatheffect-add.cpp index b5f51d81d..c558eddaf 100644 --- a/src/ui/dialog/livepatheffect-add.cpp +++ b/src/ui/dialog/livepatheffect-add.cpp @@ -38,6 +38,7 @@ LivePathEffectAdd::LivePathEffectAdd() : scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); scrolled_window.set_shadow_type(Gtk::SHADOW_IN); scrolled_window.set_size_request(250, 200); + scrolled_window.set_can_focus(); /** * Effect Store and Tree @@ -83,10 +84,12 @@ LivePathEffectAdd::LivePathEffectAdd() : add_action_widget(close_button, Gtk::RESPONSE_CLOSE); add_action_widget(add_button, Gtk::RESPONSE_APPLY); + /** * Signal handlers */ effectlist_treeview.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LivePathEffectAdd::onButtonEvent) ); + effectlist_treeview.signal_key_press_event().connect_notify(sigc::mem_fun(*this, &LivePathEffectAdd::onKeyEvent)); close_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onClose)); add_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onAdd)); signal_delete_event().connect( sigc::bind_return(sigc::hide(sigc::mem_fun(*this, &LivePathEffectAdd::onClose)), true ) ); @@ -107,6 +110,16 @@ void LivePathEffectAdd::onClose() hide(); } +void LivePathEffectAdd::onKeyEvent(GdkEventKey* evt) +{ + if (evt->keyval == GDK_KEY_Return) { + onAdd(); + } + if (evt->keyval == GDK_KEY_Escape) { + onClose(); + } +} + void LivePathEffectAdd::onButtonEvent(GdkEventButton* evt) { // Double click on tree is same as clicking the add button @@ -135,6 +148,7 @@ void LivePathEffectAdd::show(SPDesktop *desktop) dial.set_modal(true); desktop->setWindowTransient (dial.gobj()); dial.property_destroy_with_parent() = true; + dial.effectlist_treeview.grab_focus(); dial.run(); } diff --git a/src/ui/dialog/livepatheffect-add.h b/src/ui/dialog/livepatheffect-add.h index 7fa766272..99ead878c 100644 --- a/src/ui/dialog/livepatheffect-add.h +++ b/src/ui/dialog/livepatheffect-add.h @@ -74,6 +74,10 @@ protected: */ void onButtonEvent(GdkEventButton* evt); + /** + * Key event + */ + void onKeyEvent(GdkEventKey* evt); private: Gtk::TreeView effectlist_treeview; -- cgit v1.2.3 From 1fd4e3f17b3d591c56d0a50b877909791cd6c05e Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 5 May 2014 11:22:35 -0700 Subject: Add one more ifdef for LPETool prefs. Thanks suv! (bzr r13337) --- src/ui/dialog/inkscape-preferences.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 559398a84..e757bf702 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -500,10 +500,12 @@ void InkscapePreferences::initPageTools() _page_connector.add_line(false, "", _connector_ignore_text, "", _("If on, connector attachment points will not be shown for text objects")); +#ifdef WITH_LPETOOL //LPETool - // commented out, because the LPETool is not finished yet. + //disabled, because the LPETool is not finished yet. //this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL); //this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool"); +#endif // WITH_LPETOOL } void InkscapePreferences::initPageUI() -- cgit v1.2.3 From 65c7b8f3c893e681b5d395cbef9a8b37d17e07a8 Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 5 May 2014 11:29:46 -0700 Subject: Apparently I didn't look twice before committing. Thanks suv! (bzr r13338) --- src/ui/dialog/inkscape-preferences.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index e757bf702..b6095fa8b 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -503,8 +503,8 @@ void InkscapePreferences::initPageTools() #ifdef WITH_LPETOOL //LPETool //disabled, because the LPETool is not finished yet. - //this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL); - //this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool"); + this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL); + this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool"); #endif // WITH_LPETOOL } -- cgit v1.2.3 From 4038de8b4763974c97aa8fcb9d87b83c1a5daac7 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 10 May 2014 15:16:24 -0400 Subject: Add selection sets (bzr r13090.1.75) --- src/ui/dialog/Makefile_insert | 2 + src/ui/dialog/dialog-manager.cpp | 6 +- src/ui/dialog/tags.cpp | 1155 ++++++++++++++++++++++++++++++++++++++ src/ui/dialog/tags.h | 181 ++++++ 4 files changed, 1341 insertions(+), 3 deletions(-) create mode 100644 src/ui/dialog/tags.cpp create mode 100644 src/ui/dialog/tags.h (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 8a7a4a5dd..1aa73dc5b 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -100,6 +100,8 @@ ink_common_sources += \ ui/dialog/template-load-tab.h \ ui/dialog/template-widget.cpp \ ui/dialog/template-widget.h \ + ui/dialog/tags.cpp \ + ui/dialpg/tags.h \ ui/dialog/text-edit.cpp \ ui/dialog/text-edit.h \ ui/dialog/tile.cpp \ diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 22c41d75e..bd2f1eb12 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -55,7 +55,7 @@ #include "ui/dialog/clonetiler.h" #include "ui/dialog/svg-fonts-dialog.h" #include "ui/dialog/objects.h" -//#include "ui/dialog/tags.h" +#include "ui/dialog/tags.h" namespace Inkscape { namespace UI { @@ -113,7 +113,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); -// registerFactory("TagsPanel", &create); + registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -148,7 +148,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); -// registerFactory("TagsPanel", &create); + registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp new file mode 100644 index 000000000..7fdd2e906 --- /dev/null +++ b/src/ui/dialog/tags.cpp @@ -0,0 +1,1155 @@ +/* + * A simple panel for tags + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "tags.h" +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" +#include "inkscape.h" +#include "layer-fns.h" +#include "layer-manager.h" +#include "preferences.h" +#include "sp-item.h" +#include "sp-object.h" +#include "sp-shape.h" +#include "svg/css-ostringstream.h" +#include "ui/icon-names.h" +#include "ui/widget/layertypeicon.h" +#include "ui/widget/addtoicon.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/node.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-root.h" +#include "ui/tools/tool-base.h" //"event-context.h" +#include "selection.h" +#include "dialogs/dialog-events.h" +#include "widgets/sp-color-notebook.h" +#include "style.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-tag.h" +#include "sp-defs.h" +#include "sp-tag-use.h" +#include "sp-tag-use-reference.h" + +//#define DUMP_LAYERS 1 + +namespace Inkscape { +namespace UI { +namespace Dialog { + +using Inkscape::XML::Node; + +TagsPanel& TagsPanel::getInstance() +{ + return *new TagsPanel(); +} + +enum { + COL_ADD = 1 +}; + +enum { + BUTTON_NEW = 0, + BUTTON_TOP, + BUTTON_BOTTOM, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_DELETE, + DRAGNDROP +}; + +class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { +public: + ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) : + _pnl(pnl), + _obj(obj), + _repr(repr), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + ObjectWatcher(TagsPanel* pnl, SPObject* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if ( _pnl && _obj ) { + if ( name == _labelAttr ) { + _pnl->_updateObject( _obj); + } + } + } + + TagsPanel* _pnl; + SPObject* _obj; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; +}; + +class TagsPanel::InternalUIBounce +{ +public: + int _actionCode; +}; + +void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) +{ + bool set = false; + + if ( iconName ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + set = true; + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !set && action && action->image ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + set = true; + } + } + } + + btn.set_tooltip_text (tooltip); +} + + +Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) +{ + GtkWidget* iconWidget = 0; + const char* label = 0; + + if ( iconName ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !iconWidget && action && action->image ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); + } + + if ( action ) { + label = action->name; + } + } + } + + if ( !label && fallback ) { + label = fallback; + } + + Gtk::Widget* wrapped = 0; + if ( iconWidget ) { + wrapped = manage(Glib::wrap(iconWidget)); + wrapped->show(); + } + + + Gtk::MenuItem* item = 0; + + if (wrapped) { + item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); + } else { + item = Gtk::manage(new Gtk::MenuItem(label, true)); + } + + item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id)); + _popupMenu.append(*item); + + return *item; +} + +void TagsPanel::_fireAction( unsigned int code ) +{ + if ( _desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(_desktop); + if ( action ) { + sp_action_perform( action, NULL ); + } + } + } +} + +void TagsPanel::_takeAction( int val ) +{ + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 ); + } +} + +bool TagsPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _pending) + { + int val = _pending->_actionCode; +// SPObject* target = _pending->_target; + bool empty = _desktop->selection->isEmpty(); + + switch ( val ) { + case BUTTON_NEW: + { + _fireAction( SP_VERB_TAG_NEW ); + } + break; + case BUTTON_TOP: + { + _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT); + } + break; + case BUTTON_BOTTOM: + { + _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK ); + } + break; + case BUTTON_UP: + { + _fireAction( empty ? SP_VERB_LAYER_RAISE : SP_VERB_SELECTION_RAISE ); + } + break; + case BUTTON_DOWN: + { + _fireAction( empty ? SP_VERB_LAYER_LOWER : SP_VERB_SELECTION_LOWER ); + } + break; + case BUTTON_DELETE: + { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); + } + break; + case DRAGNDROP: + { + _doTreeMove( ); + } + break; + } + + delete _pending; + _pending = 0; + } + + return false; +} + + +class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colParentObject); + add(_colObject); + add(_colLabel); + add(_colAddRemove); + add(_colAllowAddRemove); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colParentObject; + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colAddRemove; + Gtk::TreeModelColumn _colAllowAddRemove; +}; + +void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete) +{ + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && obj->parent) { + todelete->push_back(obj); + } +} + +void TagsPanel::_updateObject( SPObject *obj ) { + _store->foreach( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) ); +} + +bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + if ( obj == row[_model->_colObject] ) + { + /* + * We get notified of layer update here (from layer->setLabel()) before layer->label() is set + * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which + * has the correct value (bug #168351) + */ + //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId(); + gchar const *label; + SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0; + if (use && use->ref->isAttached()) { + label = use->ref->getObject()->getAttribute("inkscape:label"); + } else { + label = obj->getAttribute("inkscape:label"); + } + row[_model->_colLabel] = label ? label : obj->getId(); + row[_model->_colAddRemove] = SP_IS_TAG(obj); + } + + return false; +} + +void TagsPanel::_objectsSelected( Selection *sel ) { + + _selectedConnection.block(); + _tree.get_selection()->unselect_all(); + for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next) + { + SPObject *obj = reinterpret_cast(iter->data); + _store->foreach(sigc::bind( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); + } + _selectedConnection.unblock(); + _checkTreeSelection(); +} + +bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + SPObject * it = row[_model->_colObject]; + if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj ) + { + Glib::RefPtr select = _tree.get_selection(); + + select->select(iter); + } + return false; +} + +void TagsPanel::_objectsChanged(SPObject* root) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_desktop) { + SPDocument* document = _desktop->doc(); + SPDefs* root = document->getDefs(); + if ( root ) { + _selectedConnection.block(); + _store->clear(); + _addObject( document, root, 0 ); + _selectedConnection.unblock(); + _objectsSelected(_desktop->selection); + _checkTreeSelection(); + } + } +} + +void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) +{ + if ( _desktop && obj ) { + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG(child)) + { + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = child->label() ? child->label() : child->getId(); + row[_model->_colAddRemove] = true; + row[_model->_colAllowAddRemove] = true; + + _tree.expand_to_path( _store->get_path(iter) ); + + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); + child->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + _addObject( doc, child, &row ); + } + } + if (SP_IS_TAG(obj) && obj->children) + { + Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row rowitems = *iteritems; + rowitems[_model->_colObject] = NULL; + rowitems[_model->_colParentObject] = obj; + rowitems[_model->_colLabel] = _("Items"); + rowitems[_model->_colAddRemove] = false; + rowitems[_model->_colAllowAddRemove] = false; + + _tree.expand_to_path( _store->get_path(iteritems) ); + + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child)) + { + SPItem *item = SP_TAG_USE(child)->ref->getObject(); + Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; + row[_model->_colAddRemove] = false; + row[_model->_colAllowAddRemove] = true; + + if (SP_TAG(obj)->expanded()) { + _tree.expand_to_path( _store->get_path(iter) ); + } + + if (item) { + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); + item->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + } + } + } + } + } +} + +void TagsPanel::_select_tag( SPTag * tag ) +{ + for (SPObject * child = tag->children; child != NULL; child = child->next) + { + if (SP_IS_TAG(child)) { + _select_tag(SP_TAG(child)); + } else if (SP_IS_TAG_USE(child)) { + SPObject * obj = SP_TAG_USE(child)->ref->getObject(); + if (obj) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); + _desktop->selection->add(obj); + } + } + } +} + +void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _select_tag(SP_TAG(obj)); + } else if (SP_IS_TAG_USE(obj)) { + SPObject * item = SP_TAG_USE(obj)->ref->getObject(); + if (item) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + } + } + } +} + +void TagsPanel::_pushTreeSelectionToCurrent() +{ + _selectionChangedConnection.block(); + // TODO hunt down the possible API abuse in getting NULL + if ( _desktop && _desktop->currentRoot() ) { + _desktop->selection->clear(); + _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback)); + } + _selectionChangedConnection.unblock(); + + _checkTreeSelection(); +} + +void TagsPanel::_checkTreeSelection() +{ + bool sensitive = _tree.get_selection()->count_selected_rows() > 0; + bool sensitiveNonTop = true; + bool sensitiveNonBottom = true; +// if ( _tree.get_selection()->count_selected_rows() > 0 ) { +// sensitive = true; +// +// SPObject* inTree = _selectedLayer(); +// if ( inTree ) { +// +// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0); +// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); +// +// } +// } + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( sensitive ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonTop ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonBottom ); + } +} + +bool TagsPanel::_handleKeyEvent(GdkEventKey *event) +{ + + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter && !_text_renderer->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && SP_IS_TAG(obj)) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_renderer->property_editable() = true; + _tree.set_cursor(*path, *_name_column, true); + grab_focus(); + return true; + } + } + } + case GDK_KEY_Delete: { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); + } + return true; + } + break; + } + return false; +} + +bool TagsPanel::_handleButtonEvent(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + // TODO - fix to a better is-popup function + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _tree.get_path_at_pos( x, y, path ) ) { + _checkTreeSelection(); + _popupMenu.popup(event->button, event->time); + if (_tree.get_selection()->is_selected(path)) { + return true; + } + } + } + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { + // 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(event->x); + int y = static_cast(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_ADD-1)) { + down_at_add = true; + return true; + } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection)); + _defer_target = path; + } else { + down_at_add = false; + } + } else { + down_at_add = false; + } + } + + if ( event->type == GDK_BUTTON_RELEASE) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction)); + } + + // 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)) { + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (_defer_target) { + if (_defer_target == path && !(event->x == 0 && event->y == 0)) + { + _tree.set_cursor(path, *col, false); + } + _defer_target = Gtk::TreeModel::Path(); + } else { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + + if (obj) { + if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { + if (SP_IS_TAG(obj)) { + bool wasadded = false; + for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next) + { + SPObject *newobj = reinterpret_cast(iter->data); + bool addchild = true; + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { + addchild = false; + } + } + if (addchild) { + Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref"); + clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false); + obj->appendChild(clone); + wasadded = true; + } + } + if (wasadded) { + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to set")); + } + } else { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * tobj = *iter; + if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { + tobj->parent->getRepr()->removeChild(tobj->getRepr()); + } + } + } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); + } + } + } + } + } + } + + + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } + + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) { + // Double click on the Layer name, enable editing + _text_renderer->property_editable() = true; + _tree.set_cursor (path, *_name_column, true); + grab_focus(); + } + } + } + + return false; +} + +void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPObject* obj = row[_model->_colObject]; + SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0; + if (item) + { + _dnd_source.push_back(item); + } +} + +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +{ + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + _dnd_into = true; + _dnd_target = _document->getDefs(); + _dnd_source.clear(); + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource)); + + if (_dnd_source.empty()) { + return true; + } + + if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _tree.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y > (int)(cell_height * 2/3)) { + Gtk::TreeModel::Path next_path = target_path; + next_path.next(); + if (_store->iter_is_valid(_store->get_iter(next_path))) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + // Drop into the top level + _dnd_target = _document->getDefs(); + _dnd_into = true; + } + } + } + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + SPObject *pobj = row[_model->_colParentObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _dnd_target = SP_TAG(obj); + } else if (SP_IS_TAG(obj->parent)) { + _dnd_target = SP_TAG(obj->parent); + _dnd_into = true; + } + } else if (pobj && SP_IS_TAG(pobj)) { + _dnd_target = SP_TAG(pobj); + _dnd_into = true; + } else { + return true; + } + } + } + + _takeAction(DRAGNDROP); + + return false; +} + +/* + * Move a layer in response to a drag & drop action + */ +void TagsPanel::_doTreeMove( ) +{ + if (_dnd_target) { + for (std::vector::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter) + { + SPTag *src = *iter; + if (src != _dnd_target) { + src->moveTo(_dnd_target, _dnd_into); + } + } + _desktop->selection->clear(); + while (!_dnd_source.empty()) + { + SPTag *src = _dnd_source.back(); + _select_tag(src); + _dnd_source.pop_back(); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS, + _("Moved sets")); + } +} + + +void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_renderer->property_editable() = false; +} + +void TagsPanel::_handleEditingCancelled() +{ + _text_renderer->property_editable() = false; +} + +void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && _desktop) { + SPObject* obj = row[_model->_colObject]; + if ( obj ) { + if (SP_IS_TAG(obj)) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } + } + } +} + +bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + return false; +} + +bool TagsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + bool val = true; + if ( !currentlySelected && _toggleEvent ) + { + GdkEvent* event = gtk_get_current_event(); + if ( event ) { + // (keep these checks separate, so we know when to call gdk_event_free() + if ( event->type == GDK_BUTTON_PRESS ) { + GdkEventButton const* target = reinterpret_cast(_toggleEvent); + GdkEventButton const* evtb = reinterpret_cast(event); + + if ( (evtb->window == target->window) + && (evtb->send_event == target->send_event) + && (evtb->time == target->time) + && (evtb->state == target->state) + ) + { + // Ooooh! It's a magic one + val = false; + } + } + gdk_event_free(event); + } + } + return val; +} + +void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colParentObject]; + if (obj && SP_IS_TAG(obj)) + { + SP_TAG(obj)->setExpanded(isexpanded); + obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Constructor + */ +TagsPanel::TagsPanel() : + UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS), + _rootWatcher(0), + deskTrack(), + _desktop(0), + _document(0), + _model(0), + _pending(0), + _toggleEvent(0), + _defer_target(), + desktopChangeConn() +{ + //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + _tree.set_model( _store ); + _tree.set_headers_visible(false); + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon()); + int addColNum = _tree.append_column("type", *addRenderer) - 1; + Gtk::TreeViewColumn *col = _tree.get_column(addColNum); + if ( col ) { + col->add_attribute( addRenderer->property_active(), _model->_colAddRemove ); + col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove ); + } + + _text_renderer = manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + + _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) ); + _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) ); + + _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false); + _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false)); + _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true)); + + _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) ); + _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) ); + + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false ); + + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + _scroller.get_preferred_size(sreq_natural, sreq); +#else + sreq = _scroller.size_request(); +#endif + int minHeight = 70; + if (sreq.height < minHeight) { + // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar + _scroller.set_size_request(sreq.width, minHeight); + } + + _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); + + _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + + _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET); + + SPDesktop* targetDesktop = getDesktop(); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new selection set") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); + _buttonsSecondary.pack_start(*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) ); +// _buttonsRow.add( *btn ); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Set") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); + _watching.push_back( btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); + + // ------------------------------------------------------- + { + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); + + _popupMenu.show_all_children(); + } + // ------------------------------------------------------- + + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( false ); + } + + setDesktop( targetDesktop ); + + show_all_children(); + + // restorePanelPrefs(); + + // Connect this up last + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); +} + +TagsPanel::~TagsPanel() +{ + + setDesktop(NULL); + + if ( _model ) + { + delete _model; + _model = 0; + } + + if (_pending) { + delete _pending; + _pending = 0; + } + + if ( _toggleEvent ) + { + gdk_event_free( _toggleEvent ); + _toggleEvent = 0; + } + + desktopChangeConn.disconnect(); + deskTrack.disconnect(); +} + +void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_rootWatcher) + { + _rootWatcher->_repr->removeObserver(*_rootWatcher); + delete _rootWatcher; + _rootWatcher = NULL; + } + + _document = document; + + if (document && document->getDefs() && document->getDefs()->getRepr()) + { + _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs()); + document->getDefs()->getRepr()->addObserver(*_rootWatcher); + _objectsChanged(document->getDefs()); + } +} + +void TagsPanel::setDesktop( SPDesktop* desktop ) +{ + Panel::setDesktop(desktop); + + if ( desktop != _desktop ) { + _documentChangedConnection.disconnect(); + _selectionChangedConnection.disconnect(); + if ( _desktop ) { + _desktop = 0; + } + + _desktop = Panel::getDesktop(); + if ( _desktop ) { + //setLabel( _desktop->doc()->name ); + _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument)); + _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected)); + + setDocument(_desktop, _desktop->doc()); + } + } +/* + GSList const *layers = _desktop->doc()->getResourceList( "layer" ); + g_message( "layers list starts at %p", layers ); + for ( GSList const *iter=layers ; iter ; iter = iter->next ) { + SPObject *layer=static_cast(iter->data); + g_message(" {%s} [%s]", layer->id, layer->label() ); + } +*/ + deskTrack.setBase(desktop); +} + + + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h new file mode 100644 index 000000000..d35dfba01 --- /dev/null +++ b/src/ui/dialog/tags.h @@ -0,0 +1,181 @@ +/* + * A simple dialog for tags UI. + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_TAGS_PANEL_H +#define SEEN_TAGS_PANEL_H + +#include +#include +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/panel.h" +#include "ui/widget/object-composite-settings.h" +#include "desktop-tracker.h" +#include "ui/widget/style-subject.h" +#include "selection.h" +#include "ui/widget/filter-effect-chooser.h" + +class SPObject; +class SPTag; +struct SPColorSelector; + +namespace Inkscape { + +namespace UI { +namespace Dialog { + + +/** + * A panel that displays layers. + */ +class TagsPanel : public UI::Widget::Panel +{ +public: + TagsPanel(); + virtual ~TagsPanel(); + + //virtual void setOrientation( Gtk::AnchorType how ); + + static TagsPanel& getInstance(); + + void setDesktop( SPDesktop* desktop ); + void setDocument( SPDesktop* desktop, SPDocument* document); + +protected: + //virtual void _handleAction( int setId, int itemId ); + friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); +private: + class ModelColumns; + class InternalUIBounce; + class ObjectWatcher; + + TagsPanel(TagsPanel const &); // no copy + TagsPanel &operator=(TagsPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); + void _fireAction( unsigned int code ); + Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _storeDragSource(const Gtk::TreeModel::iterator& iter); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + + void _doTreeMove(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _pushTreeSelectionToCurrent(); + void _selected_row_callback( const Gtk::TreeModel::iterator& iter ); + void _select_tag( SPTag * tag ); + + void _checkTreeSelection(); + + void _takeAction( int val ); + bool _executeAction(); + + void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); + + bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + + void _updateObject(SPObject *obj); + bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj); + + void _objectsSelected(Selection *sel); + bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); + + void _objectsChanged(SPObject *root); + void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ); + + void _checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete); + +// std::vector groupConnections; + TagsPanel::ObjectWatcher* _rootWatcher; + std::vector _objectWatchers; + + // Hooked to the layer manager: + sigc::connection _documentChangedConnection; + sigc::connection _selectionChangedConnection; + + sigc::connection _changedConnection; + sigc::connection _addedConnection; + sigc::connection _removedConnection; + + // Internal + sigc::connection _selectedConnection; + sigc::connection _expandedConnection; + sigc::connection _collapsedConnection; + + DesktopTracker deskTrack; + SPDesktop* _desktop; + SPDocument* _document; + ModelColumns* _model; + InternalUIBounce* _pending; + gboolean _dnd_into; + std::vector _dnd_source; + SPObject* _dnd_target; + + GdkEvent* _toggleEvent; + bool down_at_add; + + Gtk::TreeModel::Path _defer_target; + + Glib::RefPtr _store; + std::vector _watching; + std::vector _watchingNonTop; + std::vector _watchingNonBottom; + + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::TreeView::Column *_name_column; +#if WITH_GTKMM_3_0 + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; +#else + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; +#endif + Gtk::ScrolledWindow _scroller; + Gtk::Menu _popupMenu; + Inkscape::UI::Widget::SpinButton _spinBtn; + Gtk::VBox _layersPage; + + sigc::connection desktopChangeConn; + +}; + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_OBJECTS_PANEL_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From f9b46a56e41c1fb0d743ae381394b2245f264fc8 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 11 May 2014 13:57:14 +0200 Subject: i18n. Fix for bug #1318289 (preferences > bitmap > rendering shows po file headers). Fixed bugs: - https://launchpad.net/bugs/1318289 (bzr r13350) --- src/ui/dialog/inkscape-preferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index b6095fa8b..f1a29e971 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1468,7 +1468,7 @@ void InkscapePreferences::initPageBitmaps() _page_bitmaps.add_group_header( _("Render")); // rendering outlines for pixmap image tags _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", false); - _page_bitmaps.add_line(false, _(""), _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); + _page_bitmaps.add_line(false, "", _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); } -- cgit v1.2.3 From 1fb28d6c7a8d030542ab5bcdf6ed6228356e213d Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 11 May 2014 16:04:42 +0200 Subject: i18n. Fix for bug #1318345 (untranslatable strings in trunk-r13348). Fixed bugs: - https://launchpad.net/bugs/1318345 (bzr r13352) --- src/ui/dialog/grid-arrange-tab.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 8c0a4dc66..72217c729 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -708,7 +708,7 @@ GridArrangeTab::GridArrangeTab(ArrangeDialog *parent) HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1); // Anchor selection widget - AlignLabel.set_label("Alignment:"); + AlignLabel.set_label(_("Alignment:")); AlignLabel.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); AlignmentSelector.setAlignment(HorizAlign, VertAlign); AlignmentSelector.on_selectionChanged().connect(sigc::mem_fun(*this, &GridArrangeTab::Align_changed)); -- cgit v1.2.3 From 1f1932ae4592c8f316e3a68ac86874bf87f321c4 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 11 May 2014 14:23:10 -0400 Subject: Stabilize the selection set system a bit (bzr r13090.1.76) --- src/ui/dialog/tags.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 7fdd2e906..14ad5b8cc 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -280,7 +280,8 @@ bool TagsPanel::_executeAction() for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { SPObject * obj = *iter; if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); + //obj->parent->getRepr()->removeChild(obj->getRepr()); + obj->deleteObject(true, true); } } DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); @@ -576,7 +577,8 @@ bool TagsPanel::_handleKeyEvent(GdkEventKey *event) for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { SPObject * obj = *iter; if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); + //obj->parent->getRepr()->removeChild(obj->getRepr()); + obj->deleteObject(true, true); } } DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); @@ -680,12 +682,14 @@ bool TagsPanel::_handleButtonEvent(GdkEventButton* event) } } else { std::vector todelete; + // FIXME unnecessary use of XML tree _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); if (!todelete.empty()) { for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { SPObject * tobj = *iter; if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { - tobj->parent->getRepr()->removeChild(tobj->getRepr()); + //tobj->parent->getRepr()->removeChild(tobj->getRepr()); + tobj->deleteObject(true, true); } } } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { -- cgit v1.2.3 From 0dc8b506fe92a6f4a57d6412db69c3fea420d67a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 11 May 2014 15:08:59 -0400 Subject: Rename "Tags" to "Selection sets" to avoid confusion with a global tagging system (bzr r13090.1.77) --- src/ui/dialog/tags.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 14ad5b8cc..1b5dd9400 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -1025,7 +1025,7 @@ TagsPanel::TagsPanel() : // ------------------------------------------------------- { - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "Add a new selection set", (int)BUTTON_NEW ) ); _popupMenu.show_all_children(); } -- cgit v1.2.3 From 3ef365a9d42823ded18fb31aa2c36c39005cb0ee Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 11 May 2014 23:38:10 +0200 Subject: fix build for some (windows 64 bit devlibs attempt) specifically, fixes this build error: .../include/glibmm-2.4/glibmm/threads.h:201:11: error: field 'gobject_' has incomplete type 'GThread {aka _GThread}' (bzr r13357) --- src/ui/dialog/filedialogimpl-win32.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index 29bcb9a45..a71ee1ad0 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -13,6 +13,8 @@ # include "config.h" #endif +#include + #ifdef WIN32 #if WITH_GLIBMM_2_32 #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -- cgit v1.2.3 From 41ab3bd526807e0a092466e7d4e979f12bab81ff Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 13 May 2014 21:17:06 +0200 Subject: fix windows 64bit build. (changes already committed to trunk) (bzr r13341.1.19) --- src/ui/dialog/filedialogimpl-win32.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index 29bcb9a45..a71ee1ad0 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -13,6 +13,8 @@ # include "config.h" #endif +#include + #ifdef WIN32 #if WITH_GLIBMM_2_32 #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -- cgit v1.2.3 From 779a151867babce787dbd06ff1e40d54d3b9443d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 May 2014 16:13:07 +0200 Subject: Fix Pango markup used in Text and Font dialog. (bzr r13378) --- src/ui/dialog/text-edit.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 17c29c69f..c1ebb32e0 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -404,12 +404,12 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase) double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt"); // Pango font size is in 1024ths of a point - // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE ); + // C++11: Glib::ustring size = std::to_string( int(pt_size * PANGO_SCALE) ); std::ostringstream size_st; - size_st << pt_size * PANGO_SCALE; + size_st << int(pt_size * PANGO_SCALE); // Markup code expects integers - Glib::ustring markup = "" + phrase_escaped + ""; + Glib::ustring markup = "" + phrase_escaped + ""; preview_label.set_markup(markup.c_str()); } -- cgit v1.2.3 From 16262c5a24e91309c4c762ffbb0e82b05026c9b6 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 May 2014 16:14:19 +0200 Subject: Fix Pango markup in Text and Font dialog. (bzr r13341.1.25) --- src/ui/dialog/text-edit.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 17c29c69f..c1ebb32e0 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -404,12 +404,12 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase) double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt"); // Pango font size is in 1024ths of a point - // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE ); + // C++11: Glib::ustring size = std::to_string( int(pt_size * PANGO_SCALE) ); std::ostringstream size_st; - size_st << pt_size * PANGO_SCALE; + size_st << int(pt_size * PANGO_SCALE); // Markup code expects integers - Glib::ustring markup = "" + phrase_escaped + ""; + Glib::ustring markup = "" + phrase_escaped + ""; preview_label.set_markup(markup.c_str()); } -- cgit v1.2.3 From 11bb6f3d4fedd1d22637f00a480dea54d505c23c Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 15 May 2014 23:07:31 +0200 Subject: make windows filedialog's code more portable for different mingw versions (failed on 64bit) (bzr r13380) --- src/ui/dialog/filedialogimpl-win32.cpp | 11 ++--------- src/ui/dialog/filedialogimpl-win32.h | 6 +++++- 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 9d91f5d56..1eeee0592 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -72,13 +72,6 @@ const unsigned long MaxPreviewFileSize = 10240; // kB #define IDC_SHOW_PREVIEW 1000 -// Windows 2000 version of OPENFILENAMEW -struct OPENFILENAMEEXW : public OPENFILENAMEW { - void * pvReserved; - DWORD dwReserved; - DWORD FlagsEx; -}; - struct Filter { gunichar2* name; @@ -483,7 +476,7 @@ void FileOpenDialogImplWin32::createFilterMenu() void FileOpenDialogImplWin32::GetOpenFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_mutex != NULL); @@ -1829,7 +1822,7 @@ void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring patt void FileSaveDialogImplWin32::GetSaveFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_main_loop != NULL); diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index a71ee1ad0..c523f041d 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -20,9 +20,13 @@ #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H # include #endif - #endif + #include "gc-core.h" + // define WINVER high enough so we get the correct OPENFILENAMEW size +#ifndef WINVER +#define WINVER 0x0500 +#endif #include #include "filedialogimpl-gtkmm.h" -- cgit v1.2.3 From 639540b57f19cce10e6b37df3475c252455a1b28 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 15 May 2014 23:08:12 +0200 Subject: make windows filedialog's code more portable for different mingw versions (failed on 64bit) (bzr r13341.1.26) --- src/ui/dialog/filedialogimpl-win32.cpp | 12 ++---------- src/ui/dialog/filedialogimpl-win32.h | 6 +++++- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 9d91f5d56..06153a2d8 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -72,13 +72,6 @@ const unsigned long MaxPreviewFileSize = 10240; // kB #define IDC_SHOW_PREVIEW 1000 -// Windows 2000 version of OPENFILENAMEW -struct OPENFILENAMEEXW : public OPENFILENAMEW { - void * pvReserved; - DWORD dwReserved; - DWORD FlagsEx; -}; - struct Filter { gunichar2* name; @@ -483,7 +476,7 @@ void FileOpenDialogImplWin32::createFilterMenu() void FileOpenDialogImplWin32::GetOpenFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_mutex != NULL); @@ -1829,7 +1822,7 @@ void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring patt void FileSaveDialogImplWin32::GetSaveFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_main_loop != NULL); @@ -1860,7 +1853,6 @@ void FileSaveDialogImplWin32::GetSaveFileName_thread() ofn.nFilterIndex = _filter_index; ofn.lpfnHook = GetSaveFileName_hookproc; ofn.lCustData = (LPARAM)this; - _result = GetSaveFileNameW(&ofn) != 0; g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count); diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index a71ee1ad0..c523f041d 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -20,9 +20,13 @@ #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H # include #endif - #endif + #include "gc-core.h" + // define WINVER high enough so we get the correct OPENFILENAMEW size +#ifndef WINVER +#define WINVER 0x0500 +#endif #include #include "filedialogimpl-gtkmm.h" -- cgit v1.2.3 From 2ddabce031c6c408688477544f9b16a28b7b9cb1 Mon Sep 17 00:00:00 2001 From: Fridrich Strba Date: Tue, 27 May 2014 12:35:54 +0200 Subject: Port inkscape to librevenge framework for WPG, CDR and VSD imports (bzr r13398.1.1) --- src/ui/dialog/symbols.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 8e0d085a4..0b048ed82 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -63,7 +63,7 @@ #ifdef WITH_LIBVISIO #include -#include +#include #endif #include "verbs.h" @@ -449,14 +449,16 @@ void SymbolsDialog::iconChanged() { // Read Visio stencil files SPDocument* read_vss( gchar* fullname, gchar* filename ) { - WPXFileStream input(fullname); + librevenge::RVNGFileStream input(fullname); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } - libvisio::VSDStringVector output; - if (!libvisio::VisioDocument::generateSVGStencils(&input, output)) { + librevenge::RVNGStringVector output; + librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); + + if (!libvisio::VisioDocument::parseStencils(&input, &generator)) { return NULL; } -- cgit v1.2.3 From 95033e5a510be941172977dc948f9c914180e359 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 1 Jun 2014 15:05:24 +0200 Subject: spellcheck.cpp: correct indenting. disable debug output. (bzr r13341.1.44) --- src/ui/dialog/spellcheck.cpp | 74 ++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index 8a4ddc57e..a887a7355 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -347,7 +347,7 @@ SpellCheck::init(SPDesktop *d) char *slashPos = strrchr(exeName, '\\'); if (slashPos) *slashPos = '\0'; - g_print ("%s\n", exeName); + //g_print ("Aspell prefix path: %s\n", exeName); #endif _stops = 0; @@ -356,54 +356,54 @@ SpellCheck::init(SPDesktop *d) #ifdef HAVE_ASPELL { - AspellConfig *config = new_aspell_config(); + AspellConfig *config = new_aspell_config(); #ifdef WIN32 - aspell_config_replace(config, "prefix", exeName); + aspell_config_replace(config, "prefix", exeName); #endif - aspell_config_replace(config, "lang", _lang.c_str()); - aspell_config_replace(config, "encoding", "UTF-8"); - AspellCanHaveError *ret = new_aspell_speller(config); - delete_aspell_config(config); - if (aspell_error(ret) != 0) { - g_warning("Error: %s\n", aspell_error_message(ret)); - delete_aspell_can_have_error(ret); - return false; - } - _speller = to_aspell_speller(ret); + aspell_config_replace(config, "lang", _lang.c_str()); + aspell_config_replace(config, "encoding", "UTF-8"); + AspellCanHaveError *ret = new_aspell_speller(config); + delete_aspell_config(config); + if (aspell_error(ret) != 0) { + g_warning("Error: %s\n", aspell_error_message(ret)); + delete_aspell_can_have_error(ret); + return false; + } + _speller = to_aspell_speller(ret); } if (_lang2 != "") { - AspellConfig *config = new_aspell_config(); + AspellConfig *config = new_aspell_config(); #ifdef WIN32 - aspell_config_replace(config, "prefix", exeName); + aspell_config_replace(config, "prefix", exeName); #endif - aspell_config_replace(config, "lang", _lang2.c_str()); - aspell_config_replace(config, "encoding", "UTF-8"); - AspellCanHaveError *ret = new_aspell_speller(config); - delete_aspell_config(config); - if (aspell_error(ret) != 0) { - g_warning("Error: %s\n", aspell_error_message(ret)); - delete_aspell_can_have_error(ret); - return false; - } - _speller2 = to_aspell_speller(ret); + aspell_config_replace(config, "lang", _lang2.c_str()); + aspell_config_replace(config, "encoding", "UTF-8"); + AspellCanHaveError *ret = new_aspell_speller(config); + delete_aspell_config(config); + if (aspell_error(ret) != 0) { + g_warning("Error: %s\n", aspell_error_message(ret)); + delete_aspell_can_have_error(ret); + return false; + } + _speller2 = to_aspell_speller(ret); } if (_lang3 != "") { - AspellConfig *config = new_aspell_config(); + AspellConfig *config = new_aspell_config(); #ifdef WIN32 - aspell_config_replace(config, "prefix", exeName); + aspell_config_replace(config, "prefix", exeName); #endif - aspell_config_replace(config, "lang", _lang3.c_str()); - aspell_config_replace(config, "encoding", "UTF-8"); - AspellCanHaveError *ret = new_aspell_speller(config); - delete_aspell_config(config); - if (aspell_error(ret) != 0) { - g_warning("Error: %s\n", aspell_error_message(ret)); - delete_aspell_can_have_error(ret); - return false; - } - _speller3 = to_aspell_speller(ret); + aspell_config_replace(config, "lang", _lang3.c_str()); + aspell_config_replace(config, "encoding", "UTF-8"); + AspellCanHaveError *ret = new_aspell_speller(config); + delete_aspell_config(config); + if (aspell_error(ret) != 0) { + g_warning("Error: %s\n", aspell_error_message(ret)); + delete_aspell_can_have_error(ret); + return false; + } + _speller3 = to_aspell_speller(ret); } #endif /* HAVE_ASPELL */ -- cgit v1.2.3 From cb625f9576e23e2232aafc93e5b1582336624425 Mon Sep 17 00:00:00 2001 From: Adib Taraben Date: Sat, 7 Jun 2014 00:08:03 +0200 Subject: revise email theadib (bzr r13410) --- src/ui/dialog/aboutbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 121773b6d..a66855b2a 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -442,7 +442,7 @@ void AboutBox::initStrings() { */ gchar const *allTranslators = "3ARRANO.com <3arrano@3arrano.com>, 2005.\n" -"Adib Taraben , 2004.\n" +"Adib Taraben , 2004.\n" "Alan Monfort , 2009-2010.\n" "Alastair McKinstry , 2000.\n" "Aleksandar Urošević , 2004-2006.\n" -- cgit v1.2.3 From 61a6f2cc2082528d4df3147c39d3e16d41388db4 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 09:30:53 +0200 Subject: Display symbols in document order. Fix typo in FlowSymbols.svg (bzr r13424) --- src/ui/dialog/symbols.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 8e0d085a4..0dfd915fe 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -613,6 +613,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) { GSList *l = NULL; l = symbols_in_doc_recursive (symbolDocument->getRoot(), l ); + l = g_slist_reverse( l ); return l; } -- cgit v1.2.3 From 5e1c70580e6d156716aba9e5dcc62a15a215da06 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 09:34:58 +0200 Subject: Display symbols in document order. (bzr r13341.1.58) --- src/ui/dialog/symbols.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 8e0d085a4..0dfd915fe 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -613,6 +613,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) { GSList *l = NULL; l = symbols_in_doc_recursive (symbolDocument->getRoot(), l ); + l = g_slist_reverse( l ); return l; } -- cgit v1.2.3 From ba2d7d753aec7f4c356d3fec1f07f79db5e56eec Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 18:06:01 +0200 Subject: Allow symbol zooming independent of icon screen size. (bzr r13425) --- src/ui/dialog/symbols.cpp | 72 +++++++++++++++++++++++++++++++++++++++-------- src/ui/dialog/symbols.h | 9 +++++- 2 files changed, 68 insertions(+), 13 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 0dfd915fe..c58df864c 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -219,25 +219,27 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : Gtk::Label* spacer = Gtk::manage(new Gtk::Label("")); tools->pack_start(* Gtk::manage(spacer)); - in_sizes = 2; // Default 32px + // Pack size (controls display area) + pack_size = 2; // Default 32px button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); - button->set_tooltip_text(_("Make Icons bigger by zooming in.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-more")))) ); + button->set_tooltip_text(_("Display more icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packmore)); tools->pack_start(* button, Gtk::PACK_SHRINK); button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); - button->set_tooltip_text(_("Make Icons smaller by zooming out.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-less")))) ); + button->set_tooltip_text(_("Display fewer icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packless)); tools->pack_start(* button, Gtk::PACK_SHRINK); + // Toggle scale to fit on/off fitSymbol = Gtk::manage(new Gtk::ToggleButton()); fitSymbol->add(*Gtk::manage(Glib::wrap( sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-fit")))) ); @@ -248,6 +250,28 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : fitSymbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild)); tools->pack_start(* fitSymbol, Gtk::PACK_SHRINK); + // Render size (scales symbols within display area) + scale_factor = 0; // Default 1:1 * pack_size/pack_size default + zoomOut = Gtk::manage(new Gtk::Button()); + zoomOut->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); + zoomOut->set_tooltip_text(_("Make symbols smaller by zooming out.")); + zoomOut->set_relief( Gtk::RELIEF_NONE ); + zoomOut->set_focus_on_click( false ); + zoomOut->set_sensitive( false ); + zoomOut->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + tools->pack_start(* zoomOut, Gtk::PACK_SHRINK); + + zoomIn = Gtk::manage(new Gtk::Button()); + zoomIn->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); + zoomIn->set_tooltip_text(_("Make symbols bigger by zooming in.")); + zoomIn->set_relief( Gtk::RELIEF_NONE ); + zoomIn->set_focus_on_click( false ); + zoomIn->set_sensitive( false ); + zoomIn->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + tools->pack_start(* zoomIn, Gtk::PACK_SHRINK); + ++row; /**********************************************************/ @@ -298,22 +322,44 @@ SymbolsDialog& SymbolsDialog::getInstance() return *new SymbolsDialog(); } +void SymbolsDialog::packless() { + if(pack_size < 4) { + pack_size++; + rebuild(); + } +} + +void SymbolsDialog::packmore() { + if(pack_size > 0) { + pack_size--; + rebuild(); + } +} + void SymbolsDialog::zoomin() { - if(in_sizes < 4) { - in_sizes++; + if(scale_factor < 4) { + scale_factor++; rebuild(); } } void SymbolsDialog::zoomout() { - if(in_sizes > 0) { - in_sizes--; + if(scale_factor > -8) { + scale_factor--; rebuild(); } } void SymbolsDialog::rebuild() { + if( fitSymbol->get_active() ) { + zoomIn->set_sensitive( false ); + zoomOut->set_sensitive( false ); + } else { + zoomIn->set_sensitive( true); + zoomOut->set_sensitive( true ); + } + store->clear(); Glib::ustring symbolSetString = symbolSet->get_active_text(); @@ -757,7 +803,7 @@ SymbolsDialog::draw_symbol(SPObject *symbol) previewDocument->ensureUpToDate(); SPItem *item = SP_ITEM(object_temp); - unsigned psize = SYMBOL_ICON_SIZES[in_sizes]; + unsigned psize = SYMBOL_ICON_SIZES[pack_size]; Glib::RefPtr pixbuf(NULL); // We could use cache here, but it doesn't really work with the structure @@ -779,6 +825,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol) if( fitSymbol->get_active() ) scale = psize / std::max(width, height); + else + scale = pow( 2.0, scale_factor/2.0 ) * psize / 32.0; pixbuf = Glib::wrap(render_pixbuf(renderDrawing, scale, *dbox, psize)); } diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h index 8021fb0c1..5dc1e3cad 100644 --- a/src/ui/dialog/symbols.h +++ b/src/ui/dialog/symbols.h @@ -65,6 +65,8 @@ private: static SymbolColumns *getColumns(); + void packless(); + void packmore(); void zoomin(); void zoomout(); void rebuild(); @@ -95,13 +97,18 @@ private: std::map symbolSets; // Index into sizes which is selected - int in_sizes; + int pack_size; + + // Scale factor + int scale_factor; Glib::RefPtr store; Gtk::ComboBoxText* symbolSet; Gtk::IconView* iconView; Gtk::Button* addSymbol; Gtk::Button* removeSymbol; + Gtk::Button* zoomIn; + Gtk::Button* zoomOut; Gtk::ToggleButton* fitSymbol; void setTargetDesktop(SPDesktop *desktop); -- cgit v1.2.3 From 5390e245e922648d989bfa10e0613e2f588a9cc7 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 18:11:54 +0200 Subject: Allow symbol zooming independent of icon screen size. (bzr r13341.1.60) --- src/ui/dialog/symbols.cpp | 72 +++++++++++++++++++++++++++++++++++++++-------- src/ui/dialog/symbols.h | 9 +++++- 2 files changed, 68 insertions(+), 13 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 0dfd915fe..c58df864c 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -219,25 +219,27 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : Gtk::Label* spacer = Gtk::manage(new Gtk::Label("")); tools->pack_start(* Gtk::manage(spacer)); - in_sizes = 2; // Default 32px + // Pack size (controls display area) + pack_size = 2; // Default 32px button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); - button->set_tooltip_text(_("Make Icons bigger by zooming in.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-more")))) ); + button->set_tooltip_text(_("Display more icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packmore)); tools->pack_start(* button, Gtk::PACK_SHRINK); button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); - button->set_tooltip_text(_("Make Icons smaller by zooming out.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-less")))) ); + button->set_tooltip_text(_("Display fewer icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packless)); tools->pack_start(* button, Gtk::PACK_SHRINK); + // Toggle scale to fit on/off fitSymbol = Gtk::manage(new Gtk::ToggleButton()); fitSymbol->add(*Gtk::manage(Glib::wrap( sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-fit")))) ); @@ -248,6 +250,28 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : fitSymbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild)); tools->pack_start(* fitSymbol, Gtk::PACK_SHRINK); + // Render size (scales symbols within display area) + scale_factor = 0; // Default 1:1 * pack_size/pack_size default + zoomOut = Gtk::manage(new Gtk::Button()); + zoomOut->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); + zoomOut->set_tooltip_text(_("Make symbols smaller by zooming out.")); + zoomOut->set_relief( Gtk::RELIEF_NONE ); + zoomOut->set_focus_on_click( false ); + zoomOut->set_sensitive( false ); + zoomOut->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + tools->pack_start(* zoomOut, Gtk::PACK_SHRINK); + + zoomIn = Gtk::manage(new Gtk::Button()); + zoomIn->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); + zoomIn->set_tooltip_text(_("Make symbols bigger by zooming in.")); + zoomIn->set_relief( Gtk::RELIEF_NONE ); + zoomIn->set_focus_on_click( false ); + zoomIn->set_sensitive( false ); + zoomIn->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + tools->pack_start(* zoomIn, Gtk::PACK_SHRINK); + ++row; /**********************************************************/ @@ -298,22 +322,44 @@ SymbolsDialog& SymbolsDialog::getInstance() return *new SymbolsDialog(); } +void SymbolsDialog::packless() { + if(pack_size < 4) { + pack_size++; + rebuild(); + } +} + +void SymbolsDialog::packmore() { + if(pack_size > 0) { + pack_size--; + rebuild(); + } +} + void SymbolsDialog::zoomin() { - if(in_sizes < 4) { - in_sizes++; + if(scale_factor < 4) { + scale_factor++; rebuild(); } } void SymbolsDialog::zoomout() { - if(in_sizes > 0) { - in_sizes--; + if(scale_factor > -8) { + scale_factor--; rebuild(); } } void SymbolsDialog::rebuild() { + if( fitSymbol->get_active() ) { + zoomIn->set_sensitive( false ); + zoomOut->set_sensitive( false ); + } else { + zoomIn->set_sensitive( true); + zoomOut->set_sensitive( true ); + } + store->clear(); Glib::ustring symbolSetString = symbolSet->get_active_text(); @@ -757,7 +803,7 @@ SymbolsDialog::draw_symbol(SPObject *symbol) previewDocument->ensureUpToDate(); SPItem *item = SP_ITEM(object_temp); - unsigned psize = SYMBOL_ICON_SIZES[in_sizes]; + unsigned psize = SYMBOL_ICON_SIZES[pack_size]; Glib::RefPtr pixbuf(NULL); // We could use cache here, but it doesn't really work with the structure @@ -779,6 +825,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol) if( fitSymbol->get_active() ) scale = psize / std::max(width, height); + else + scale = pow( 2.0, scale_factor/2.0 ) * psize / 32.0; pixbuf = Glib::wrap(render_pixbuf(renderDrawing, scale, *dbox, psize)); } diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h index 8021fb0c1..5dc1e3cad 100644 --- a/src/ui/dialog/symbols.h +++ b/src/ui/dialog/symbols.h @@ -65,6 +65,8 @@ private: static SymbolColumns *getColumns(); + void packless(); + void packmore(); void zoomin(); void zoomout(); void rebuild(); @@ -95,13 +97,18 @@ private: std::map symbolSets; // Index into sizes which is selected - int in_sizes; + int pack_size; + + // Scale factor + int scale_factor; Glib::RefPtr store; Gtk::ComboBoxText* symbolSet; Gtk::IconView* iconView; Gtk::Button* addSymbol; Gtk::Button* removeSymbol; + Gtk::Button* zoomIn; + Gtk::Button* zoomOut; Gtk::ToggleButton* fitSymbol; void setTargetDesktop(SPDesktop *desktop); -- cgit v1.2.3 From eb4d7e1225a2e1e5a5d1da8d0ab784632bc77291 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 14 Jun 2014 14:51:11 -0400 Subject: Add clip group option from Ponyscape (bzr r13090.1.83) --- src/ui/dialog/objects.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 85583a0e7..2d558daae 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -106,7 +106,7 @@ enum { BUTTON_LOCK_ALL, BUTTON_UNLOCK_ALL, BUTTON_SETCLIP, -// BUTTON_CLIPGROUP, + BUTTON_CLIPGROUP, // BUTTON_SETINVCLIP, BUTTON_UNSETCLIP, BUTTON_SETMASK, @@ -269,7 +269,7 @@ Gtk::MenuItem& ObjectsPanel::_addPopupItem( SPDesktop *desktop, unsigned int cod } if ( action ) { - label = action->name; + // label = action->name; } } } @@ -1257,6 +1257,10 @@ bool ObjectsPanel::_executeAction() _fireAction( SP_VERB_LAYER_UNLOCK_ALL ); } break; + case BUTTON_CLIPGROUP: + { + _fireAction ( SP_VERB_OBJECT_CREATE_CLIP_GROUP ); + } case BUTTON_SETCLIP: { _fireAction( SP_VERB_OBJECT_SET_CLIPPATH ); @@ -1935,8 +1939,8 @@ ObjectsPanel::ObjectsPanel() : _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_CLIPPATH, 0, "Set Clip", (int)BUTTON_SETCLIP ) ); - //not implemented - //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) ); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) ); //will never be implemented //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_INVERSE_CLIPPATH, 0, "Set Inverse Clip", (int)BUTTON_SETINVCLIP ) ); -- cgit v1.2.3 From f1305982b84adfe04cdeb2686c3b1d7ed3a37bc7 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 25 Jun 2014 23:05:33 +0200 Subject: fix windows build (gtk3) partly. broken because of windows.h poluting namespace with "interface" struct name. (bzr r13341.1.68) --- src/ui/dialog/filedialogimpl-win32.h | 3 ++- src/ui/dialog/print.cpp | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index c523f041d..f77249abd 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -22,13 +22,14 @@ #endif #endif +#include "filedialogimpl-gtkmm.h" + #include "gc-core.h" // define WINVER high enough so we get the correct OPENFILENAMEW size #ifndef WINVER #define WINVER 0x0500 #endif #include -#include "filedialogimpl-gtkmm.h" namespace Inkscape diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 03ac9dc64..459e64041 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -13,10 +13,6 @@ #ifdef HAVE_CONFIG_H # include #endif -#ifdef WIN32 -#include -#include -#endif #include "print.h" #include @@ -33,6 +29,11 @@ #include +#ifdef WIN32 +#include +#include +#endif + static void draw_page( #ifdef WIN32 -- cgit v1.2.3 From 96fec2043bbac0293fb30486d6c6a8650190abff Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 29 Jun 2014 09:21:44 +0200 Subject: Layers. Fix for Bug #1326131 (Can't delete layer from context menu). Fixed bugs: - https://launchpad.net/bugs/1326131 (bzr r13442) --- src/ui/dialog/layers.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index b5dac0595..65351cb68 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -926,9 +926,8 @@ LayersPanel::LayersPanel() : // ------------------------------------------------------- { - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); @@ -944,9 +943,14 @@ LayersPanel::LayersPanel() : _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); - _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("go-up"), "Up", (int)BUTTON_UP ) ); - _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("go-down"), "Down", (int)BUTTON_DOWN ) ); + _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("layer-raise"), "Up", (int)BUTTON_UP ) ); + _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("layer-lower"), "Down", (int)BUTTON_DOWN ) ); + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DELETE, 0, "Delete", (int)BUTTON_DELETE ) ); + _popupMenu.show_all_children(); } // ------------------------------------------------------- -- cgit v1.2.3 From 371f45365a6b6ea42d17c8ea33cc0072f318967e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Jul 2014 13:14:35 +0200 Subject: Add LPE fillet-chamfer (bzr r13341.1.74) --- src/ui/dialog/Makefile_insert | 2 + src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 257 ++++++++++++++++++++++++ src/ui/dialog/lpe-fillet-chamfer-properties.h | 112 +++++++++++ 3 files changed, 371 insertions(+) create mode 100644 src/ui/dialog/lpe-fillet-chamfer-properties.cpp create mode 100644 src/ui/dialog/lpe-fillet-chamfer-properties.h (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index daa8aea22..1bd939707 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -114,4 +114,6 @@ ink_common_sources += \ ui/dialog/undo-history.h \ ui/dialog/xml-tree.cpp \ ui/dialog/xml-tree.h \ + ui/dialog/lpe-fillet-chamfer-properties.cpp \ + ui/dialog/lpe-fillet-chamfer-properties.h \ $(inkboard_dialogs) diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp new file mode 100644 index 000000000..a68c7ee08 --- /dev/null +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -0,0 +1,257 @@ +/** + * From the code of Liam P.White from his Power Stroke Knot dialog + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if GLIBMM_DISABLE_DEPRECATED &&HAVE_GLIBMM_THREADS_H +#include +#endif + +#include "lpe-fillet-chamfer-properties.h" +#include +#include +#include +#include +#include "inkscape.h" +#include "desktop.h" +#include "document.h" +#include "document-undo.h" +#include "layer-manager.h" +#include "message-stack.h" +#include "desktop-handles.h" +#include "sp-object.h" +#include "sp-item.h" +#include "verbs.h" +#include "selection.h" +#include "selection-chemistry.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +#include +#include +#include "util/units.h" + +//#include "event-context.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() + : _desktop(NULL), _knotpoint(NULL), _position_visible(false) +{ + Gtk::Box *mainVBox = get_vbox(); + mainVBox->set_homogeneous(false); + _layout_table.set_spacings(4); + _layout_table.resize(2, 2); + + // Layer name widgets + _fillet_chamfer_position_entry.set_activates_default(true); + _fillet_chamfer_position_label.set_label(_("Radius (pixels):")); + _fillet_chamfer_position_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_fillet_chamfer_position_label, 0, 1, 0, 1, Gtk::FILL, + Gtk::FILL); + _layout_table.attach(_fillet_chamfer_position_entry, 1, 2, 0, 1, + Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + _fillet_chamfer_type_fillet.set_label(_("Fillet")); + _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); + _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_chamfer.set_label(_("Chamfer")); + _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_double_chamfer.set_label(_("Double chamfer")); + _fillet_chamfer_type_double_chamfer.set_group(_fillet_chamfer_type_group); + + mainVBox->pack_start(_layout_table, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_double_chamfer, true, true, 4); + + // Buttons + _close_button.set_use_stock(true); + _close_button.set_label(Gtk::Stock::CANCEL.id); + _close_button.set_can_default(); + + _apply_button.set_use_underline(true); + _apply_button.set_can_default(); + + _close_button.signal_clicked() + .connect(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_close)); + _apply_button.signal_clicked() + .connect(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_apply)); + + signal_delete_event().connect(sigc::bind_return( + sigc::hide(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_close)), + true)); + + add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); + add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); + + _apply_button.grab_default(); + + show_all_children(); + + set_focus(_fillet_chamfer_position_entry); +} + +FilletChamferPropertiesDialog::~FilletChamferPropertiesDialog() +{ + + _setDesktop(NULL); +} + +void FilletChamferPropertiesDialog::showDialog( + SPDesktop *desktop, Geom::Point knotpoint, + const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt, + const gchar *unit) +{ + FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog(); + + dialog->_setDesktop(desktop); + dialog->_setUnit(unit); + dialog->_setKnotPoint(knotpoint); + dialog->_setPt(pt); + + dialog->set_title(_("Modify Fillet-Chamfer")); + dialog->_apply_button.set_label(_("_Modify")); + + dialog->set_modal(true); + desktop->setWindowTransient(dialog->gobj()); + dialog->property_destroy_with_parent() = true; + + dialog->show(); + dialog->present(); +} + +void FilletChamferPropertiesDialog::_apply() +{ + std::istringstream i_pos(_fillet_chamfer_position_entry.get_text()); + double d_pos, d_width; + if (i_pos >> d_pos) { + if (_fillet_chamfer_type_fillet.get_active() == true) { + d_width = 1; + } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { + d_width = 2; + } else if (_fillet_chamfer_type_chamfer.get_active() == true) { + d_width = 3; + } else { + d_width = 4; + } + if (_flexible) { + if (d_pos > 99.99999 || d_pos < 0) { + d_pos = 0; + } + d_pos = _index + (d_pos / 100); + } else { + d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, "px"); + d_pos = d_pos * -1; + } + _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); + } + _close(); +} + +void FilletChamferPropertiesDialog::_close() +{ + _setDesktop(NULL); + destroy_(); + Glib::signal_idle().connect( + sigc::bind_return( + sigc::bind(sigc::ptr_fun(&::operator delete), this), + false + ) + ); +} + +bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey *event) +{ + return false; +} + +void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event) +{ + if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) { + _apply(); + } +} + +void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) +{ + double position; + if (knotpoint.x() > 0) { + double intpart; + position = modf(knotpoint[Geom::X], &intpart) * 100; + _flexible = true; + _index = intpart; + _fillet_chamfer_position_label.set_label(_("Position (%):")); + } else { + _flexible = false; + std::string posConcat = + std::string(_("Position (")) + std::string(unit) + std::string(")"); + _fillet_chamfer_position_label.set_label(_(posConcat.c_str())); + position = knotpoint[Geom::X] * -1; + position = Inkscape::Util::Quantity::convert(position, "px", unit); + } + std::ostringstream s; + s.imbue(std::locale::classic()); + s << position; + _fillet_chamfer_position_entry.set_text(s.str()); + if (knotpoint.y() == 1) { + _fillet_chamfer_type_fillet.set_active(true); + } else if (knotpoint.y() == 2) { + _fillet_chamfer_type_inverse_fillet.set_active(true); + } else if (knotpoint.y() == 3) { + _fillet_chamfer_type_chamfer.set_active(true); + } else if (knotpoint.y() == 1) { + _fillet_chamfer_type_double_chamfer.set_active(true); + } +} + +void FilletChamferPropertiesDialog::_setPt( + const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt) +{ + _knotpoint = const_cast< + Inkscape::LivePathEffect::FilletChamferPointArrayParamKnotHolderEntity *>( + pt); +} + +void FilletChamferPropertiesDialog::_setUnit(const gchar *abbr) +{ + unit = abbr; +} + +void FilletChamferPropertiesDialog::_setDesktop(SPDesktop *desktop) +{ + if (desktop) { + Inkscape::GC::anchor(desktop); + } + if (_desktop) { + Inkscape::GC::release(_desktop); + } + _desktop = desktop; +} + +} // namespace +} // namespace +} // namespace + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: +// filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 +// : diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h new file mode 100644 index 000000000..a07b5ab66 --- /dev/null +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -0,0 +1,112 @@ +/** + * + * From the code of Liam P.White from his Power Stroke Knot dialog + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H +#define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H + +#include <2geom/point.h> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "live_effects/parameter/filletchamferpointarray.h" + +class SPDesktop; + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +class FilletChamferPropertiesDialog : public Gtk::Dialog { +public: + FilletChamferPropertiesDialog(); + virtual ~FilletChamferPropertiesDialog(); + + Glib::ustring getName() const { + return "LayerPropertiesDialog"; + } + + static void showDialog(SPDesktop *desktop, Geom::Point knotpoint, + const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt, + const gchar *unit); + +protected: + + SPDesktop *_desktop; + Inkscape::LivePathEffect::FilletChamferPointArrayParamKnotHolderEntity * + _knotpoint; + + Gtk::Label _fillet_chamfer_position_label; + Gtk::Entry _fillet_chamfer_position_entry; + Gtk::RadioButton::Group _fillet_chamfer_type_group; + Gtk::RadioButton _fillet_chamfer_type_fillet; + Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; + Gtk::RadioButton _fillet_chamfer_type_chamfer; + Gtk::RadioButton _fillet_chamfer_type_double_chamfer; + + Gtk::Table _layout_table; + bool _position_visible; + double _index; + + Gtk::Button _close_button; + Gtk::Button _apply_button; + + sigc::connection _destroy_connection; + + static FilletChamferPropertiesDialog &_instance() { + static FilletChamferPropertiesDialog instance; + return instance; + } + + void _setDesktop(SPDesktop *desktop); + void _setPt(const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt); + void _setUnit(const gchar *abbr); + void _apply(); + void _close(); + bool _flexible; + const gchar *unit; + void _setKnotPoint(Geom::Point knotpoint); + void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); + + bool _handleKeyEvent(GdkEventKey *event); + void _handleButtonEvent(GdkEventButton *event); + + friend class Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity; + +private: + FilletChamferPropertiesDialog( + FilletChamferPropertiesDialog const &); // no copy + FilletChamferPropertiesDialog &operator=( + FilletChamferPropertiesDialog const &); // no assign +}; + +} // namespace +} // namespace +} // namespace + +#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: +// filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 +// : -- cgit v1.2.3 From 962ef8a02c2dbaf2049c1951ec8953ba885f9e19 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 5 Jul 2014 12:01:13 -0400 Subject: Fix FTBFS gtk3 & make check (bzr r13341.1.78) --- src/ui/dialog/lpe-fillet-chamfer-properties.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index a07b5ab66..d3e859bff 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -9,15 +9,7 @@ #define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H #include <2geom/point.h> -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include "live_effects/parameter/filletchamferpointarray.h" class SPDesktop; -- cgit v1.2.3 From 3c71759c0b922e85dbbbffe92ca31cc000d4eced Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Fri, 11 Jul 2014 18:26:18 -0400 Subject: scale tiled clones to document units (Bug 1288860) Fixed bugs: - https://launchpad.net/bugs/1288860 (bzr r13451) --- src/ui/dialog/clonetiler.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index fb131d8da..e5f18216c 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -2242,6 +2242,8 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) clonetiler_remove (NULL, dlg, false); + double scale_units = Inkscape::Util::Quantity::convert(1, "px", sp_desktop_document(desktop)->getDefaultUnit()); + double shiftx_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_i", 0, -10000, 10000); double shifty_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_i", 0, -10000, 10000); double shiftx_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_j", 0, -10000, 10000); @@ -2311,8 +2313,8 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) int jmax = prefs->getInt(prefs_path + "jmax", 2); bool fillrect = prefs->getBool(prefs_path + "fillrect"); - double fillwidth = prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6); - double fillheight = prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6); + double fillwidth = scale_units*prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6); + double fillheight = scale_units*prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6); bool dotrace = prefs->getBool(prefs_path + "dotrace"); int pick = prefs->getInt(prefs_path + "pick"); @@ -2358,11 +2360,11 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX ); Geom::OptRect r = item->documentBounds(bbox_type); if (r) { - w = r->dimensions()[Geom::X]; - h = r->dimensions()[Geom::Y]; - x0 = r->min()[Geom::X]; - y0 = r->min()[Geom::Y]; - center = desktop->dt2doc(item->getCenter()); + w = scale_units*r->dimensions()[Geom::X]; + h = scale_units*r->dimensions()[Geom::Y]; + x0 = scale_units*r->min()[Geom::X]; + y0 = scale_units*r->min()[Geom::Y]; + center = scale_units*desktop->dt2doc(item->getCenter()); sp_repr_set_svg_double(obj_repr, "inkscape:tile-cx", center[Geom::X]); sp_repr_set_svg_double(obj_repr, "inkscape:tile-cy", center[Geom::Y]); @@ -2578,7 +2580,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) Geom::Point new_center; bool center_set = false; if (obj_repr->attribute("inkscape:transform-center-x") || obj_repr->attribute("inkscape:transform-center-y")) { - new_center = desktop->dt2doc(item->getCenter()) * t; + new_center = scale_units*desktop->dt2doc(item->getCenter()) * t; center_set = true; } -- cgit v1.2.3 From d7c36cd293ee35f53a5b47f2795b061888d4f79b Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 22 Jul 2014 21:16:52 +0200 Subject: Fixed some logic errors; clang warnings. (bzr r13460) --- src/ui/dialog/template-widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index ef91962d4..9758b35ac 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -120,7 +120,7 @@ void TemplateWidget::_displayTemplateDetails() if (_current_template.long_description != "") message += _("Description: ") + _current_template.long_description + "\n\n"; - if (~_current_template.keywords.empty()){ + if (!_current_template.keywords.empty()){ message += _("Keywords: "); for (std::set::iterator it = _current_template.keywords.begin(); it != _current_template.keywords.end(); ++it) message += *it + " "; -- cgit v1.2.3 From 964d747265af3f80ed83a54b444ed5ae200a441d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 26 Jul 2014 11:50:39 -0400 Subject: Fix for crash regression 1348927 -- dialogs that are shown but have not been presented are buggy Fixed bugs: - https://launchpad.net/bugs/1348927 (bzr r13471) --- src/ui/dialog/dialog-manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index d427e3590..7e69e439a 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -251,7 +251,7 @@ void DialogManager::showDialog(gchar const *name, bool grabfocus) { /** * Shows the named dialog, creating it if necessary. */ -void DialogManager::showDialog(GQuark name, bool grabfocus) { +void DialogManager::showDialog(GQuark name, bool /*grabfocus*/) { bool wantTiming = Inkscape::Preferences::get()->getBool("/dialogs/debug/trackAppear", false); GTimer *timer = (wantTiming) ? g_timer_new() : 0; // if needed, must be created/started before getDialog() Dialog *dialog = getDialog(name); @@ -262,8 +262,8 @@ void DialogManager::showDialog(GQuark name, bool grabfocus) { tracker->setAutodelete(true); timer = 0; } - if (grabfocus) - dialog->present(); + // should check for grabfocus, but lp:1348927 prevents it + dialog->present(); } if ( timer ) { -- cgit v1.2.3 From 553293740817862cb756c770f6bee01dd00089bf Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Jul 2014 23:48:41 +0200 Subject: fix crash bug (reported by su_v on IRC) related to removing color profiles (bzr r13481) --- src/ui/dialog/document-properties.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 2674efc1e..9141b2268 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -596,6 +596,7 @@ void DocumentProperties::removeSelectedProfile(){ //XML Tree being used directly here while it shouldn't be. sp_repr_unparent(obj->getRepr()); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_COLOR_PROFILE, _("Remove linked color profile")); + break; // removing the color profile likely invalidates part of the traversed list, stop traversing here. } current = g_slist_next(current); } -- cgit v1.2.3 From 5a4eae28b6bd036a3ba87fdf90f8560cc1ca5c41 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Thu, 7 Aug 2014 13:43:16 -0400 Subject: refresh clip path when editing in XML editor (Bug 1349018) Fixed bugs: - https://launchpad.net/bugs/1349018 (bzr r13502) --- src/ui/dialog/xml-tree.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 55d0aff09..c87e42633 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -1033,6 +1033,7 @@ void XmlTree::cmd_set_attr() updated->updateRepr(); } + reinterpret_cast(current_desktop->currentLayer())->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); DocumentUndo::done(current_document, SP_VERB_DIALOG_XML_EDITOR, _("Change attribute")); -- cgit v1.2.3 From c73ebf3c732e19f665de2d490a915eabf425905e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 13 Aug 2014 08:24:04 +0200 Subject: Printing. Fix for Bug #264831 (Print settings not persistent). Printing. Fix for Bug #508529 (Printing rastered image offsets the page). Fixed bugs: - https://launchpad.net/bugs/264831 - https://launchpad.net/bugs/508529 (bzr r13509) --- src/ui/dialog/print.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 03ac9dc64..4d8d512df 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -18,6 +18,7 @@ #include #endif +#include "preferences.h" #include "print.h" #include @@ -44,14 +45,18 @@ static void draw_page( gint /*page_nr*/, gpointer user_data) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); struct workaround_gtkmm *junk = (struct workaround_gtkmm*)user_data; //printf("%s %d\n",__FUNCTION__, page_nr); if (junk->_tab->as_bitmap()) { // Render as exported PNG + prefs->setBool("/dialogs/printing/asbitmap", true); gdouble width = (junk->_doc)->getWidth().value("px"); gdouble height = (junk->_doc)->getHeight().value("px"); gdouble dpi = junk->_tab->bitmap_dpi(); + prefs->setDouble("/dialogs/printing/dpi", dpi); + std::string tmp_png; std::string tmp_base = "inkscape-print-png-XXXXXX"; @@ -92,7 +97,7 @@ static void draw_page( cairo_get_matrix(cr, &m); cairo_scale(cr, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi); // FIXME: why is the origin offset?? - cairo_set_source_surface(cr, png->cobj(), -16.0, -16.0); + cairo_set_source_surface(cr, png->cobj(), 0, 0); cairo_paint(cr); cairo_set_matrix(cr, &m); } @@ -106,6 +111,7 @@ static void draw_page( } else { // Render as vectors + prefs->setBool("/dialogs/printing/asbitmap", false); Inkscape::Extension::Internal::CairoRenderer renderer; Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext(); -- cgit v1.2.3 From 9d5529ca1b43a144f825fc58d6aa37911a4ac7f6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 13 Aug 2014 09:12:45 -0400 Subject: Fix build (bzr r13510) --- src/ui/dialog/print.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 4d8d512df..ed39ebb32 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -13,14 +13,16 @@ #ifdef HAVE_CONFIG_H # include #endif + #ifdef WIN32 #include #include #endif +#include + #include "preferences.h" #include "print.h" -#include #include "extension/internal/cairo-render-context.h" #include "extension/internal/cairo-renderer.h" -- cgit v1.2.3 From 9fdd8f25ee0f04d337864c7ec5e3216dae727e3c Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Thu, 14 Aug 2014 22:09:10 +0200 Subject: Fix some transformation center regressions, related to the viewbox/units changes (bzr r13512) --- src/ui/dialog/document-properties.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 9141b2268..4e4616724 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -45,6 +45,7 @@ #include "widgets/icon.h" #include "xml/node-event-vector.h" #include "xml/repr.h" +#include // std::min #include "rdf.h" #include "ui/widget/entity-entry.h" @@ -1735,9 +1736,9 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); - gdouble viewscale = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); - if (doc->getHeight().value("px")/doc->getRoot()->viewBox.height() < viewscale) - viewscale = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); + gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); + gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); + gdouble viewscale = std::min(viewscale_h, viewscale_w); gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, -- cgit v1.2.3 From 940176d1a9959328f186cb21c22bf43d4cfed4fc Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 15 Aug 2014 08:43:45 +0200 Subject: Preferences. Fix for Bug #184499 (Inkscape Preferences dialog does not remember tabs/pages). Fixed bugs: - https://launchpad.net/bugs/184499 (bzr r13517) --- src/ui/dialog/inkscape-preferences.cpp | 8 ++++++-- src/ui/dialog/inkscape-preferences.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index f1a29e971..5d065dc60 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -76,7 +76,8 @@ InkscapePreferences::InkscapePreferences() : UI::Widget::Panel ("", "/dialogs/preferences", SP_VERB_DIALOG_DISPLAY), _max_dialog_width(0), _max_dialog_height(0), - _current_page(0) + _current_page(0), + _init(true) { //get the width of a spinbutton Inkscape::UI::Widget::SpinButton* sb = new Inkscape::UI::Widget::SpinButton; @@ -2000,6 +2001,7 @@ bool InkscapePreferences::PresentPage(const Gtk::TreeModel::iterator& iter) Gtk::TreeModel::Row row = *iter; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int desired_page = prefs->getInt("/dialogs/preferences/page", 0); + _init = false; if (desired_page == row[_page_list_columns._col_id]) { if (desired_page >= PREFS_PAGE_TOOLS && desired_page <= PREFS_PAGE_TOOLS_CONNECTOR) @@ -2049,7 +2051,9 @@ void InkscapePreferences::on_pagelist_selection_changed() Gtk::TreeModel::Row row = *iter; _current_page = row[_page_list_columns._col_page]; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); + if (!_init) { + prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); + } _page_title.set_markup("" + row[_page_list_columns._col_name] + ""); _page_frame.add(*_current_page); _current_page->show(); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 1c2151605..9f37626ed 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -532,6 +532,7 @@ private: InkscapePreferences(); InkscapePreferences(InkscapePreferences const &d); InkscapePreferences operator=(InkscapePreferences const &d); + bool _init; }; } // namespace Dialog -- cgit v1.2.3 From 2a2db8af11c2e518bd7bfe520e2f88a7e439d939 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 16 Aug 2014 22:47:53 -0400 Subject: Merge in font-speedup branch to improve launch times (bzr r13341.1.140) --- src/ui/dialog/text-edit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index c1ebb32e0..e44809c65 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -344,9 +344,9 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - // This is done for us by text-toolbar. No need to do it twice. - // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); - // fontlister->selection_update(); + // This is normally done for us by text-toolbar but only when we are in text editing context + fontlister->update_font_list(sp_desktop_document(this->desktop)); + fontlister->selection_update(); Glib::ustring fontspec = fontlister->get_fontspec(); -- cgit v1.2.3 From 282a7ce3f988e792545c19854b5f55cff1291cbe Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 13:44:01 -0400 Subject: Fix gtk3 crash when using "close" button Fixed bugs: - https://launchpad.net/bugs/1090936 (bzr r13341.1.143) --- src/ui/dialog/dialog.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 645294bb5..22ba0b6fb 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -317,20 +317,7 @@ void Dialog::_apply() void Dialog::_close() { - GtkWidget *dlg = GTK_WIDGET(_behavior->gobj()); - - GdkEventAny event; - event.type = GDK_DELETE; - event.window = gtk_widget_get_window(dlg); - event.send_event = TRUE; - - if (event.window) - g_object_ref(G_OBJECT(event.window)); - - gtk_main_do_event ((GdkEvent*)&event); - - if (event.window) - g_object_unref(G_OBJECT(event.window)); + _behavior->hide(); } void Dialog::_defocus() -- cgit v1.2.3 From 2a04905eb339f85263babd7d668dd43f072f75b3 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 14:13:20 -0400 Subject: Fix accidental regression in previous commit (bzr r13341.1.144) --- src/ui/dialog/dialog.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 22ba0b6fb..f2c63ed8d 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -318,6 +318,7 @@ void Dialog::_apply() void Dialog::_close() { _behavior->hide(); + _onDeleteEvent(NULL); } void Dialog::_defocus() -- cgit v1.2.3 From 62339f48161baf01b49d331b7c31ab9d8fb64ec6 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 23 Aug 2014 14:54:39 +0200 Subject: fix Windows 64-bit build (bzr r13341.1.154) --- src/ui/dialog/print.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index ed39ebb32..a015d28f9 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -14,13 +14,13 @@ # include #endif +#include + #ifdef WIN32 #include #include #endif -#include - #include "preferences.h" #include "print.h" -- cgit v1.2.3 From e469f1f4eb04e7cc1401c6679a41c217287ae888 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 23 Aug 2014 15:17:43 +0200 Subject: fix Windows 64-bit build (bzr r13531) --- src/ui/dialog/print.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index ed39ebb32..a015d28f9 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -14,13 +14,13 @@ # include #endif +#include + #ifdef WIN32 #include #include #endif -#include - #include "preferences.h" #include "print.h" -- cgit v1.2.3 From fd314c7cbec965ec702c3ea80e1e48d41302d687 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 21:30:32 +0100 Subject: Fix deprecated VBox use (bzr r13341.1.165) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 2 +- src/ui/dialog/new-from-template.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index a68c7ee08..c1e16495b 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -44,7 +44,7 @@ namespace Dialogs { FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() : _desktop(NULL), _knotpoint(NULL), _position_visible(false) { - Gtk::Box *mainVBox = get_vbox(); + Gtk::Box *mainVBox = get_content_area(); mainVBox->set_homogeneous(false); _layout_table.set_spacings(4); _layout_table.resize(2, 2); diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp index f326bb3ee..5ce96d10f 100644 --- a/src/ui/dialog/new-from-template.cpp +++ b/src/ui/dialog/new-from-template.cpp @@ -26,11 +26,11 @@ NewFromTemplate::NewFromTemplate() set_title(_("New From Template")); resize(400, 400); - get_vbox()->pack_start(_main_widget); + get_content_area()->pack_start(_main_widget); Gtk::Alignment *align; align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); - get_vbox()->pack_end(*align, Gtk::PACK_SHRINK); + get_content_area()->pack_end(*align, Gtk::PACK_SHRINK); align->set_padding(0, 0, 0, 15); align->add(_create_template_button); -- cgit v1.2.3 From 6388fa1d00b2731feb0b9eedd03c2751d2efee84 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 22:35:35 +0100 Subject: Migrate more widgets to Gtk::Grid (bzr r13341.1.169) --- src/ui/dialog/grid-arrange-tab.h | 8 +++++--- src/ui/dialog/polar-arrange-tab.cpp | 32 ++++++++++++++++++++++++++++++++ src/ui/dialog/polar-arrange-tab.h | 19 ++++++++++++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/grid-arrange-tab.h b/src/ui/dialog/grid-arrange-tab.h index 9d6700b39..a137d1694 100644 --- a/src/ui/dialog/grid-arrange-tab.h +++ b/src/ui/dialog/grid-arrange-tab.h @@ -17,14 +17,16 @@ #ifndef INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H #define INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H -#include - +#include "ui/widget/scalar-unit.h" #include "ui/dialog/arrange-tab.h" #include "ui/widget/anchor-selector.h" -#include "ui/widget/scalar-unit.h" #include "ui/widget/spinbutton.h" +#include +#include +#include + namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp index a00b8fc02..80579c9d3 100644 --- a/src/ui/dialog/polar-arrange-tab.cpp +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -25,6 +25,7 @@ #include "desktop.h" #include "sp-ellipse.h" #include "sp-item-transform.h" +#include namespace Inkscape { namespace UI { @@ -32,7 +33,11 @@ namespace Dialog { PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) : parent(parent_), +#if WITH_GTKMM_3_0 + parametersTable(), +#else parametersTable(3, 3, false), +#endif centerY("", "Y coordinate of the center", UNIT_TYPE_LINEAR), centerX("", "X coordinate of the center", centerY), radiusY("", "Y coordinate of the radius", UNIT_TYPE_LINEAR), @@ -76,7 +81,11 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) pack_start(arrangeOnParametersRadio, false, false); centerLabel.set_text(_("Center X/Y:")); +#if WITH_GTKMM_3_0 + parametersTable.attach(centerLabel, 0, 0, 1, 1); +#else parametersTable.attach(centerLabel, 0, 1, 0, 1, Gtk::FILL); +#endif centerX.setDigits(2); centerX.setIncrements(0.2, 0); centerX.setRange(-10000, 10000); @@ -85,11 +94,20 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) centerY.setIncrements(0.2, 0); centerY.setRange(-10000, 10000); centerY.setValue(0, "px"); +#if WITH_GTKMM_3_0 + parametersTable.attach(centerX, 1, 0, 1, 1); + parametersTable.attach(centerY, 2, 0, 1, 1); +#else parametersTable.attach(centerX, 1, 2, 0, 1, Gtk::FILL); parametersTable.attach(centerY, 2, 3, 0, 1, Gtk::FILL); +#endif radiusLabel.set_text(_("Radius X/Y:")); +#if WITH_GTKMM_3_0 + parametersTable.attach(radiusLabel, 0, 1, 1, 1); +#else parametersTable.attach(radiusLabel, 0, 1, 1, 2, Gtk::FILL); +#endif radiusX.setDigits(2); radiusX.setIncrements(0.2, 0); radiusX.setRange(0.001, 10000); @@ -98,11 +116,20 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) radiusY.setIncrements(0.2, 0); radiusY.setRange(0.001, 10000); radiusY.setValue(100, "px"); +#if WITH_GTKMM_3_0 + parametersTable.attach(radiusX, 1, 1, 1, 1); + parametersTable.attach(radiusY, 2, 1, 1, 1); +#else parametersTable.attach(radiusX, 1, 2, 1, 2, Gtk::FILL); parametersTable.attach(radiusY, 2, 3, 1, 2, Gtk::FILL); +#endif angleLabel.set_text(_("Angle X/Y:")); +#if WITH_GTKMM_3_0 + parametersTable.attach(angleLabel, 0, 2, 1, 1); +#else parametersTable.attach(angleLabel, 0, 1, 2, 3, Gtk::FILL); +#endif angleX.setDigits(2); angleX.setIncrements(0.2, 0); angleX.setRange(-10000, 10000); @@ -111,8 +138,13 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) angleY.setIncrements(0.2, 0); angleY.setRange(-10000, 10000); angleY.setValue(180, "°"); +#if WITH_GTKMM_3_0 + parametersTable.attach(angleX, 1, 2, 1, 1); + parametersTable.attach(angleY, 2, 2, 1, 1); +#else parametersTable.attach(angleX, 1, 2, 2, 3, Gtk::FILL); parametersTable.attach(angleY, 2, 3, 2, 3, Gtk::FILL); +#endif pack_start(parametersTable, false, false); rotateObjectsCheckBox.set_label(_("Rotate objects")); diff --git a/src/ui/dialog/polar-arrange-tab.h b/src/ui/dialog/polar-arrange-tab.h index f6c3b2906..f7d7bf11f 100644 --- a/src/ui/dialog/polar-arrange-tab.h +++ b/src/ui/dialog/polar-arrange-tab.h @@ -10,9 +10,22 @@ #ifndef INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H #define INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include "ui/widget/scalar-unit.h" #include "ui/widget/anchor-selector.h" #include "ui/dialog/arrange-tab.h" -#include "ui/widget/scalar-unit.h" + +#include +#include + +#if WITH_GTKMM_3_0 + #include +#else + #include +#endif namespace Inkscape { namespace UI { @@ -62,7 +75,11 @@ private: Gtk::RadioButton arrangeOnLastCircleRadio; Gtk::RadioButton arrangeOnParametersRadio; +#if WITH_GTKMM_3_0 + Gtk::Grid parametersTable; +#else Gtk::Table parametersTable; +#endif Gtk::Label centerLabel; Inkscape::UI::Widget::ScalarUnit centerY; -- cgit v1.2.3 From 81ae160f5d204d3841505a6c364c064f77f17f88 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 22:52:01 +0100 Subject: Finish Gtk::Grid migration (bzr r13341.1.170) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 13 +++++++++++++ src/ui/dialog/lpe-fillet-chamfer-properties.h | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index c1e16495b..f5a554b36 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -46,18 +46,31 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() { Gtk::Box *mainVBox = get_content_area(); mainVBox->set_homogeneous(false); + +#if WITH_GTKMM_3_0 + _layout_table.set_row_spacing(4); + _layout_table.set_column_spacing(4); +#else _layout_table.set_spacings(4); _layout_table.resize(2, 2); +#endif // Layer name widgets _fillet_chamfer_position_entry.set_activates_default(true); _fillet_chamfer_position_label.set_label(_("Radius (pixels):")); _fillet_chamfer_position_label.set_alignment(1.0, 0.5); +#if WITH_GTKMM_3_0 + _layout_table.attach(_fillet_chamfer_position_label, 0, 0, 1, 1); + _layout_table.attach(_fillet_chamfer_position_entry, 1, 0, 1, 1); + _fillet_chamfer_position_entry.set_hexpand(); +#else _layout_table.attach(_fillet_chamfer_position_label, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); _layout_table.attach(_fillet_chamfer_position_entry, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); +#endif + _fillet_chamfer_type_fillet.set_label(_("Fillet")); _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index d3e859bff..6667e5785 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -8,10 +8,24 @@ #ifndef INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H #define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H +#if HAVE_CONFIG_H + #include "config.h" +#endif + #include <2geom/point.h> -#include #include "live_effects/parameter/filletchamferpointarray.h" +#include +#include +#include +#include + +#if WITH_GTKMM_3_0 + #include +#else + #include +#endif + class SPDesktop; namespace Inkscape { @@ -46,7 +60,12 @@ protected: Gtk::RadioButton _fillet_chamfer_type_chamfer; Gtk::RadioButton _fillet_chamfer_type_double_chamfer; +#if WITH_GTKMM_3_0 + Gtk::Grid _layout_table; +#else Gtk::Table _layout_table; +#endif + bool _position_visible; double _index; -- cgit v1.2.3 From a3e1d94ae50f769d2b1539307cf182ce5801e647 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 24 Aug 2014 11:37:18 +0100 Subject: Fix Gtk+ 2 build (bzr r13341.1.171) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 5 +++++ src/ui/dialog/lpe-fillet-chamfer-properties.h | 2 +- src/ui/dialog/new-from-template.cpp | 15 ++++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index f5a554b36..eef32d10d 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -44,7 +44,12 @@ namespace Dialogs { FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() : _desktop(NULL), _knotpoint(NULL), _position_visible(false) { +#if WITH_GTKMM_3_0 Gtk::Box *mainVBox = get_content_area(); +#else + Gtk::Box *mainVBox = get_vbox(); +#endif + mainVBox->set_homogeneous(false); #if WITH_GTKMM_3_0 diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 6667e5785..9beca02e1 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -12,10 +12,10 @@ #include "config.h" #endif +#include #include <2geom/point.h> #include "live_effects/parameter/filletchamferpointarray.h" -#include #include #include #include diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp index 5ce96d10f..e30b148bb 100644 --- a/src/ui/dialog/new-from-template.cpp +++ b/src/ui/dialog/new-from-template.cpp @@ -8,6 +8,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#if HAVE_CONFIG_H + #include "config.h" +#endif #include "new-from-template.h" #include "file.h" @@ -25,12 +28,22 @@ NewFromTemplate::NewFromTemplate() { set_title(_("New From Template")); resize(400, 400); - + +#if WITH_GTKMM_3_0 get_content_area()->pack_start(_main_widget); +#else + get_vbox()->pack_start(_main_widget); +#endif Gtk::Alignment *align; align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); + +#if WITH_GTKMM_3_0 get_content_area()->pack_end(*align, Gtk::PACK_SHRINK); +#else + get_vbox()->pack_end(*align, Gtk::PACK_SHRINK); +#endif + align->set_padding(0, 0, 0, 15); align->add(_create_template_button); -- cgit v1.2.3 From 4a6dfa29131adb8c7470ab66a839d144b02542e5 Mon Sep 17 00:00:00 2001 From: su_v Date: Tue, 26 Aug 2014 10:41:57 +0200 Subject: librevenge: update to latest patch from bug #1323592 (support old and new versions of libwpg, libcdr and libvisio ) (bzr r13398.1.7) --- src/ui/dialog/symbols.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 27e40f552..a9cf8d068 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -62,8 +62,20 @@ #include "widgets/icon.h" #ifdef WITH_LIBVISIO -#include -#include + #include + + // TODO: Drop this check when librevenge is widespread. + #if WITH_LIBVISIO01 + #include + + using librevenge::RVNGFileStream; + using librevenge::RVNGStringVector; + #else + #include + + typedef WPXFileStream RVNGFileStream; + typedef libvisio::VSDStringVector RVNGStringVector; + #endif #endif #include "verbs.h" @@ -495,16 +507,20 @@ void SymbolsDialog::iconChanged() { // Read Visio stencil files SPDocument* read_vss( gchar* fullname, gchar* filename ) { - librevenge::RVNGFileStream input(fullname); + RVNGFileStream input(fullname); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } - librevenge::RVNGStringVector output; + RVNGStringVector output; +#if WITH_LIBVISIO01 librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); if (!libvisio::VisioDocument::parseStencils(&input, &generator)) { +#else + if (!libvisio::VisioDocument::generateSVGStencils(&input, output)) { +#endif return NULL; } -- cgit v1.2.3 From 2d1275f0337e3fe49ea493f58135c81d0e3af36d Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 26 Aug 2014 11:55:28 +0100 Subject: Standardise InkscapeApplication GObject implementation (namespace not supported properly) (bzr r13341.1.179) --- src/ui/dialog/align-and-distribute.cpp | 4 ++-- src/ui/dialog/clonetiler.cpp | 4 ++-- src/ui/dialog/clonetiler.h | 4 ++-- src/ui/dialog/desktop-tracker.cpp | 2 +- src/ui/dialog/desktop-tracker.h | 5 ++--- src/ui/dialog/dialog-manager.cpp | 4 ++-- src/ui/dialog/dialog.cpp | 2 +- src/ui/dialog/dialog.h | 4 ++-- src/ui/dialog/document-metadata.cpp | 4 ++-- src/ui/dialog/document-metadata.h | 4 ++-- src/ui/dialog/document-properties.cpp | 4 ++-- src/ui/dialog/document-properties.h | 4 ++-- src/ui/dialog/fill-and-stroke.h | 2 +- src/ui/dialog/grid-arrange-tab.cpp | 2 +- src/ui/dialog/panel-dialog.h | 12 ++++++------ src/ui/dialog/transformation.cpp | 4 ++-- 16 files changed, 32 insertions(+), 33 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index e02ccd3f1..8352de1e3 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -829,14 +829,14 @@ private : -static void on_tool_changed(Inkscape::Application */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad) +static void on_tool_changed(InkscapeApplication */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop && desktop->getEventContext()) daad->setMode(tools_active(desktop) == TOOLS_NODES); } -static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) +static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) { daad->randomize_bbox = Geom::OptRect(); } diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index e5f18216c..d9e2c03ba 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1349,7 +1349,7 @@ void CloneTiler::on_picker_color_changed(guint rgba) is_updating = false; } -void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) +void CloneTiler::clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) { 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")); @@ -1378,7 +1378,7 @@ void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape* } } -void CloneTiler::clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg) +void CloneTiler::clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg) { clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); } diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h index e2a0240ee..9bacc701d 100644 --- a/src/ui/dialog/clonetiler.h +++ b/src/ui/dialog/clonetiler.h @@ -58,8 +58,8 @@ protected: static void clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/); static void clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg); static void clonetiler_unclump(GtkWidget */*widget*/, void *); - static void clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg); - static void clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg); + static void clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg); + static void clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg); static void clonetiler_disconnect_gsignal(GObject *widget, gpointer source); static void clonetiler_reset(GtkWidget */*widget*/, GtkWidget *dlg); static guint clonetiler_number_of_clones(SPObject *obj); diff --git a/src/ui/dialog/desktop-tracker.cpp b/src/ui/dialog/desktop-tracker.cpp index 8a359dd2d..3ed998252 100644 --- a/src/ui/dialog/desktop-tracker.cpp +++ b/src/ui/dialog/desktop-tracker.cpp @@ -94,7 +94,7 @@ sigc::connection DesktopTracker::connectDesktopChanged( const sigc::slottrackActive) { self->setDesktop(desktop); diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h index 7da55cf2f..7b944ddfa 100644 --- a/src/ui/dialog/desktop-tracker.h +++ b/src/ui/dialog/desktop-tracker.h @@ -12,11 +12,10 @@ typedef struct _GtkWidget GtkWidget; class SPDesktop; +struct InkscapeApplication; namespace Inkscape { -struct Application; - namespace UI { namespace Dialog { @@ -37,7 +36,7 @@ public: sigc::connection connectDesktopChanged( const sigc::slot & slot ); private: - static gboolean activateDesktopCB(Inkscape::Application *inkscape, SPDesktop *desktop, DesktopTracker *self ); + static gboolean activateDesktopCB(InkscapeApplication *inkscape, SPDesktop *desktop, DesktopTracker *self ); static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, DesktopTracker *self); void handleHierarchyChange(); diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 7e69e439a..0da638546 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -70,13 +70,13 @@ inline Dialog *create() { return PanelDialog::template create(); } /** * This class is provided as a container for Inkscape's various - * dialogs. This allows Inkscape::Application to treat the various + * dialogs. This allows InkscapeApplication to treat the various * dialogs it invokes, as abstractions. * * DialogManager is essentially a cache of dialogs. It lets us * initialize dialogs lazily - instead of constructing them during * application startup, they're constructed the first time they're - * actually invoked by Inkscape::Application. The constructed + * actually invoked by InkscapeApplication. The constructed * dialog is held here after that, so future invokations of the * dialog don't need to get re-constructed each time. The memory for * the dialogs are then reclaimed when the DialogManager is destroyed. diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index f2c63ed8d..4f0d9fbe1 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -41,7 +41,7 @@ namespace Inkscape { namespace UI { namespace Dialog { -void sp_retransientize(Inkscape::Application */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr) +void sp_retransientize(InkscapeApplication */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr) { Dialog *dlg = static_cast(dlgPtr); dlg->onDesktopActivated (desktop); diff --git a/src/ui/dialog/dialog.h b/src/ui/dialog/dialog.h index ec5d203bc..ccff43a56 100644 --- a/src/ui/dialog/dialog.h +++ b/src/ui/dialog/dialog.h @@ -18,10 +18,10 @@ #include "floating-behavior.h" class SPDesktop; +struct InkscapeApplication; namespace Inkscape { class Selection; -struct Application; } namespace Inkscape { @@ -30,7 +30,7 @@ namespace Dialog { enum BehaviorType { FLOATING, DOCK }; -void sp_retransientize(Inkscape::Application *inkscape, SPDesktop *desktop, gpointer dlgPtr); +void sp_retransientize(InkscapeApplication *inkscape, SPDesktop *desktop, gpointer dlgPtr); gboolean sp_retransientize_again(gpointer dlgPtr); void sp_dialog_shutdown(GObject *object, gpointer dlgPtr); diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp index 09c505860..77ea175d9 100644 --- a/src/ui/dialog/document-metadata.cpp +++ b/src/ui/dialog/document-metadata.cpp @@ -223,7 +223,7 @@ DocumentMetadata::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *) } void -DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop) +DocumentMetadata::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener(&_repr_events, this); @@ -231,7 +231,7 @@ DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *des } void -DocumentMetadata::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop) +DocumentMetadata::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->removeListenerByData(this); diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h index 3b7ed1ec8..77084bc3d 100644 --- a/src/ui/dialog/document-metadata.h +++ b/src/ui/dialog/document-metadata.h @@ -56,8 +56,8 @@ protected: void init(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop); - void _handleDeactivateDesktop(Inkscape::Application *application, SPDesktop *desktop); + void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); Gtk::Notebook _notebook; diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 4e4616724..5ad82644e 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1594,7 +1594,7 @@ void DocumentProperties::_handleDocumentReplaced(SPDesktop* desktop, SPDocument update(); } -void DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop) +void DocumentProperties::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener(&_repr_events, this); @@ -1603,7 +1603,7 @@ void DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDeskt update(); } -void DocumentProperties::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop) +void DocumentProperties::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->removeListenerByData(this); diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index 495f3177d..ee7e88b18 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -94,8 +94,8 @@ protected: void save_default_metadata(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop); - void _handleDeactivateDesktop(Inkscape::Application *application, SPDesktop *desktop); + void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); Inkscape::XML::SignalObserver _emb_profiles_observer, _scripts_observer; Gtk::Notebook _notebook; diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h index 340cb860f..35c98ef9c 100644 --- a/src/ui/dialog/fill-and-stroke.h +++ b/src/ui/dialog/fill-and-stroke.h @@ -41,7 +41,7 @@ public: virtual void setDesktop(SPDesktop *desktop); - void selectionChanged(Inkscape::Application *inkscape, + void selectionChanged(InkscapeApplication *inkscape, Inkscape::Selection *selection); void showPageFill(); diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 72217c729..1417b39fa 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -572,7 +572,7 @@ void GridArrangeTab::updateSelection() ## Experimental ##########################*/ -static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) +static void updateSelectionCallback(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) { dlg->updateSelection(); } diff --git a/src/ui/dialog/panel-dialog.h b/src/ui/dialog/panel-dialog.h index 1fefd811e..b4a355083 100644 --- a/src/ui/dialog/panel-dialog.h +++ b/src/ui/dialog/panel-dialog.h @@ -49,19 +49,19 @@ public: virtual UI::Widget::Panel &getPanel() { return _panel; } protected: - static void handle_deactivate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) { + static void handle_deactivate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { g_return_if_fail(data != NULL); static_cast(data)->_propagateDesktopDeactivated(application, desktop); } - static void _handle_activate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) { + static void _handle_activate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { g_return_if_fail(data != NULL); static_cast(data)->_propagateDesktopActivated(application, desktop); } inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document); - inline virtual void _propagateDesktopActivated(Inkscape::Application *, SPDesktop *); - inline virtual void _propagateDesktopDeactivated(Inkscape::Application *, SPDesktop *); + inline virtual void _propagateDesktopActivated(InkscapeApplication *, SPDesktop *); + inline virtual void _propagateDesktopDeactivated(InkscapeApplication *, SPDesktop *); UI::Widget::Panel &_panel; sigc::connection _document_replaced_connection; @@ -134,14 +134,14 @@ void PanelDialogBase::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument _panel.signalDocumentReplaced().emit(desktop, document); } -void PanelDialogBase::_propagateDesktopActivated(Inkscape::Application *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopActivated(InkscapeApplication *application, SPDesktop *desktop) { _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialogBase::_propagateDocumentReplaced)); _panel.signalActivateDesktop().emit(application, desktop); } -void PanelDialogBase::_propagateDesktopDeactivated(Inkscape::Application *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopDeactivated(InkscapeApplication *application, SPDesktop *desktop) { _document_replaced_connection.disconnect(); _panel.signalDeactiveDesktop().emit(application, desktop); diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index a7f0b068e..3e135b9b2 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -47,13 +47,13 @@ namespace Inkscape { namespace UI { namespace Dialog { -static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, Transformation *daad) +static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection *selection, Transformation *daad) { int page = daad->getCurrentPage(); daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection); } -static void on_selection_modified( Inkscape::Application */*inkscape*/, +static void on_selection_modified( InkscapeApplication */*inkscape*/, Inkscape::Selection *selection, guint /*flags*/, Transformation *daad ) -- cgit v1.2.3 From 7fd8ede6c698136bfa675dd4f1d5da6f5803154f Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Tue, 26 Aug 2014 22:38:14 +0200 Subject: Fix rotation center regression caused by my own commit 13512 Fixed bugs: - https://launchpad.net/bugs/1360953 - https://launchpad.net/bugs/1360946 (bzr r13534) --- src/ui/dialog/document-properties.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 4e4616724..2757a0ec9 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1736,9 +1736,13 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); - gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); - gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); - gdouble viewscale = std::min(viewscale_h, viewscale_w); + gdouble viewscale = 1.0; + Geom::Rect vb = doc->getRoot()->viewBox; + if ( !vb.hasZeroArea() ) { + gdouble viewscale_w = doc->getWidth().value("px") / vb.width(); + gdouble viewscale_h = doc->getHeight().value("px")/ vb.height(); + viewscale = std::min(viewscale_h, viewscale_w); + } gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, -- cgit v1.2.3 From 65e028240540fafc4269bd43e66cdeaf41408b12 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sat, 30 Aug 2014 08:24:40 +0200 Subject: Translators list update (bzr r13536) --- src/ui/dialog/aboutbox.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index a66855b2a..7cd069132 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -482,6 +482,7 @@ void AboutBox::initStrings() { "Elias Norberg , 2009.\n" "Equipe de Tradução Inkscape Brasil , 2007.\n" "Fatih Demir , 2000.\n" +"Firas Hanife , 2014.\n" "Foppe Benedictus , 2007-2009.\n" "Francesc Dorca , 2003. Traducció sodipodi.\n" "Francisco Javier F. Serrador , 2003.\n" @@ -493,8 +494,9 @@ void AboutBox::initStrings() { "Hizkuntza Politikarako Sailburuordetza , 2005.\n" "Ilia Penev , 2006.\n" "Ivan Masár , 2006-2010. \n" +"Ivan Řihošek , 2014.\n" "Iñaki Larrañaga , 2006.\n" -"Jānis Eisaks , 2012, 2013.\n" +"Jānis Eisaks , 2012-2014.\n" "Jeffrey Steve Borbón Sanabria , 2005.\n" "Jesper Öqvist , 2010, 2011.\n" "Joaquim Perez i Noguer , 2008-2009.\n" @@ -516,7 +518,7 @@ void AboutBox::initStrings() { "Kingsley Turner , 2006.\n" "Kitae , 2006.\n" "Kjartan Maraas , 2000-2002.\n" -"Kris De Gussem , 2008-2013.\n" +"Kris De Gussem , 2008-2014.\n" "Lauris Kaplinski , 2000.\n" "Leandro Regueiro , 2006-2008, 2010.\n" "Liu Xiaoqin , 2008.\n" @@ -536,7 +538,7 @@ void AboutBox::initStrings() { "Muhammad Bashir Al-Noimi , 2008.\n" "Myckel Habets , 2008.\n" "Nguyen Dinh Trung , 2007, 2008.\n" -"Nicolas Dufour , 2008-2013.\n" +"Nicolas Dufour , 2008-2014.\n" "Pawan Chitrakar , 2006.\n" "Przemysław Loesch , 2005.\n" "Quico Llach , 2000. Traducció sodipodi.\n" -- cgit v1.2.3 From 9066e62e9f0cb4972f3b7988004393e96e55e09d Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 30 Aug 2014 12:00:43 +0100 Subject: Fix modelines (bzr r13341.1.183) --- src/ui/dialog/aboutbox.cpp | 6 +++--- src/ui/dialog/aboutbox.h | 6 +++--- src/ui/dialog/inkscape-preferences.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index a66855b2a..44ed3b58f 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -941,13 +941,13 @@ void AboutBox::initStrings() { } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/aboutbox.h b/src/ui/dialog/aboutbox.h index 7b3308672..015e344a1 100644 --- a/src/ui/dialog/aboutbox.h +++ b/src/ui/dialog/aboutbox.h @@ -55,13 +55,13 @@ private: #endif // INKSCAPE_UI_DIALOG_ABOUTBOX_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 9f37626ed..dcea91741 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -545,9 +545,9 @@ private: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 977857ef75a45ed1ec79cfdcf0f25dd66d4a7e86 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 30 Aug 2014 14:00:28 +0100 Subject: Reduce header bloat (bzr r13341.1.184) --- src/ui/dialog/clonetiler.h | 1 - src/ui/dialog/export.h | 9 --------- src/ui/dialog/filedialogimpl-gtkmm.cpp | 1 + 3 files changed, 1 insertion(+), 10 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h index 9bacc701d..70da86338 100644 --- a/src/ui/dialog/clonetiler.h +++ b/src/ui/dialog/clonetiler.h @@ -11,7 +11,6 @@ #define __SP_CLONE_TILER_H__ #include "ui/widget/panel.h" -#include #include "ui/dialog/desktop-tracker.h" #include "ui/widget/color-picker.h" diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 6f3c0dfac..23af0109b 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -12,20 +12,11 @@ #ifndef SP_EXPORT_H #define SP_EXPORT_H -#include -#include - -#include -#include -#include #include -#include -#include "desktop.h" #include "ui/dialog/desktop-tracker.h" #include "ui/widget/panel.h" #include "ui/widget/button.h" -#include "ui/widget/entry.h" namespace Gtk { class Dialog; diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 8ba3ad684..575519848 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -40,6 +40,7 @@ #include #include +#include "document.h" #include "extension/input.h" #include "extension/output.h" #include "extension/db.h" -- cgit v1.2.3 From 3380db70b04c1a5df6c0ad2ffef56d3c469f8614 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Mon, 1 Sep 2014 21:36:17 -0400 Subject: Updated about box authors list from AUTHORS file. (bzr r13539) --- src/ui/dialog/aboutbox.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 7cd069132..f3cffa244 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -254,6 +254,7 @@ void AboutBox::initStrings() { "Nicholas Bishop\n" "Joshua L. Blocher\n" "Hanno Böck\n" +"Tomasz Boczkowski\n" "Henrik Bohre\n" "Boldewyn\n" "Daniel Borgmann\n" @@ -270,6 +271,7 @@ void AboutBox::initStrings() { "Gail Carmichael\n" "Ed Catmur\n" "Chema Celorio\n" +"Jabiertxo Arraiza Cenoz\n" "Johan Ceuppens\n" "Zbigniew Chyla\n" "Alexander Clausen\n" @@ -311,6 +313,7 @@ void AboutBox::initStrings() { "Hannes Hochreiner\n" "Thomas Holder\n" "Joel Holdsworth\n" +"Christoffer Holmstedt\n" "Alan Horkan\n" "Karl Ove Hufthammer\n" "Richard Hughes\n" @@ -319,6 +322,7 @@ void AboutBox::initStrings() { "Thomas Ingham\n" "Jean-Olivier Irisson\n" "Bob Jamison\n" +"Ted Janeczko\n" "jEsuSdA\n" "Fernando Lucchesi Bastos Jurema\n" "Lauris Kaplinski\n" @@ -342,7 +346,9 @@ void AboutBox::initStrings() { "Aurel-Aimé Marmion\n" "Colin Marquardt\n" "Craig Marshall\n" +"Ivan Masár\n" "Dmitry G. Mastrukov\n" +"David Mathog\n" "Matiphas\n" "Michael Meeks\n" "Federico Mena\n" @@ -360,8 +366,10 @@ void AboutBox::initStrings() { "Nick\n" "Andreas Nilsson\n" "Mitsuru Oka\n" +"Vinícius dos Santos Oliveira\n" "Martin Owens\n" "Alvin Penner\n" +"Matthew Petroff\n" "Jon Phillips\n" "Zdenko Podobny\n" "Alexandre Prokoudine\n" @@ -398,6 +406,8 @@ void AboutBox::initStrings() { "Joakim Verona\n" "Lucas Vieites\n" "Daniel Wagenaar\n" +"Liam P. White\n" +"Sebastian Wüst\n" "Michael Wybrow\n" "Gellule Xg\n" "Daniel Yacob\n" -- cgit v1.2.3 From 395b34493e806b4aa2333c694d7d6e4e4d4700a4 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 2 Sep 2014 17:14:55 -0400 Subject: Remove misleading dialogs directory (bzr r13341.1.192) --- src/ui/dialog/dock-behavior.cpp | 2 +- src/ui/dialog/export.cpp | 2 +- src/ui/dialog/filedialog.cpp | 2 +- src/ui/dialog/filedialogimpl-gtkmm.cpp | 2 +- src/ui/dialog/filedialogimpl-win32.cpp | 2 +- src/ui/dialog/find.cpp | 2 +- src/ui/dialog/floating-behavior.cpp | 2 +- src/ui/dialog/font-substitution.cpp | 2 +- src/ui/dialog/guides.cpp | 2 +- src/ui/dialog/ocaldialogs.cpp | 2 +- src/ui/dialog/ocaldialogs.h | 3 +-- src/ui/dialog/xml-tree.cpp | 2 +- 12 files changed, 12 insertions(+), 13 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/dock-behavior.cpp b/src/ui/dialog/dock-behavior.cpp index 9b216e841..f65b298c9 100644 --- a/src/ui/dialog/dock-behavior.cpp +++ b/src/ui/dialog/dock-behavior.cpp @@ -24,7 +24,7 @@ #include "verbs.h" #include "dialog.h" #include "preferences.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include #include diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 913713e5c..cd8fdbd92 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -62,7 +62,7 @@ #include "sp-namedview.h" #include "selection-chemistry.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "preferences.h" #include "verbs.h" #include "interface.h" diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp index e71605739..00ed09551 100644 --- a/src/ui/dialog/filedialog.cpp +++ b/src/ui/dialog/filedialog.cpp @@ -20,7 +20,7 @@ #include "filedialog.h" #include "gc-core.h" -#include +#include "ui/dialog-events.h" #include "extension/output.h" #include "preferences.h" diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 575519848..5778b44db 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -22,7 +22,7 @@ #endif #include "filedialogimpl-gtkmm.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "interface.h" #include "io/sys.h" #include "path-prefix.h" diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 06153a2d8..ee6a0ef3a 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -31,7 +31,7 @@ //Inkscape includes #include "inkscape.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "extension/input.h" #include "extension/output.h" #include "extension/db.h" diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 37f2761df..9b814bb9f 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -31,7 +31,7 @@ #include "selection.h" #include "desktop-handles.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "verbs.h" #include "interface.h" #include "preferences.h" diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp index dd07f009a..f286588b2 100644 --- a/src/ui/dialog/floating-behavior.cpp +++ b/src/ui/dialog/floating-behavior.cpp @@ -28,7 +28,7 @@ #include "inkscape.h" #include "desktop.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "interface.h" #include "preferences.h" #include "verbs.h" diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index 6e9ecc3c8..db7bdf222 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -27,7 +27,7 @@ #include "document.h" #include "selection.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "desktop-handles.h" #include "selection-chemistry.h" #include "preferences.h" diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 80740113c..76c26a3cb 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -28,7 +28,7 @@ #include "ui/tools/tool-base.h" #include "widgets/desktop-widget.h" #include -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "message-context.h" #include "xml/repr.h" #include "verbs.h" diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index f676e75fd..607087f6d 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -27,7 +27,7 @@ #include "filedialogimpl-gtkmm.h" #include "interface.h" #include "gc-core.h" -#include +#include "ui/dialog-events.h" #include "io/sys.h" #include "preferences.h" diff --git a/src/ui/dialog/ocaldialogs.h b/src/ui/dialog/ocaldialogs.h index e21030bcd..bd028c145 100644 --- a/src/ui/dialog/ocaldialogs.h +++ b/src/ui/dialog/ocaldialogs.h @@ -38,8 +38,7 @@ //Inkscape includes #include "ui/dialog/filedialog.h" - -#include +#include "ui/dialog-events.h" struct _xmlNode; typedef _xmlNode xmlNode; diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index c87e42633..9a8c188b2 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -24,7 +24,7 @@ #include "desktop.h" #include "desktop-handles.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "document.h" #include "document-undo.h" #include "ui/tools/tool-base.h" -- cgit v1.2.3 From 0d0958e3b2aff0ed5f3ad7a98b4035213475c7f1 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 7 Sep 2014 13:02:01 -0400 Subject: Update to experimental r13543 (bzr r13090.1.108) --- src/ui/dialog/aboutbox.cpp | 18 +++++++++++++++--- src/ui/dialog/dock-behavior.cpp | 2 +- src/ui/dialog/document-properties.cpp | 10 +++++++--- src/ui/dialog/export.cpp | 2 +- src/ui/dialog/filedialog.cpp | 2 +- src/ui/dialog/filedialogimpl-gtkmm.cpp | 2 +- src/ui/dialog/filedialogimpl-win32.cpp | 2 +- src/ui/dialog/find.cpp | 2 +- src/ui/dialog/floating-behavior.cpp | 2 +- src/ui/dialog/font-substitution.cpp | 2 +- src/ui/dialog/guides.cpp | 2 +- src/ui/dialog/objects.cpp | 2 +- src/ui/dialog/ocaldialogs.cpp | 2 +- src/ui/dialog/ocaldialogs.h | 3 +-- src/ui/dialog/tags.cpp | 2 +- src/ui/dialog/xml-tree.cpp | 2 +- 16 files changed, 36 insertions(+), 21 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 44ed3b58f..7212fa372 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -254,6 +254,7 @@ void AboutBox::initStrings() { "Nicholas Bishop\n" "Joshua L. Blocher\n" "Hanno Böck\n" +"Tomasz Boczkowski\n" "Henrik Bohre\n" "Boldewyn\n" "Daniel Borgmann\n" @@ -270,6 +271,7 @@ void AboutBox::initStrings() { "Gail Carmichael\n" "Ed Catmur\n" "Chema Celorio\n" +"Jabiertxo Arraiza Cenoz\n" "Johan Ceuppens\n" "Zbigniew Chyla\n" "Alexander Clausen\n" @@ -311,6 +313,7 @@ void AboutBox::initStrings() { "Hannes Hochreiner\n" "Thomas Holder\n" "Joel Holdsworth\n" +"Christoffer Holmstedt\n" "Alan Horkan\n" "Karl Ove Hufthammer\n" "Richard Hughes\n" @@ -319,6 +322,7 @@ void AboutBox::initStrings() { "Thomas Ingham\n" "Jean-Olivier Irisson\n" "Bob Jamison\n" +"Ted Janeczko\n" "jEsuSdA\n" "Fernando Lucchesi Bastos Jurema\n" "Lauris Kaplinski\n" @@ -342,7 +346,9 @@ void AboutBox::initStrings() { "Aurel-Aimé Marmion\n" "Colin Marquardt\n" "Craig Marshall\n" +"Ivan Masár\n" "Dmitry G. Mastrukov\n" +"David Mathog\n" "Matiphas\n" "Michael Meeks\n" "Federico Mena\n" @@ -360,8 +366,10 @@ void AboutBox::initStrings() { "Nick\n" "Andreas Nilsson\n" "Mitsuru Oka\n" +"Vinícius dos Santos Oliveira\n" "Martin Owens\n" "Alvin Penner\n" +"Matthew Petroff\n" "Jon Phillips\n" "Zdenko Podobny\n" "Alexandre Prokoudine\n" @@ -398,6 +406,8 @@ void AboutBox::initStrings() { "Joakim Verona\n" "Lucas Vieites\n" "Daniel Wagenaar\n" +"Liam P. White\n" +"Sebastian Wüst\n" "Michael Wybrow\n" "Gellule Xg\n" "Daniel Yacob\n" @@ -482,6 +492,7 @@ void AboutBox::initStrings() { "Elias Norberg , 2009.\n" "Equipe de Tradução Inkscape Brasil , 2007.\n" "Fatih Demir , 2000.\n" +"Firas Hanife , 2014.\n" "Foppe Benedictus , 2007-2009.\n" "Francesc Dorca , 2003. Traducció sodipodi.\n" "Francisco Javier F. Serrador , 2003.\n" @@ -493,8 +504,9 @@ void AboutBox::initStrings() { "Hizkuntza Politikarako Sailburuordetza , 2005.\n" "Ilia Penev , 2006.\n" "Ivan Masár , 2006-2010. \n" +"Ivan Řihošek , 2014.\n" "Iñaki Larrañaga , 2006.\n" -"Jānis Eisaks , 2012, 2013.\n" +"Jānis Eisaks , 2012-2014.\n" "Jeffrey Steve Borbón Sanabria , 2005.\n" "Jesper Öqvist , 2010, 2011.\n" "Joaquim Perez i Noguer , 2008-2009.\n" @@ -516,7 +528,7 @@ void AboutBox::initStrings() { "Kingsley Turner , 2006.\n" "Kitae , 2006.\n" "Kjartan Maraas , 2000-2002.\n" -"Kris De Gussem , 2008-2013.\n" +"Kris De Gussem , 2008-2014.\n" "Lauris Kaplinski , 2000.\n" "Leandro Regueiro , 2006-2008, 2010.\n" "Liu Xiaoqin , 2008.\n" @@ -536,7 +548,7 @@ void AboutBox::initStrings() { "Muhammad Bashir Al-Noimi , 2008.\n" "Myckel Habets , 2008.\n" "Nguyen Dinh Trung , 2007, 2008.\n" -"Nicolas Dufour , 2008-2013.\n" +"Nicolas Dufour , 2008-2014.\n" "Pawan Chitrakar , 2006.\n" "Przemysław Loesch , 2005.\n" "Quico Llach , 2000. Traducció sodipodi.\n" diff --git a/src/ui/dialog/dock-behavior.cpp b/src/ui/dialog/dock-behavior.cpp index 9b216e841..f65b298c9 100644 --- a/src/ui/dialog/dock-behavior.cpp +++ b/src/ui/dialog/dock-behavior.cpp @@ -24,7 +24,7 @@ #include "verbs.h" #include "dialog.h" #include "preferences.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include #include diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 5ad82644e..2a3a1dd86 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1736,9 +1736,13 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); - gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); - gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); - gdouble viewscale = std::min(viewscale_h, viewscale_w); + gdouble viewscale = 1.0; + Geom::Rect vb = doc->getRoot()->viewBox; + if ( !vb.hasZeroArea() ) { + gdouble viewscale_w = doc->getWidth().value("px") / vb.width(); + gdouble viewscale_h = doc->getHeight().value("px")/ vb.height(); + viewscale = std::min(viewscale_h, viewscale_w); + } gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 913713e5c..cd8fdbd92 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -62,7 +62,7 @@ #include "sp-namedview.h" #include "selection-chemistry.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "preferences.h" #include "verbs.h" #include "interface.h" diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp index e71605739..00ed09551 100644 --- a/src/ui/dialog/filedialog.cpp +++ b/src/ui/dialog/filedialog.cpp @@ -20,7 +20,7 @@ #include "filedialog.h" #include "gc-core.h" -#include +#include "ui/dialog-events.h" #include "extension/output.h" #include "preferences.h" diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 575519848..5778b44db 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -22,7 +22,7 @@ #endif #include "filedialogimpl-gtkmm.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "interface.h" #include "io/sys.h" #include "path-prefix.h" diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 06153a2d8..ee6a0ef3a 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -31,7 +31,7 @@ //Inkscape includes #include "inkscape.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "extension/input.h" #include "extension/output.h" #include "extension/db.h" diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 37f2761df..9b814bb9f 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -31,7 +31,7 @@ #include "selection.h" #include "desktop-handles.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "verbs.h" #include "interface.h" #include "preferences.h" diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp index dd07f009a..f286588b2 100644 --- a/src/ui/dialog/floating-behavior.cpp +++ b/src/ui/dialog/floating-behavior.cpp @@ -28,7 +28,7 @@ #include "inkscape.h" #include "desktop.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "interface.h" #include "preferences.h" #include "verbs.h" diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index 6e9ecc3c8..db7bdf222 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -27,7 +27,7 @@ #include "document.h" #include "selection.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "desktop-handles.h" #include "selection-chemistry.h" #include "preferences.h" diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 80740113c..76c26a3cb 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -28,7 +28,7 @@ #include "ui/tools/tool-base.h" #include "widgets/desktop-widget.h" #include -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "message-context.h" #include "xml/repr.h" #include "verbs.h" diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 2d558daae..ecd4ff42f 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -25,7 +25,7 @@ #include "desktop.h" #include "desktop-style.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "document.h" #include "document-undo.h" #include "filter-chemistry.h" diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index f676e75fd..607087f6d 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -27,7 +27,7 @@ #include "filedialogimpl-gtkmm.h" #include "interface.h" #include "gc-core.h" -#include +#include "ui/dialog-events.h" #include "io/sys.h" #include "preferences.h" diff --git a/src/ui/dialog/ocaldialogs.h b/src/ui/dialog/ocaldialogs.h index e21030bcd..bd028c145 100644 --- a/src/ui/dialog/ocaldialogs.h +++ b/src/ui/dialog/ocaldialogs.h @@ -38,8 +38,7 @@ //Inkscape includes #include "ui/dialog/filedialog.h" - -#include +#include "ui/dialog-events.h" struct _xmlNode; typedef _xmlNode xmlNode; diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index b2ca1b6da..127e4d95e 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -50,7 +50,7 @@ #include "sp-root.h" #include "ui/tools/tool-base.h" //"event-context.h" #include "selection.h" -#include "dialogs/dialog-events.h" +//#include "dialogs/dialog-events.h" #include "widgets/sp-color-notebook.h" #include "style.h" #include "filter-chemistry.h" diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index c87e42633..9a8c188b2 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -24,7 +24,7 @@ #include "desktop.h" #include "desktop-handles.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "document.h" #include "document-undo.h" #include "ui/tools/tool-base.h" -- cgit v1.2.3 From 71c3b0398381d4bace1427bbda11f486fcbcc307 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Mon, 8 Sep 2014 10:13:03 -0700 Subject: partial rollback of r13544, allow old recursive behavior for some locations, but not EMF import (bzr r13549) --- src/ui/dialog/document-properties.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 2757a0ec9..1f220b246 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1747,7 +1747,8 @@ void DocumentProperties::onDocUnitChange() doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, viewscale*doc->getRoot()->viewBox.min()[Geom::Y] + - (doc->getHeight().value("px") + viewscale*doc->getRoot()->viewBox.height())/2)); + (doc->getHeight().value("px") + viewscale*doc->getRoot()->viewBox.height())/2), + false); ShapeEditor::blockSetItem(false); } prefs->setBool("/options/transform/stroke", transform_stroke); -- cgit v1.2.3 From 39d4d238a04162c559f83011999cc16feb6da88f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 11 Sep 2014 05:30:09 +0200 Subject: add radius support to fillet-chamfer, bugfixes (bzr r13341.1.203) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 71 +++++++++++++------------ src/ui/dialog/lpe-fillet-chamfer-properties.h | 31 ++++------- 2 files changed, 46 insertions(+), 56 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index eef32d10d..ad8b66b8c 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -12,9 +12,9 @@ #include #endif +#include #include "lpe-fillet-chamfer-properties.h" #include -#include #include #include #include "inkscape.h" @@ -31,9 +31,8 @@ #include "selection-chemistry.h" #include "ui/icon-names.h" #include "ui/widget/imagetoggler.h" -#include -#include #include "util/units.h" +#include //#include "event-context.h" @@ -44,38 +43,24 @@ namespace Dialogs { FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() : _desktop(NULL), _knotpoint(NULL), _position_visible(false) { -#if WITH_GTKMM_3_0 - Gtk::Box *mainVBox = get_content_area(); -#else Gtk::Box *mainVBox = get_vbox(); -#endif - mainVBox->set_homogeneous(false); - -#if WITH_GTKMM_3_0 - _layout_table.set_row_spacing(4); - _layout_table.set_column_spacing(4); -#else _layout_table.set_spacings(4); _layout_table.resize(2, 2); -#endif // Layer name widgets - _fillet_chamfer_position_entry.set_activates_default(true); + _fillet_chamfer_position_numeric.set_digits(4); + _fillet_chamfer_position_numeric.set_increments(1,1); + //todo: get tha max aloable infinity freeze the widget + _fillet_chamfer_position_numeric.set_range(0., 999999999999999999.); + _fillet_chamfer_position_label.set_label(_("Radius (pixels):")); _fillet_chamfer_position_label.set_alignment(1.0, 0.5); -#if WITH_GTKMM_3_0 - _layout_table.attach(_fillet_chamfer_position_label, 0, 0, 1, 1); - _layout_table.attach(_fillet_chamfer_position_entry, 1, 0, 1, 1); - _fillet_chamfer_position_entry.set_hexpand(); -#else _layout_table.attach(_fillet_chamfer_position_label, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); - _layout_table.attach(_fillet_chamfer_position_entry, 1, 2, 0, 1, + _layout_table.attach(_fillet_chamfer_position_numeric, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); -#endif - _fillet_chamfer_type_fillet.set_label(_("Fillet")); _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); @@ -115,7 +100,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() show_all_children(); - set_focus(_fillet_chamfer_position_entry); + set_focus(_fillet_chamfer_position_numeric); } FilletChamferPropertiesDialog::~FilletChamferPropertiesDialog() @@ -128,12 +113,16 @@ void FilletChamferPropertiesDialog::showDialog( SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt, - const gchar *unit) + const gchar *unit, + bool use_distance, + bool aprox_radius) { FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog(); dialog->_setDesktop(desktop); dialog->_setUnit(unit); + dialog->_set_use_distance(use_distance); + dialog->_set_aprox(aprox_radius); dialog->_setKnotPoint(knotpoint); dialog->_setPt(pt); @@ -150,9 +139,9 @@ void FilletChamferPropertiesDialog::showDialog( void FilletChamferPropertiesDialog::_apply() { - std::istringstream i_pos(_fillet_chamfer_position_entry.get_text()); - double d_pos, d_width; - if (i_pos >> d_pos) { + double d_width; + double d_pos = _fillet_chamfer_position_numeric.get_value(); + if (d_pos) { if (_fillet_chamfer_type_fillet.get_active() == true) { d_width = 1; } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { @@ -203,6 +192,13 @@ void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event) void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) { double position; + std::string distance_or_radius = std::string(_("Radius ")); + if(aprox){ + distance_or_radius = std::string(_("Radius aproximated ")); + } + if(use_distance){ + distance_or_radius = std::string(_("Knot distance ")); + } if (knotpoint.x() > 0) { double intpart; position = modf(knotpoint[Geom::X], &intpart) * 100; @@ -211,16 +207,13 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) _fillet_chamfer_position_label.set_label(_("Position (%):")); } else { _flexible = false; - std::string posConcat = - std::string(_("Position (")) + std::string(unit) + std::string(")"); + std::string posConcat = distance_or_radius + + std::string(_("(")) + std::string(unit) + std::string(")"); _fillet_chamfer_position_label.set_label(_(posConcat.c_str())); position = knotpoint[Geom::X] * -1; position = Inkscape::Util::Quantity::convert(position, "px", unit); } - std::ostringstream s; - s.imbue(std::locale::classic()); - s << position; - _fillet_chamfer_position_entry.set_text(s.str()); + _fillet_chamfer_position_numeric.set_value(position); if (knotpoint.y() == 1) { _fillet_chamfer_type_fillet.set_active(true); } else if (knotpoint.y() == 2) { @@ -246,6 +239,16 @@ void FilletChamferPropertiesDialog::_setUnit(const gchar *abbr) unit = abbr; } +void FilletChamferPropertiesDialog::_set_use_distance(bool use_knot_distance) +{ + use_distance = use_knot_distance; +} + +void FilletChamferPropertiesDialog::_set_aprox(bool aprox_radius) +{ + aprox = aprox_radius; +} + void FilletChamferPropertiesDialog::_setDesktop(SPDesktop *desktop) { if (desktop) { diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 9beca02e1..47ff97b00 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -8,24 +8,10 @@ #ifndef INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H #define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include #include <2geom/point.h> +#include #include "live_effects/parameter/filletchamferpointarray.h" -#include -#include -#include - -#if WITH_GTKMM_3_0 - #include -#else - #include -#endif - class SPDesktop; namespace Inkscape { @@ -44,7 +30,9 @@ public: static void showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt, - const gchar *unit); + const gchar *unit, + bool use_distance, + bool aprox_radius); protected: @@ -53,19 +41,14 @@ protected: _knotpoint; Gtk::Label _fillet_chamfer_position_label; - Gtk::Entry _fillet_chamfer_position_entry; + Gtk::SpinButton _fillet_chamfer_position_numeric; Gtk::RadioButton::Group _fillet_chamfer_type_group; Gtk::RadioButton _fillet_chamfer_type_fillet; Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; Gtk::RadioButton _fillet_chamfer_type_chamfer; Gtk::RadioButton _fillet_chamfer_type_double_chamfer; -#if WITH_GTKMM_3_0 - Gtk::Grid _layout_table; -#else Gtk::Table _layout_table; -#endif - bool _position_visible; double _index; @@ -83,10 +66,14 @@ protected: void _setPt(const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt); void _setUnit(const gchar *abbr); + void _set_use_distance(bool use_knot_distance); + void _set_aprox(bool aprox_radius); void _apply(); void _close(); bool _flexible; const gchar *unit; + bool use_distance; + bool aprox; void _setKnotPoint(Geom::Point knotpoint); void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); -- cgit v1.2.3 From 1e435432e61ca5794f784e3758d1034aa93cc171 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 12 Sep 2014 07:59:27 +0200 Subject: i18n. Fix for Bug #1368375 (Page titles in preferences don't escape text for markup) by houz. Fixed bugs: - https://launchpad.net/bugs/1368375 (bzr r13552) --- src/ui/dialog/inkscape-preferences.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 5d065dc60..e04748759 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -2054,7 +2054,8 @@ void InkscapePreferences::on_pagelist_selection_changed() if (!_init) { prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); } - _page_title.set_markup("" + row[_page_list_columns._col_name] + ""); + Glib::ustring col_name_escaped = Glib::Markup::escape_text( row[_page_list_columns._col_name] ); + _page_title.set_markup("" + col_name_escaped + ""); _page_frame.add(*_current_page); _current_page->show(); while (Gtk::Main::events_pending()) -- cgit v1.2.3 From e81250edbb1751c3626b01645872f74948081a19 Mon Sep 17 00:00:00 2001 From: su_v Date: Sat, 13 Sep 2014 19:48:17 +0200 Subject: Fix GTK3 build (bzr r13555) --- src/ui/dialog/inkscape-preferences.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index e04748759..7d43adc0f 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -19,6 +19,7 @@ #include "inkscape-preferences.h" #include +#include #include #include #include -- cgit v1.2.3 From 3f649ca279f98542e8147e9bd5ab67691c6e21a0 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Sep 2014 21:22:34 +0200 Subject: Fix bug in object dialog, in highlight color couldent select opacity, now fixed (bzr r13341.1.224) --- src/ui/dialog/objects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index ecd4ff42f..07a27c96e 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -1450,7 +1450,7 @@ void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) guint32 rgba = color.toRGBA32( alpha ); ObjectsPanel *ptr = reinterpret_cast(cp); - + //Set the highlight color for all items in the _highlight_target (all selected items) for (std::vector::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter) { -- cgit v1.2.3 From 3c73700a91c6dc1561b3b70dcdc0c051d23405d3 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 29 Sep 2014 15:57:21 +0200 Subject: Remove NRTypePosDef class and associated cruft. More direct CSS -> Pango translation. (bzr r13569) --- src/ui/dialog/text-edit.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index c1ebb32e0..a00db1715 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -32,7 +32,6 @@ extern "C" { #include #include -#include #include #include -- cgit v1.2.3 From e186cf544131e582a43316767257f199e6af986c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 29 Sep 2014 16:21:07 +0200 Subject: Remove NRTypePosDef class and associated cruft. More direct CSS -> Pango translation. (bzr r13341.1.233) --- src/ui/dialog/text-edit.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index e44809c65..9996fc0f9 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -32,7 +32,6 @@ extern "C" { #include #include -#include #include #include -- cgit v1.2.3 From 0b7731f9d93442ba18df146b85ce46bdb0c21220 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 1 Oct 2014 09:00:39 +0200 Subject: Fix for bug #690255 (Rename te_IN.po to te.po). Fixed bugs: - https://launchpad.net/bugs/690255 (bzr r13571) --- src/ui/dialog/inkscape-preferences.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 7d43adc0f..8d43358a7 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -526,11 +526,11 @@ void InkscapePreferences::initPageUI() _("Mongolian (mn)"), _("Nepali (ne)"), _("Norwegian Bokmål (nb)"), _("Norwegian Nynorsk (nn)"), _("Panjabi (pa)"), _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"), _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), - _("Swedish (sv)"),_("Telugu (te_IN)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")}; + _("Swedish (sv)"),_("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")}; Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "az", "eu", "be", "bg", "bn", "bn_BD", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "nl", "dz", "de", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", "fa", "fi", "fr", "ga", "gl", "he", "hu", "id", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "mn", "ne", "nb", "nn", "pa", - "pl", "pt", "pt_BR", "ro", "ru", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "te_IN", "th", "tr", "uk", "vi" }; + "pl", "pt", "pt_BR", "ro", "ru", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "te", "th", "tr", "uk", "vi" }; { // sorting languages according to translated name -- cgit v1.2.3 From 66fd1af880dddae1fa77e9c0cc22e475de4d54d2 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 2 Oct 2014 10:04:45 +0200 Subject: Fixing inconsistencies in the PixelArt dialog. (bzr r13575) --- src/ui/dialog/pixelartdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/pixelartdialog.cpp b/src/ui/dialog/pixelartdialog.cpp index 2d25f54d7..5113f172a 100644 --- a/src/ui/dialog/pixelartdialog.cpp +++ b/src/ui/dialog/pixelartdialog.cpp @@ -385,8 +385,8 @@ void PixelArtDialogImpl::vectorize() if ( input.pixbuf->get_width() > 256 || input.pixbuf->get_height() > 256 ) { - char *msg = _("Image looks too big. Process may take a while and is" - " wise to save your document before continue." + char *msg = _("Image looks too big. Process may take a while and it is" + " wise to save your document before continuing." "\n\nContinue the procedure (without saving)?"); Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK_CANCEL, true); -- cgit v1.2.3 From 50a19700fb02a712803aa3623f0920d562116534 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 2 Oct 2014 10:32:46 +0200 Subject: i18n. Fix for Bug #380522 (strings that need to be fixed for translation). Translations. Inkscape.pot and French translation update. Fixed bugs: - https://launchpad.net/bugs/380522 (bzr r13576) --- src/ui/dialog/filter-effects-dialog.cpp | 2 +- src/ui/dialog/inkscape-preferences.cpp | 8 ++++---- src/ui/dialog/input.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index c2367c2a2..bd44846a3 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -546,7 +546,7 @@ public: _matrix(SP_ATTR_VALUES, _("This matrix determines a linear transform on color space. Each line affects one of the color components. Each column determines how much of each color component from the input is passed to the output. The last column does not depend on input colors, so can be used to adjust a constant component value.")), _saturation("", 0, 0, 1, 0.1, 0.01, 2, SP_ATTR_VALUES), _angle("", 0, 0, 360, 0.1, 0.01, 1, SP_ATTR_VALUES), - _label(_("None"), Gtk::ALIGN_START), + _label(C_("Label", "None"), Gtk::ALIGN_START), _use_stored(false), _saturation_store(0), _angle_store(0) diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 8d43358a7..c2da12058 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -331,7 +331,7 @@ void InkscapePreferences::initPageTools() _page_selector.add_line( true, "", _t_sel_trans_outl, "", _("Show only a box outline of the objects when moving or transforming")); _page_selector.add_group_header( _("Per-object selection cue")); - _t_sel_cue_none.init ( _("None"), "/options/selcue/value", Inkscape::SelCue::NONE, false, 0); + _t_sel_cue_none.init ( C_("Selection cue", "None"), "/options/selcue/value", Inkscape::SelCue::NONE, false, 0); _page_selector.add_line( true, "", _t_sel_cue_none, "", _("No per-object selection indication")); _t_sel_cue_mark.init ( _("Mark"), "/options/selcue/value", Inkscape::SelCue::MARK, true, &_t_sel_cue_none); @@ -642,7 +642,7 @@ void InkscapePreferences::initPageUI() _win_save_viewport.init ( _("Save and restore documents viewport"), "/options/savedocviewport/value", true); _win_zoom_resize.init ( _("Zoom when window is resized"), "/options/stickyzoom/value", false); _win_show_close.init ( _("Show close button on dialogs"), "/dialogs/showclose", false); - _win_ontop_none.init ( _("None"), "/options/transientpolicy/value", 0, false, 0); + _win_ontop_none.init ( C_("Dialog on top", "None"), "/options/transientpolicy/value", 0, false, 0); _win_ontop_normal.init ( _("Normal"), "/options/transientpolicy/value", 1, true, &_win_ontop_none); _win_ontop_agressive.init ( _("Aggressive"), "/options/transientpolicy/value", 2, false, &_win_ontop_none); @@ -1260,7 +1260,7 @@ void InkscapePreferences::initPageBehavior() _page_steps.add_line( false, "", _steps_compass, "", _("When on, angles are displayed with 0 at north, 0 to 360 range, positive clockwise; otherwise with 0 at east, -180 to 180 range, positive counterclockwise")); int const num_items = 17; - Glib::ustring labels[num_items] = {"90", "60", "45", "36", "30", "22.5", "18", "15", "12", "10", "7.5", "6", "3", "2", "1", "0.5", _("None")}; + Glib::ustring labels[num_items] = {"90", "60", "45", "36", "30", "22.5", "18", "15", "12", "10", "7.5", "6", "3", "2", "1", "0.5", C_("Rotation angle", "None")}; int values[num_items] = {2, 3, 4, 5, 6, 8, 10, 12, 15, 18, 24, 30, 60, 90, 180, 360, 0}; _steps_rot_snap.set_size_request(_sb_width); _steps_rot_snap.init("/options/rotationsnapsperpi/value", labels, values, num_items, 12); @@ -1836,7 +1836,7 @@ void InkscapePreferences::initPageSpellcheck() AspellDictInfoEnumeration *dels = aspell_dict_info_list_elements(dlist); - languages.push_back(Glib::ustring(_("None"))); + languages.push_back(Glib::ustring(C_("Spellchecker language", "None"))); langValues.push_back(Glib::ustring("")); const AspellDictInfo *entry; diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 4be6716a5..8343cd6fe 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -1622,7 +1622,7 @@ void InputDialogImpl::ConfPanel::setAxis(gint count) if (barNum < count) { row[axisColumns.value] = Glib::ustring::format(barNum+1); } else { - row[axisColumns.value] = _("None"); + row[axisColumns.value] = C_("Input device axe", "None"); } } -- cgit v1.2.3 From 380f71793aba455f86eae2c75532b24dc613e71d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 3 Oct 2014 21:32:26 -0400 Subject: Refactor SPGuide to use more C++ (bzr r13341.1.241) --- src/ui/dialog/guides.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 76c26a3cb..4519a905f 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -100,7 +100,7 @@ void GuidelinePropertiesDialog::_onOK() double rad_angle = Geom::deg_to_rad( deg_angle ); normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0)); } - sp_guide_set_normal(*_guide, normal, true); + _guide->set_normal(normal, true); double const points_x = _spin_button_x.getValue("px"); double const points_y = _spin_button_y.getValue("px"); @@ -108,11 +108,11 @@ void GuidelinePropertiesDialog::_onOK() if (!_mode) newpos += _oldpos; - sp_guide_moveto(*_guide, newpos, true); + _guide->moveto(newpos, true); const gchar* name = g_strdup( _label_entry.getEntry()->get_text().c_str() ); - sp_guide_set_label(*_guide, name, true); + _guide->set_label(name, true); g_free((gpointer) name); #if WITH_GTKMM_3_0 @@ -124,7 +124,7 @@ void GuidelinePropertiesDialog::_onOK() #endif //TODO: why 257? verify this! - sp_guide_set_color(*_guide, r, g, b, true); + _guide->set_color(r, g, b, true); DocumentUndo::done(_guide->document, SP_VERB_NONE, _("Set guide properties")); @@ -295,16 +295,17 @@ void GuidelinePropertiesDialog::_setup() { signal_response().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_response)); // initialize dialog - _oldpos = _guide->point_on_line; + _oldpos = _guide->getPoint(); if (_guide->isVertical()) { _oldangle = 90; } else if (_guide->isHorizontal()) { _oldangle = 0; } else { - _oldangle = Geom::rad_to_deg( std::atan2( - _guide->normal_to_line[Geom::X], _guide->normal_to_line[Geom::Y] ) ); + _oldangle = Geom::rad_to_deg( std::atan2( - _guide->getNormal()[Geom::X], _guide->getNormal()[Geom::Y] ) ); } { + // FIXME holy crap!!! Inkscape::XML::Node *repr = _guide->getRepr(); const gchar *guide_id = repr->attribute("id"); gchar *label = g_strdup_printf(_("Guideline ID: %s"), guide_id); @@ -312,7 +313,7 @@ void GuidelinePropertiesDialog::_setup() { g_free(label); } { - gchar *guide_description = sp_guide_description(_guide, false); + gchar *guide_description = _guide->description(false); gchar *label = g_strdup_printf(_("Current: %s"), guide_description); g_free(guide_description); _label_descr.set_markup(label); @@ -320,15 +321,15 @@ void GuidelinePropertiesDialog::_setup() { } // init name entry - _label_entry.getEntry()->set_text(_guide->label ? _guide->label : ""); + _label_entry.getEntry()->set_text(_guide->getLabel() ? _guide->getLabel() : ""); #if WITH_GTKMM_3_0 Gdk::RGBA c; - c.set_rgba(((_guide->color>>24)&0xff) / 255.0, ((_guide->color>>16)&0xff) / 255.0, ((_guide->color>>8)&0xff) / 255.0); + c.set_rgba(((_guide->getColor()>>24)&0xff) / 255.0, ((_guide->getColor()>>16)&0xff) / 255.0, ((_guide->getColor()>>8)&0xff) / 255.0); _color.set_rgba(c); #else Gdk::Color c; - c.set_rgb_p(((_guide->color>>24)&0xff) / 255.0, ((_guide->color>>16)&0xff) / 255.0, ((_guide->color>>8)&0xff) / 255.0); + c.set_rgb_p(((_guide->getColor()>>24)&0xff) / 255.0, ((_guide->getColor()>>16)&0xff) / 255.0, ((_guide->getColor()>>8)&0xff) / 255.0); _color.set_color(c); #endif -- cgit v1.2.3 From efd39893a4f5e629a9df2d0674222aea1be14199 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 5 Oct 2014 12:38:15 -0400 Subject: Move obvious ui component to ui/ (bzr r13341.1.247) --- src/ui/dialog/clonetiler.cpp | 2 +- src/ui/dialog/dialog.cpp | 2 +- src/ui/dialog/dock-behavior.cpp | 2 +- src/ui/dialog/export.cpp | 2 +- src/ui/dialog/extension-editor.cpp | 2 +- src/ui/dialog/filedialogimpl-gtkmm.cpp | 2 +- src/ui/dialog/find.cpp | 2 +- src/ui/dialog/floating-behavior.cpp | 2 +- src/ui/dialog/ocaldialogs.cpp | 2 +- src/ui/dialog/spellcheck.cpp | 2 +- src/ui/dialog/template-load-tab.cpp | 2 +- src/ui/dialog/text-edit.cpp | 2 +- src/ui/dialog/xml-tree.cpp | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index d9e2c03ba..1d6d0403e 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -38,7 +38,7 @@ #include "util/units.h" #include "helper/window.h" #include "inkscape.h" -#include "interface.h" +#include "ui/interface.h" #include "macros.h" #include "message-stack.h" #include "preferences.h" diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 4f0d9fbe1..213965a18 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -28,7 +28,7 @@ #include "desktop-handles.h" #include "shortcuts.h" #include "preferences.h" -#include "interface.h" +#include "ui/interface.h" #include "verbs.h" #include "ui/tool/event-utils.h" diff --git a/src/ui/dialog/dock-behavior.cpp b/src/ui/dialog/dock-behavior.cpp index f65b298c9..50a6db208 100644 --- a/src/ui/dialog/dock-behavior.cpp +++ b/src/ui/dialog/dock-behavior.cpp @@ -18,7 +18,7 @@ #include "dock-behavior.h" #include "inkscape.h" #include "desktop.h" -#include "interface.h" +#include "ui/interface.h" #include "widgets/icon.h" #include "ui/widget/dock.h" #include "verbs.h" diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index cd8fdbd92..a4d8801f7 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -65,7 +65,7 @@ #include "ui/dialog-events.h" #include "preferences.h" #include "verbs.h" -#include "interface.h" +#include "ui/interface.h" #include "sp-root.h" #include "extension/output.h" diff --git a/src/ui/dialog/extension-editor.cpp b/src/ui/dialog/extension-editor.cpp index cd5491c24..9bdddc0e0 100644 --- a/src/ui/dialog/extension-editor.cpp +++ b/src/ui/dialog/extension-editor.cpp @@ -25,7 +25,7 @@ #include "verbs.h" #include "preferences.h" -#include "interface.h" +#include "ui/interface.h" #include "extension/extension.h" #include "extension/db.h" diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 5778b44db..511237f4d 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -23,7 +23,7 @@ #include "filedialogimpl-gtkmm.h" #include "ui/dialog-events.h" -#include "interface.h" +#include "ui/interface.h" #include "io/sys.h" #include "path-prefix.h" #include "preferences.h" diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 9b814bb9f..1a4823e4a 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -33,7 +33,7 @@ #include "ui/dialog-events.h" #include "verbs.h" -#include "interface.h" +#include "ui/interface.h" #include "preferences.h" #include "sp-text.h" #include "sp-flowtext.h" diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp index f286588b2..11db14801 100644 --- a/src/ui/dialog/floating-behavior.cpp +++ b/src/ui/dialog/floating-behavior.cpp @@ -29,7 +29,7 @@ #include "inkscape.h" #include "desktop.h" #include "ui/dialog-events.h" -#include "interface.h" +#include "ui/interface.h" #include "preferences.h" #include "verbs.h" diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index 607087f6d..c4dd9df98 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -25,7 +25,7 @@ #include "path-prefix.h" #include "filedialogimpl-gtkmm.h" -#include "interface.h" +#include "ui/interface.h" #include "gc-core.h" #include "ui/dialog-events.h" #include "io/sys.h" diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index a887a7355..b8436ebf1 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -25,7 +25,7 @@ #include "desktop-handles.h" #include "tools-switch.h" #include "ui/tools/text-tool.h" -#include "interface.h" +#include "ui/interface.h" #include "preferences.h" #include "sp-text.h" #include "sp-flowtext.h" diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp index d75f81456..13cb01eef 100644 --- a/src/ui/dialog/template-load-tab.cpp +++ b/src/ui/dialog/template-load-tab.cpp @@ -24,7 +24,7 @@ #include "extension/db.h" #include "extension/effect.h" #include "inkscape.h" -#include "interface.h" +#include "ui/interface.h" #include "file.h" #include "path-prefix.h" #include "preferences.h" diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 9996fc0f9..0f4a6f7f1 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -51,7 +51,7 @@ extern "C" { #include "ui/icon-names.h" #include "preferences.h" #include "verbs.h" -#include "interface.h" +#include "ui/interface.h" #include "svg/css-ostringstream.h" #include "widgets/icon.h" #include "widgets/font-selector.h" diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 9a8c188b2..7ab6c78ba 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -30,7 +30,7 @@ #include "ui/tools/tool-base.h" #include "helper/window.h" #include "inkscape.h" -#include "interface.h" +#include "ui/interface.h" #include "macros.h" #include "message-context.h" #include "message-stack.h" -- cgit v1.2.3 From b700110359cc8bba13357efe42f1b1bdb8069ed8 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 5 Oct 2014 21:48:43 +0200 Subject: Use actual SVG width and height property values in preview image text. (bzr r13341.1.251) --- src/ui/dialog/filedialogimpl-gtkmm.cpp | 40 ++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 511237f4d..2c13d40b6 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -40,6 +40,8 @@ #include #include +#include + #include "document.h" #include "extension/input.h" #include "extension/output.h" @@ -191,6 +193,40 @@ void SVGPreview::showImage(Glib::ustring &theFileName) { Glib::ustring fileName = theFileName; + // Let's get real width and height from SVG file. These are template + // files so we assume they are well formed. + + // std::cout << "SVGPreview::showImage: " << theFileName << std::endl; + std::ifstream input(theFileName.c_str()); + + std::string width; + std::string height; + + if( !input ) { + std::cout << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; + } else { + + std::string token; + + Glib::MatchInfo match_info; + Glib::RefPtr regex1 = Glib::Regex::create("width=\"(.*)\""); + Glib::RefPtr regex2 = Glib::Regex::create("height=\"(.*)\""); + + while( !input.eof() && (height.empty() || width.empty()) ) { + + input >> token; + // std::cout << "|" << token << "|" << std::endl; + + if (regex1->match(token, match_info)) { + width = match_info.fetch(1).raw(); + } + + if (regex2->match(token, match_info)) { + height = match_info.fetch(1).raw(); + } + + } + } /*##################################### # LET'S HAVE SOME FUN WITH SVG! @@ -270,7 +306,7 @@ void SVGPreview::showImage(Glib::ustring &theFileName) " style=\"font-size:24.000000;font-style:normal;font-weight:normal;" " fill:#000000;fill-opacity:1.0000000;stroke:none;" " font-family:Sans\"\n" - " x=\"10\" y=\"26\">%d x %d\n" //# VALUES HERE + " x=\"10\" y=\"26\">%s x %s\n" //# VALUES HERE "\n\n"; // if (!Glib::get_charset()) //If we are not utf8 @@ -280,7 +316,7 @@ void SVGPreview::showImage(Glib::ustring &theFileName) /* FIXME: Do proper XML quoting for fileName. */ gchar *xmlBuffer = g_strdup_printf(xformat, previewWidth, previewHeight, imgX, imgY, scaledImgWidth, scaledImgHeight, - fileName.c_str(), rectX, rectY, rectWidth, rectHeight, imgWidth, imgHeight); + fileName.c_str(), rectX, rectY, rectWidth, rectHeight, width.c_str(), height.c_str() ); // g_message("%s\n", xmlBuffer); -- cgit v1.2.3 From 8a779e74c5243e3efe16431fdd215efe4380bcfc Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 5 Oct 2014 22:07:53 +0200 Subject: Attempt to fix build breakage reported by su_v (but not seen locally). (bzr r13341.1.252) --- src/ui/dialog/filedialogimpl-gtkmm.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 2c13d40b6..5d330f7f0 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -21,6 +21,8 @@ #include #endif +#include + #include "filedialogimpl-gtkmm.h" #include "ui/dialog-events.h" #include "ui/interface.h" @@ -203,7 +205,7 @@ void SVGPreview::showImage(Glib::ustring &theFileName) std::string height; if( !input ) { - std::cout << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; + std::cerr << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; } else { std::string token; -- cgit v1.2.3 From 156cf3323a936c7dfccd9e09458cd8b5d174b7fe Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 5 Oct 2014 19:24:27 -0400 Subject: Move more UI code into ui/ (bzr r13341.1.253) --- src/ui/dialog/align-and-distribute.cpp | 2 +- src/ui/dialog/document-properties.cpp | 4 ++-- src/ui/dialog/objects.cpp | 2 +- src/ui/dialog/spellcheck.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 8352de1e3..431da7ad1 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -38,7 +38,7 @@ #include "sp-item-transform.h" #include "sp-text.h" #include "text-editing.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/icon-names.h" #include "ui/tools/node-tool.h" #include "ui/tool/multi-path-manipulator.h" diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 2a3a1dd86..071ac037f 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -31,13 +31,13 @@ #include "inkscape.h" #include "io/sys.h" #include "preferences.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-namedview.h" #include "sp-root.h" #include "sp-script.h" #include "style.h" #include "svg/stringstream.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/widget/color-picker.h" #include "ui/widget/scalar-unit.h" #include "ui/dialog/filedialog.h" diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 07a27c96e..93d5dfbd5 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -43,7 +43,7 @@ #include "sp-root.h" #include "sp-shape.h" #include "style.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/icon-names.h" #include "ui/widget/imagetoggler.h" #include "ui/widget/layertypeicon.h" diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index b8436ebf1..9faa8a2cb 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -23,7 +23,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-handles.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tools/text-tool.h" #include "ui/interface.h" #include "preferences.h" -- cgit v1.2.3 From 259976c863ccdd6c28698125179b20b91da32ec0 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 9 Oct 2014 14:27:49 +0200 Subject: Apply cx, cy, etc. from template to newly created document window. (bzr r13341.1.264) --- src/ui/dialog/template-widget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index 9758b35ac..f79d166f2 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -24,6 +24,7 @@ #include "document.h" #include "document-undo.h" #include "file.h" +#include "sp-namedview.h" #include "extension/implementation/implementation.h" #include "inkscape.h" @@ -69,7 +70,10 @@ void TemplateWidget::create() _current_template.tpl_effect->effect(desc); DocumentUndo::clearUndo(sp_desktop_document(desc)); sp_desktop_document(desc)->setModifiedSinceSave(false); - + + // Apply cx,cy etc. from document + sp_namedview_window_from_document( desc ); + if (desktop) desktop->clearWaitingCursor(); } -- cgit v1.2.3 From 01a8acb49126aa37fee65b3e350ce69e87abecc8 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 9 Oct 2014 14:32:16 +0200 Subject: Apply cx, cy, etc. from template to newly created document window. (bzr r13586) --- src/ui/dialog/template-widget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index 9758b35ac..f79d166f2 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -24,6 +24,7 @@ #include "document.h" #include "document-undo.h" #include "file.h" +#include "sp-namedview.h" #include "extension/implementation/implementation.h" #include "inkscape.h" @@ -69,7 +70,10 @@ void TemplateWidget::create() _current_template.tpl_effect->effect(desc); DocumentUndo::clearUndo(sp_desktop_document(desc)); sp_desktop_document(desc)->setModifiedSinceSave(false); - + + // Apply cx,cy etc. from document + sp_namedview_window_from_document( desc ); + if (desktop) desktop->clearWaitingCursor(); } -- cgit v1.2.3 From a2c47e60a02938013ab913bfee2ef9c9fa5ea870 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 13 Oct 2014 11:11:01 +0200 Subject: Fixed: "Called C++ object pointer is null" (bzr r13609) --- src/ui/dialog/clonetiler.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index e5f18216c..9b67132c0 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -2235,7 +2235,11 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) gdk_window_process_all_updates(); SPObject *obj = selection->singleItem(); - SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; + if (!obj) { + // Should never happen (empty selection checked above). + std::cerr << "CloneTiler::clonetile_apply(): No object in single item selection!!!" << std::endl; + return; + } Inkscape::XML::Node *obj_repr = obj->getRepr(); const char *id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); SPObject *parent = obj->parent; @@ -2326,6 +2330,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) bool invert_picked = prefs->getBool(prefs_path + "invert_picked"); double gamma_picked = prefs->getDoubleLimited(prefs_path + "gamma_picked", 0, -10, 10); + SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; if (dotrace) { clonetiler_trace_setup (sp_desktop_document(desktop), 1.0, item); } -- cgit v1.2.3 From 83e50305d77a98329ea2085f90b6a9f154e1509f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 15 Oct 2014 20:01:50 +0200 Subject: LiamW's initial font caching work. (bzr r13616.1.1) --- src/ui/dialog/text-edit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index a00db1715..9996fc0f9 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -343,9 +343,9 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - // This is done for us by text-toolbar. No need to do it twice. - // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); - // fontlister->selection_update(); + // This is normally done for us by text-toolbar but only when we are in text editing context + fontlister->update_font_list(sp_desktop_document(this->desktop)); + fontlister->selection_update(); Glib::ustring fontspec = fontlister->get_fontspec(); -- cgit v1.2.3 From 43d418f2720546f501594e30e24151248b2a67e8 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 21 Oct 2014 09:21:06 +0200 Subject: Updating translators list. (bzr r13631) --- src/ui/dialog/aboutbox.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index f3cffa244..fad10ae11 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -452,13 +452,13 @@ void AboutBox::initStrings() { */ gchar const *allTranslators = "3ARRANO.com <3arrano@3arrano.com>, 2005.\n" -"Adib Taraben , 2004.\n" +"Adib Taraben , 2004-2014.\n" "Alan Monfort , 2009-2010.\n" "Alastair McKinstry , 2000.\n" "Aleksandar Urošević , 2004-2006.\n" "Alessio Frusciante , 2002, 2003.\n" "Alexander Shopov , 2006.\n" -"Alexandre Prokoudine , 2005, 2010-2013.\n" +"Alexandre Prokoudine , 2005, 2010-2014.\n" "Alexey Remizov , 2004.\n" "Ali Ghanavatian , 2010.\n" "Álvaro Lopes , 2001, 2002.\n" @@ -503,7 +503,7 @@ void AboutBox::initStrings() { "Hleb Valoshka <375gnu@gmail.com>, 2008-2009.\n" "Hizkuntza Politikarako Sailburuordetza , 2005.\n" "Ilia Penev , 2006.\n" -"Ivan Masár , 2006-2010. \n" +"Ivan Masár , 2006-2014. \n" "Ivan Řihošek , 2014.\n" "Iñaki Larrañaga , 2006.\n" "Jānis Eisaks , 2012-2014.\n" @@ -537,7 +537,7 @@ void AboutBox::initStrings() { "Mahesh subedi , 2006.\n" "Martin Srebotnjak, , 2005, 2010.\n" "Masatake YAMATO , 2002.\n" -"Masato Hashimoto , 2009-2012.\n" +"Masato Hashimoto , 2009-2014.\n" "Matiphas , 2004-2006.\n" "Mattias Hultgren , 2005, 2006.\n" "Maxim Dziumanenko , 2004.\n" @@ -553,7 +553,7 @@ void AboutBox::initStrings() { "Przemysław Loesch , 2005.\n" "Quico Llach , 2000. Traducció sodipodi.\n" "Raymond Ostertag , 2002, 2003.\n" -"Riku Leino , 2006.\n" +"Riku Leino , 2006-2011.\n" "Rune Rønde Laursen , 2006.\n" "Ruud Steltenpool , 2006.\n" "Serdar Soytetir , 2005.\n" @@ -569,9 +569,11 @@ void AboutBox::initStrings() { "Thiago Pimentel , 2006.\n" "Toshifumi Sato , 2005.\n" "Jon South , 2006. \n" -"Uwe Schöler , 2006-2013.\n" +"Uwe Schöler , 2006-2014.\n" "Valek Filippov , 2000, 2003.\n" "Victor Dachev , 2006.\n" +"Victor Westmann , 2011, 2014.\n" +"Ville Pätsi, 2013.\n" "Vincent van Adrighem , 2003.\n" "Vital Khilko , 2003.\n" "Vitaly Lipatov , 2002, 2004.\n" @@ -584,7 +586,7 @@ void AboutBox::initStrings() { "Yaron Shahrabani , 2009.\n" "Yukihiro Nakai , 2000, 2003.\n" "Yuri Beznos , 2006.\n" -"Yuri Chornoivan , 2007-2013.\n" +"Yuri Chornoivan , 2007-2014.\n" "Yuri Syrota , 2000.\n" "Yves Guillou , 2004.\n" "Zdenko Podobný , 2003, 2004." -- cgit v1.2.3 From 1784329fa3ac4a56944fe03a3b439c4fcd31dea1 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 1 Nov 2014 13:47:00 -0700 Subject: Warning cleanup. (bzr r13653) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 2 +- src/ui/dialog/lpe-powerstroke-properties.cpp | 2 +- src/ui/dialog/objects.cpp | 2 +- src/ui/dialog/tags.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index ad8b66b8c..a8870e69b 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -177,7 +177,7 @@ void FilletChamferPropertiesDialog::_close() ); } -bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey *event) +bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey * /*event*/) { return false; } diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp index c34351511..55f938a48 100644 --- a/src/ui/dialog/lpe-powerstroke-properties.cpp +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -152,7 +152,7 @@ PowerstrokePropertiesDialog::_close() ); } -bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey *event) +bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey * /*event*/) { /*switch (get_group0_keyval(event)) { diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 93d5dfbd5..c95529a56 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -988,7 +988,7 @@ void ObjectsPanel::_storeHighlightTarget(const Gtk::TreeModel::iterator& iter) /* * Drap and drop within the tree */ -bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr& /*context*/, int x, int y, guint /*time*/) { int cell_x = 0, cell_y = 0; Gtk::TreeModel::Path target_path; diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 127e4d95e..ba1052ede 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -380,7 +380,7 @@ void TagsPanel::_objectsSelected( Selection *sel ) { _checkTreeSelection(); } -bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) +bool TagsPanel::_checkForSelected(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) { Gtk::TreeModel::Row row = *iter; SPObject * it = row[_model->_colObject]; @@ -754,7 +754,7 @@ void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) * Drap and drop within the tree * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer */ -bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +bool TagsPanel::_handleDragDrop(const Glib::RefPtr& /*context*/, int x, int y, guint /*time*/) { int cell_x = 0, cell_y = 0; Gtk::TreeModel::Path target_path; @@ -885,7 +885,7 @@ void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name } } -bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ ) { return false; } -- cgit v1.2.3 From db7a155b8fdaeff84faba30e953df1cfd2cacc1a Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 1 Nov 2014 18:57:10 -0700 Subject: Warning cleanup. (bzr r13657) --- src/ui/dialog/tags.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index ba1052ede..8a104d137 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -393,6 +393,7 @@ bool TagsPanel::_checkForSelected(const Gtk::TreePath &/*path*/, const Gtk::Tree return false; } +// TODO does not look good that we're ignoring the passed in root. Investigate. void TagsPanel::_objectsChanged(SPObject* root) { while (!_objectWatchers.empty()) -- cgit v1.2.3 From 3dfff76972208b0328ac7937bb9e9fe037560a26 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 3 Nov 2014 21:54:01 +0100 Subject: Update fillet/chamfer to allow subdivisions in chamfer mode. Still happends bug affecting only selected nodes in document:units diferent than "px". I think the problem is node->position() send me a bad data if document units not px. (bzr r13665) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 28 +++++++++++++++---------- src/ui/dialog/lpe-fillet-chamfer-properties.h | 3 ++- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index a8870e69b..85a2ccd3f 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -46,7 +46,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() Gtk::Box *mainVBox = get_vbox(); mainVBox->set_homogeneous(false); _layout_table.set_spacings(4); - _layout_table.resize(2, 2); + _layout_table.resize(3, 3); // Layer name widgets _fillet_chamfer_position_numeric.set_digits(4); @@ -61,20 +61,30 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() Gtk::FILL); _layout_table.attach(_fillet_chamfer_position_numeric, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + _fillet_chamfer_chamfer_subdivisions.set_digits(0); + _fillet_chamfer_chamfer_subdivisions.set_increments(1,1); + //todo: get tha max aloable infinity freeze the widget + _fillet_chamfer_chamfer_subdivisions.set_range(0, 999999999999999999); + + _fillet_chamfer_chamfer_subdivisions_label.set_label(_("Chamfer subdivisions:")); + _fillet_chamfer_chamfer_subdivisions_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_fillet_chamfer_chamfer_subdivisions_label, 0, 1, 1, 2, Gtk::FILL, + Gtk::FILL); + _layout_table.attach(_fillet_chamfer_chamfer_subdivisions, 1, 2, 1, 2, + Gtk::FILL | Gtk::EXPAND, Gtk::FILL); _fillet_chamfer_type_fillet.set_label(_("Fillet")); _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_chamfer.set_label(_("Chamfer")); _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group); - _fillet_chamfer_type_double_chamfer.set_label(_("Double chamfer")); - _fillet_chamfer_type_double_chamfer.set_group(_fillet_chamfer_type_group); + mainVBox->pack_start(_layout_table, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4); - mainVBox->pack_start(_fillet_chamfer_type_double_chamfer, true, true, 4); // Buttons _close_button.set_use_stock(true); @@ -146,10 +156,8 @@ void FilletChamferPropertiesDialog::_apply() d_width = 1; } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { d_width = 2; - } else if (_fillet_chamfer_type_chamfer.get_active() == true) { - d_width = 3; } else { - d_width = 4; + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3; } if (_flexible) { if (d_pos > 99.99999 || d_pos < 0) { @@ -218,10 +226,8 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) _fillet_chamfer_type_fillet.set_active(true); } else if (knotpoint.y() == 2) { _fillet_chamfer_type_inverse_fillet.set_active(true); - } else if (knotpoint.y() == 3) { - _fillet_chamfer_type_chamfer.set_active(true); - } else if (knotpoint.y() == 1) { - _fillet_chamfer_type_double_chamfer.set_active(true); + } else if (knotpoint.y() >= 3) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3); } } diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 47ff97b00..deae0cee0 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -46,7 +46,8 @@ protected: Gtk::RadioButton _fillet_chamfer_type_fillet; Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; Gtk::RadioButton _fillet_chamfer_type_chamfer; - Gtk::RadioButton _fillet_chamfer_type_double_chamfer; + Gtk::Label _fillet_chamfer_chamfer_subdivisions_label; + Gtk::SpinButton _fillet_chamfer_chamfer_subdivisions; Gtk::Table _layout_table; bool _position_visible; -- cgit v1.2.3 From ff6f0db21af7e564e205dcec40a886ce2b674608 Mon Sep 17 00:00:00 2001 From: Masato Hashimoto Date: Wed, 5 Nov 2014 07:01:12 +0100 Subject: i18n. Fix for bug #1389509 (typos in trunk-r13669). (bzr r13670) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index 85a2ccd3f..fa909924d 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -202,7 +202,7 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) double position; std::string distance_or_radius = std::string(_("Radius ")); if(aprox){ - distance_or_radius = std::string(_("Radius aproximated ")); + distance_or_radius = std::string(_("Radius approximated ")); } if(use_distance){ distance_or_radius = std::string(_("Knot distance ")); -- cgit v1.2.3 From 42eb288d19390918f05c6f0754e45d25f9881a19 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 5 Nov 2014 22:06:17 +0100 Subject: Fixing typos found by Firas Hanife. (bzr r13673) --- src/ui/dialog/inkscape-preferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index c2da12058..a98494e18 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -838,7 +838,7 @@ void InkscapePreferences::initPageIO() _save_use_current_dir.init( _("Use current directory for \"Save As ...\""), "/dialogs/save_as/use_current_dir", true); _page_io.add_line( false, "", _save_use_current_dir, "", - _("When this option is on, the \"Save as...\" and \"Save a Copy\" dialogs will always open in the directory where the currently open document is; when it's off, each will open in the directory where you last saved a file using it"), true); + _("When this option is on, the \"Save as...\" and \"Save a Copy...\" dialogs will always open in the directory where the currently open document is; when it's off, each will open in the directory where you last saved a file using it"), true); _misc_comment.init( _("Add label comments to printing output"), "/printing/debug/show-label-comments", false); _page_io.add_line( false, "", _misc_comment, "", -- cgit v1.2.3 From ff6dc09cde0fcbcf1064d94c9161643a163b1f91 Mon Sep 17 00:00:00 2001 From: Ryan Lerch Date: Fri, 7 Nov 2014 17:46:20 -0500 Subject: fixed typo in src/ui/dialog/Makefile_insert -- dialpg to dialog (bzr r13675) --- src/ui/dialog/Makefile_insert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 26a59ce2c..cbdae1cb0 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -101,7 +101,7 @@ ink_common_sources += \ ui/dialog/template-widget.cpp \ ui/dialog/template-widget.h \ ui/dialog/tags.cpp \ - ui/dialpg/tags.h \ + ui/dialog/tags.h \ ui/dialog/text-edit.cpp \ ui/dialog/text-edit.h \ ui/dialog/tile.cpp \ -- cgit v1.2.3 From 965e178e307b4c82ad8b618cf6af6d3c3c31d2cb Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 8 Nov 2014 12:25:15 +0100 Subject: Black list some properties that shouldn't appear in default styles. (bzr r13679) --- src/ui/dialog/inkscape-preferences.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index a98494e18..75cfe5bfe 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -234,6 +234,9 @@ static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatc if (!css) return; + // remove black-listed properties + css = sp_css_attr_unset_blacklist (css); + // only store text style for the text tool if (prefs_path != "/tools/text") { css = sp_css_attr_unset_text (css); -- cgit v1.2.3 From d8559463c6b3e2656bb0726e9dcb7680c4ae3283 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 8 Nov 2014 22:53:49 +0100 Subject: export dialog, small code cleanup, should be a noop. (check if pointer is nullptr, instead of checking the pre-condition for newing into the pointer) (bzr r13687) --- src/ui/dialog/export.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index a4d8801f7..b044a6e2c 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -537,7 +537,7 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl sb->set_sensitive (sensitive); pos++; - if (!ll.empty()) { + if (l) { l->set_mnemonic_widget(*sb); } -- cgit v1.2.3 From 05a8ca8653fefcdc59e3ee1d1416829ec2712c8f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 10 Nov 2014 00:50:46 +0100 Subject: fix a bug pointed by su_v in fillet chamfer dialog, about units (bzr r13697) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 34 +++++++++++++++---------- src/ui/dialog/lpe-fillet-chamfer-properties.h | 13 ++++++---- 2 files changed, 29 insertions(+), 18 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index fa909924d..e9d69b464 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -116,7 +116,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() FilletChamferPropertiesDialog::~FilletChamferPropertiesDialog() { - _setDesktop(NULL); + _set_desktop(NULL); } void FilletChamferPropertiesDialog::showDialog( @@ -125,16 +125,18 @@ void FilletChamferPropertiesDialog::showDialog( FilletChamferPointArrayParamKnotHolderEntity *pt, const gchar *unit, bool use_distance, - bool aprox_radius) + bool aprox_radius, + Glib::ustring const * documentUnit) { FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog(); - dialog->_setDesktop(desktop); - dialog->_setUnit(unit); + dialog->_set_desktop(desktop); + dialog->_set_unit(unit); dialog->_set_use_distance(use_distance); dialog->_set_aprox(aprox_radius); - dialog->_setKnotPoint(knotpoint); - dialog->_setPt(pt); + dialog->_set_document_unit(documentUnit); + dialog->_set_knot_point(knotpoint); + dialog->_set_pt(pt); dialog->set_title(_("Modify Fillet-Chamfer")); dialog->_apply_button.set_label(_("_Modify")); @@ -165,7 +167,7 @@ void FilletChamferPropertiesDialog::_apply() } d_pos = _index + (d_pos / 100); } else { - d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, "px"); + d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, *document_unit); d_pos = d_pos * -1; } _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); @@ -175,7 +177,7 @@ void FilletChamferPropertiesDialog::_apply() void FilletChamferPropertiesDialog::_close() { - _setDesktop(NULL); + _set_desktop(NULL); destroy_(); Glib::signal_idle().connect( sigc::bind_return( @@ -197,7 +199,7 @@ void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event) } } -void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) +void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint) { double position; std::string distance_or_radius = std::string(_("Radius ")); @@ -219,7 +221,8 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) std::string(_("(")) + std::string(unit) + std::string(")"); _fillet_chamfer_position_label.set_label(_(posConcat.c_str())); position = knotpoint[Geom::X] * -1; - position = Inkscape::Util::Quantity::convert(position, "px", unit); + + position = Inkscape::Util::Quantity::convert(position, *document_unit, unit); } _fillet_chamfer_position_numeric.set_value(position); if (knotpoint.y() == 1) { @@ -231,7 +234,7 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) } } -void FilletChamferPropertiesDialog::_setPt( +void FilletChamferPropertiesDialog::_set_pt( const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt) { @@ -240,11 +243,16 @@ void FilletChamferPropertiesDialog::_setPt( pt); } -void FilletChamferPropertiesDialog::_setUnit(const gchar *abbr) +void FilletChamferPropertiesDialog::_set_unit(const gchar *abbr) { unit = abbr; } +void FilletChamferPropertiesDialog::_set_document_unit(Glib::ustring const *abbr) +{ + document_unit = abbr; +} + void FilletChamferPropertiesDialog::_set_use_distance(bool use_knot_distance) { use_distance = use_knot_distance; @@ -255,7 +263,7 @@ void FilletChamferPropertiesDialog::_set_aprox(bool aprox_radius) aprox = aprox_radius; } -void FilletChamferPropertiesDialog::_setDesktop(SPDesktop *desktop) +void FilletChamferPropertiesDialog::_set_desktop(SPDesktop *desktop) { if (desktop) { Inkscape::GC::anchor(desktop); diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index deae0cee0..ec87addc5 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -32,7 +32,8 @@ public: FilletChamferPointArrayParamKnotHolderEntity *pt, const gchar *unit, bool use_distance, - bool aprox_radius); + bool aprox_radius, + Glib::ustring const * documentUnit); protected: @@ -63,19 +64,21 @@ protected: return instance; } - void _setDesktop(SPDesktop *desktop); - void _setPt(const Inkscape::LivePathEffect:: + void _set_desktop(SPDesktop *desktop); + void _set_pt(const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt); - void _setUnit(const gchar *abbr); + void _set_unit(const gchar *abbr); + void _set_document_unit(Glib::ustring const * abbr); void _set_use_distance(bool use_knot_distance); void _set_aprox(bool aprox_radius); void _apply(); void _close(); bool _flexible; const gchar *unit; + Glib::ustring const * document_unit; bool use_distance; bool aprox; - void _setKnotPoint(Geom::Point knotpoint); + void _set_knot_point(Geom::Point knotpoint); void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); bool _handleKeyEvent(GdkEventKey *event); -- cgit v1.2.3 From 46314979be91405f5a1fb31b1ac8b5c62b622948 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Mon, 10 Nov 2014 09:04:48 -0800 Subject: Fix 32-bit build break. (bzr r13699) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index e9d69b464..e55c9f8df 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -64,7 +64,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() _fillet_chamfer_chamfer_subdivisions.set_digits(0); _fillet_chamfer_chamfer_subdivisions.set_increments(1,1); //todo: get tha max aloable infinity freeze the widget - _fillet_chamfer_chamfer_subdivisions.set_range(0, 999999999999999999); + _fillet_chamfer_chamfer_subdivisions.set_range(0, 999999999999999999.0); _fillet_chamfer_chamfer_subdivisions_label.set_label(_("Chamfer subdivisions:")); _fillet_chamfer_chamfer_subdivisions_label.set_alignment(1.0, 0.5); -- cgit v1.2.3 From e179290f049d5c34ae2b9c05fdfeab830b7c39e7 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Mon, 10 Nov 2014 09:39:33 -0800 Subject: Removed SP_USE/SP_IS_USE Gtk-ish macros and cleaned affected files. (bzr r13700) --- src/ui/dialog/clonetiler.cpp | 22 ++++-- src/ui/dialog/find.cpp | 93 ++++++++++++++--------- src/ui/dialog/livepatheffect-editor.cpp | 127 +++++++++++++++++--------------- src/ui/dialog/symbols.cpp | 22 +++--- 4 files changed, 152 insertions(+), 112 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 5ef885ab2..d1a675735 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1,5 +1,6 @@ -/** @file +/** + * @file * Clone tiling dialog */ /* Authors: @@ -2002,7 +2003,7 @@ bool CloneTiler::clonetiler_is_a_clone_of(SPObject *tile, SPObject *obj) id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); } - if (SP_IS_USE(tile) && + if (dynamic_cast(tile) && tile->getRepr()->attribute("xlink:href") && (!id_href || !strcmp(id_href, tile->getRepr()->attribute("xlink:href"))) && tile->getRepr()->attribute("inkscape:tiled-clone-of") && @@ -2025,8 +2026,10 @@ void CloneTiler::clonetiler_trace_hide_tiled_clones_recursively(SPObject *from) return; for (SPObject *o = from->firstChild(); o != NULL; o = o->next) { - if (SP_IS_ITEM(o) && clonetiler_is_a_clone_of (o, NULL)) - SP_ITEM(o)->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too! + SPItem *item = dynamic_cast(o); + if (item && clonetiler_is_a_clone_of(o, NULL)) { + item->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too! + } clonetiler_trace_hide_tiled_clones_recursively (o); } } @@ -2160,7 +2163,9 @@ void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool d } } for (GSList *i = to_delete; i; i = i->next) { - SP_OBJECT(i->data)->deleteObject(); + SPObject *obj = reinterpret_cast(i->data); + g_assert(obj != NULL); + obj->deleteObject(); } g_slist_free (to_delete); @@ -2330,7 +2335,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) bool invert_picked = prefs->getBool(prefs_path + "invert_picked"); double gamma_picked = prefs->getDoubleLimited(prefs_path + "gamma_picked", 0, -10, 10); - SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; + SPItem *item = dynamic_cast(obj); if (dotrace) { clonetiler_trace_setup (sp_desktop_document(desktop), 1.0, item); } @@ -2621,9 +2626,10 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) if (center_set) { SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); - if (clone_object && SP_IS_ITEM(clone_object)) { + SPItem *item = dynamic_cast(clone_object); + if (clone_object && item) { clone_object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - SP_ITEM(clone_object)->setCenter(desktop->doc2dt(new_center)); + item->setCenter(desktop->doc2dt(new_center)); clone_object->updateRepr(); } } diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 1a4823e4a..1a7832688 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -241,7 +241,7 @@ Find::Find() Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); SPItem *item = selection->singleItem(); if (item) { - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + if (dynamic_cast(item) || dynamic_cast(item)) { gchar *str; str = sp_te_get_string_multiline (item); entry_find.getEntry()->set_text(str); @@ -343,7 +343,7 @@ bool Find::item_text_match (SPItem *item, const gchar *find, bool exact, bool ca return false; } - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + if (dynamic_cast(item) || dynamic_cast(item)) { const gchar *item_text = sp_te_get_string_multiline (item); if (item_text == NULL) { return false; @@ -388,7 +388,7 @@ bool Find::item_id_match (SPItem *item, const gchar *id, bool exact, bool casema return false; } - if (SP_IS_STRING(item)) { // SPStrings have "on demand" ids which are useless for searching + if (dynamic_cast(item)) { // SPStrings have "on demand" ids which are useless for searching return false; } @@ -561,11 +561,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (check_searchin_text.get_active()) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_text_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_text_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_text_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_text_match(item, text, exact, casematch, _action_replace); } } } @@ -581,11 +584,13 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (ids) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_id_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + if (item_id_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_id_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_id_match(item, text, exact, casematch, _action_replace); } } } @@ -595,12 +600,15 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (style) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_style_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_style_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_style_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_style_match(item, text, exact, casematch, _action_replace); } } } @@ -610,11 +618,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (attrname) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_attr_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_attr_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_attr_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_attr_match(item, text, exact, casematch, _action_replace); } } } @@ -624,11 +635,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (attrvalue) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_attrvalue_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_attrvalue_match(item, text, exact, casematch, _action_replace); } } } @@ -638,11 +652,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (font) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_font_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_font_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_font_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_font_match(item, text, exact, casematch, _action_replace); } } } @@ -661,34 +678,34 @@ bool Find::item_type_match (SPItem *item) { bool all =check_alltypes.get_active(); - if ( SP_IS_RECT(item)) { + if ( dynamic_cast(item)) { return ( all ||check_rects.get_active()); - } else if (SP_IS_GENERICELLIPSE(item)) { + } else if (dynamic_cast(item)) { return ( all || check_ellipses.get_active()); - } else if (SP_IS_STAR(item) || SP_IS_POLYGON(item)) { + } else if (dynamic_cast(item) || dynamic_cast(item)) { return ( all || check_stars.get_active()); - } else if (SP_IS_SPIRAL(item)) { + } else if (dynamic_cast(item)) { return ( all || check_spirals.get_active()); - } else if (SP_IS_PATH(item) || SP_IS_LINE(item) || SP_IS_POLYLINE(item)) { + } else if (dynamic_cast(item) || dynamic_cast(item) || dynamic_cast(item)) { return (all || check_paths.get_active()); - } else if (SP_IS_TEXT(item) || SP_IS_TSPAN(item) || SP_IS_TREF(item) || SP_IS_STRING(item)) { + } else if (dynamic_cast(item) || dynamic_cast(item) || dynamic_cast(item) || dynamic_cast(item)) { return (all || check_texts.get_active()); - } else if (SP_IS_GROUP(item) && !desktop->isLayer(item) ) { // never select layers! + } else if (dynamic_cast(item) && !desktop->isLayer(item) ) { // never select layers! return (all || check_groups.get_active()); - } else if (SP_IS_USE(item)) { + } else if (dynamic_cast(item)) { return (all || check_clones.get_active()); - } else if (SP_IS_IMAGE(item)) { + } else if (dynamic_cast(item)) { return (all || check_images.get_active()); - } else if (SP_IS_OFFSET(item)) { + } else if (dynamic_cast(item)) { return (all || check_offsets.get_active()); } @@ -699,7 +716,10 @@ GSList *Find::filter_types (GSList *l) { GSList *n = NULL; for (GSList *i = l; i != NULL; i = i->next) { - if (item_type_match (SP_ITEM(i->data))) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_type_match(item)) { n = g_slist_prepend (n, i->data); } } @@ -716,7 +736,7 @@ GSList *Find::filter_list (GSList *l, bool exact, bool casematch) GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) { - if (SP_IS_DEFS(r)) { + if (dynamic_cast(r)) { return l; // we're not interested in items in defs } @@ -725,8 +745,8 @@ GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) } for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - if (SP_IS_ITEM(child) && !child->cloned && !desktop->isLayer(SP_ITEM(child))) { - SPItem *item = reinterpret_cast(child); + SPItem *item = dynamic_cast(child); + if (item && !child->cloned && !desktop->isLayer(item)) { if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) { l = g_slist_prepend (l, child); } @@ -739,16 +759,18 @@ GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) GSList *Find::all_selection_items (Inkscape::Selection *s, GSList *l, SPObject *ancestor, bool hidden, bool locked) { for (GSList *i = (GSList *) s->itemList(); i != NULL; i = i->next) { - if (SP_IS_ITEM (i->data) && !reinterpret_cast(i->data)->cloned && !desktop->isLayer(SP_ITEM(i->data))) { - SPItem *item = reinterpret_cast(i->data); + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item && !item->cloned && !desktop->isLayer(item)) { if (!ancestor || ancestor->isAncestorOf(item)) { if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) { l = g_slist_prepend (l, i->data); } } } - if (!ancestor || ancestor->isAncestorOf(SP_OBJECT (i->data))) { - l = all_items (SP_OBJECT (i->data), l, hidden, locked); + if (!ancestor || ancestor->isAncestorOf(item)) { + l = all_items(item, l, hidden, locked); } } return l; @@ -831,7 +853,10 @@ void Find::onAction() Inkscape::Selection *selection = sp_desktop_selection (desktop); selection->clear(); selection->setList(n); - scroll_to_show_item (desktop, SP_ITEM(n->data)); + SPObject *obj = reinterpret_cast(n->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + scroll_to_show_item(desktop, item); if (_action_replace) { DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Replace text or property")); diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 9a569725c..eb3857ee7 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -295,9 +295,8 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); if ( item ) { - if ( SP_IS_LPE_ITEM(item) ) { - SPLPEItem *lpeitem = SP_LPE_ITEM(item); - + SPLPEItem *lpeitem = dynamic_cast(item); + if ( lpeitem ) { effect_list_reload(lpeitem); current_lpeitem = lpeitem; @@ -318,25 +317,28 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) button_up.set_sensitive(false); button_down.set_sensitive(false); } - } else if ( SP_IS_USE(item) ) { - // test whether linked object is supported by the CLONE_ORIGINAL LPE - SPItem *orig = SP_USE(item)->get_original(); - if ( SP_IS_SHAPE(orig) || - SP_IS_TEXT(orig) ) - { - // Note that an SP_USE cannot have an LPE applied, so we only need to worry about the "add effect" case. - set_sensitize_all(true); - showText(_("Click add button to convert clone")); - button_remove.set_sensitive(false); - button_up.set_sensitive(false); - button_down.set_sensitive(false); + } else { + SPUse *use = dynamic_cast(item); + if ( use ) { + // test whether linked object is supported by the CLONE_ORIGINAL LPE + SPItem *orig = use->get_original(); + if ( dynamic_cast(orig) || + dynamic_cast(orig) ) + { + // Note that an SP_USE cannot have an LPE applied, so we only need to worry about the "add effect" case. + set_sensitize_all(true); + showText(_("Click add button to convert clone")); + button_remove.set_sensitive(false); + button_up.set_sensitive(false); + button_down.set_sensitive(false); + } else { + showText(_("Select a path or shape")); + set_sensitize_all(false); + } } else { showText(_("Select a path or shape")); set_sensitize_all(false); } - } else { - showText(_("Select a path or shape")); - set_sensitize_all(false); } } else { showText(_("Only one item can be selected")); @@ -423,7 +425,7 @@ LivePathEffectEditor::onAdd() if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); if (item) { - if ( SP_IS_LPE_ITEM(item) ) { + if ( dynamic_cast(item) ) { // show effectlist dialog using Inkscape::UI::Dialog::LivePathEffectAdd; LivePathEffectAdd::show(current_desktop); @@ -439,7 +441,7 @@ LivePathEffectEditor::onAdd() } // If item is a SPRect, convert it to path first: - if ( SP_IS_RECT(item) ) { + if ( dynamic_cast(item) ) { sp_selected_path_to_curves(sel, current_desktop, false); item = sel->singleItem(); // get new item } @@ -451,41 +453,43 @@ LivePathEffectEditor::onAdd() lpe_list_locked = false; onSelectionChanged(sel); - } - else if ( SP_IS_USE(item) ) { - // item is a clone. do not show effectlist dialog. - // convert to path, apply CLONE_ORIGINAL LPE, link it to the cloned path - - // test whether linked object is supported by the CLONE_ORIGINAL LPE - SPItem *orig = SP_USE(item)->get_original(); - if ( SP_IS_SHAPE(orig) || - SP_IS_TEXT(orig) ) - { - // select original - sel->set(orig); - - // delete clone but remember its id and transform - gchar *id = g_strdup(item->getRepr()->attribute("id")); - gchar *transform = g_strdup(item->getRepr()->attribute("transform")); - item->deleteObject(false); - item = NULL; - - // run sp_selection_clone_original_path_lpe - sp_selection_clone_original_path_lpe(current_desktop); - SPItem *new_item = sel->singleItem(); - new_item->getRepr()->setAttribute("id", id); - new_item->getRepr()->setAttribute("transform", transform); - g_free(id); - g_free(transform); - - /// \todo Add the LPE stack of the original path? - - SPDocument *doc = current_desktop->doc(); - DocumentUndo::done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT, - _("Create and apply Clone original path effect")); - - lpe_list_locked = false; - onSelectionChanged(sel); + } else { + SPUse *use = dynamic_cast(item); + if ( use ) { + // item is a clone. do not show effectlist dialog. + // convert to path, apply CLONE_ORIGINAL LPE, link it to the cloned path + + // test whether linked object is supported by the CLONE_ORIGINAL LPE + SPItem *orig = use->get_original(); + if ( dynamic_cast(orig) || + dynamic_cast(orig) ) + { + // select original + sel->set(orig); + + // delete clone but remember its id and transform + gchar *id = g_strdup(item->getRepr()->attribute("id")); + gchar *transform = g_strdup(item->getRepr()->attribute("transform")); + item->deleteObject(false); + item = NULL; + + // run sp_selection_clone_original_path_lpe + sp_selection_clone_original_path_lpe(current_desktop); + SPItem *new_item = sel->singleItem(); + new_item->getRepr()->setAttribute("id", id); + new_item->getRepr()->setAttribute("transform", transform); + g_free(id); + g_free(transform); + + /// \todo Add the LPE stack of the original path? + + SPDocument *doc = current_desktop->doc(); + DocumentUndo::done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Create and apply Clone original path effect")); + + lpe_list_locked = false; + onSelectionChanged(sel); + } } } } @@ -498,13 +502,14 @@ LivePathEffectEditor::onRemove() Inkscape::Selection *sel = _getSelection(); if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); - if ( item && SP_IS_LPE_ITEM(item) ) { - SP_LPE_ITEM(item)->removeCurrentPathEffect(false); + SPLPEItem *lpeitem = dynamic_cast(item); + if ( lpeitem ) { + lpeitem->removeCurrentPathEffect(false); DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Remove path effect") ); - effect_list_reload(SP_LPE_ITEM(item)); + effect_list_reload(lpeitem); } } @@ -515,7 +520,8 @@ void LivePathEffectEditor::onUp() Inkscape::Selection *sel = _getSelection(); if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); - if ( SPLPEItem *lpeitem = SP_LPE_ITEM(item) ) { + SPLPEItem *lpeitem = dynamic_cast(item); + if ( lpeitem ) { lpeitem->upCurrentPathEffect(); DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, @@ -531,7 +537,8 @@ void LivePathEffectEditor::onDown() Inkscape::Selection *sel = _getSelection(); if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); - if ( SPLPEItem *lpeitem = SP_LPE_ITEM(item) ) { + SPLPEItem *lpeitem = dynamic_cast(item); + if ( lpeitem ) { lpeitem->downCurrentPathEffect(); DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index a9cf8d068..a17a03861 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -298,8 +298,7 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : // This might need to be a global variable so setTargetDesktop can modify it SPDefs *defs = currentDocument->getDefs(); - sigc::connection defsModifiedConn = (SP_OBJECT(defs))->connectModified( - sigc::mem_fun(*this, &SymbolsDialog::defsModified)); + sigc::connection defsModifiedConn = defs->connectModified(sigc::mem_fun(*this, &SymbolsDialog::defsModified)); instanceConns.push_back(defsModifiedConn); sigc::connection selectionChangedConn = currentDesktop->selection->connectChanged( @@ -658,11 +657,11 @@ GSList* SymbolsDialog::symbols_in_doc_recursive (SPObject *r, GSList *l) g_return_val_if_fail(r != NULL, l); // Stop multiple counting of same symbol - if( SP_IS_USE(r) ) { + if ( dynamic_cast(r) ) { return l; } - if( SP_IS_SYMBOL(r) ) { + if ( dynamic_cast(r) ) { l = g_slist_prepend (l, r); } @@ -684,7 +683,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) { GSList* SymbolsDialog::use_in_doc_recursive (SPObject *r, GSList *l) { - if( SP_IS_USE(r) ) { + if ( dynamic_cast(r) ) { l = g_slist_prepend (l, r); } @@ -709,8 +708,9 @@ gchar const* SymbolsDialog::style_from_use( gchar const* id, SPDocument* documen gchar const* style = 0; GSList* l = use_in_doc( document ); for( ; l != NULL; l = l->next ) { - SPObject* use = SP_OBJECT(l->data); - if( SP_IS_USE( use ) ) { + SPObject *obj = reinterpret_cast(l->data); + SPUse *use = dynamic_cast(obj); + if ( use ) { gchar const *href = use->getRepr()->attribute("xlink:href"); if( href ) { Glib::ustring href2(href); @@ -730,8 +730,9 @@ void SymbolsDialog::add_symbols( SPDocument* symbolDocument ) { GSList* l = symbols_in_doc( symbolDocument ); for( ; l != NULL; l = l->next ) { - SPObject* symbol = SP_OBJECT(l->data); - if (SP_IS_SYMBOL(symbol)) { + SPObject *obj = reinterpret_cast(l->data); + SPSymbol *symbol = dynamic_cast(obj); + if (symbol) { add_symbol( symbol ); } } @@ -820,7 +821,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol) previewDocument->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); previewDocument->ensureUpToDate(); - SPItem *item = SP_ITEM(object_temp); + SPItem *item = dynamic_cast(object_temp); + g_assert(item != NULL); unsigned psize = SYMBOL_ICON_SIZES[pack_size]; Glib::RefPtr pixbuf(NULL); -- cgit v1.2.3 From 87469d81799b58681b91800234f266ea8b19b30b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Nov 2014 01:08:40 +0100 Subject: Add inverse subdivision chamfer to fillet chamfer LPE, feature sugested by Ivan Louette. (bzr r13708) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 15 ++++++++++++--- src/ui/dialog/lpe-fillet-chamfer-properties.h | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index e55c9f8df..55a19fc51 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -79,12 +79,15 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_chamfer.set_label(_("Chamfer")); _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_inverse_chamfer.set_label(_("Inverse chamfer")); + _fillet_chamfer_type_inverse_chamfer.set_group(_fillet_chamfer_type_group); mainVBox->pack_start(_layout_table, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_inverse_chamfer, true, true, 4); // Buttons _close_button.set_use_stock(true); @@ -158,8 +161,10 @@ void FilletChamferPropertiesDialog::_apply() d_width = 1; } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { d_width = 2; + } else if (_fillet_chamfer_type_inverse_chamfer.get_active() == true) { + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 4000; } else { - d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3; + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3000; } if (_flexible) { if (d_pos > 99.99999 || d_pos < 0) { @@ -229,8 +234,12 @@ void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint) _fillet_chamfer_type_fillet.set_active(true); } else if (knotpoint.y() == 2) { _fillet_chamfer_type_inverse_fillet.set_active(true); - } else if (knotpoint.y() >= 3) { - _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3); + } else if (knotpoint.y() >= 3000 && knotpoint.y() < 4000) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3000); + _fillet_chamfer_type_chamfer.set_active(true); + } else if (knotpoint.y() >= 4000 && knotpoint.y() < 5000) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 4000); + _fillet_chamfer_type_inverse_chamfer.set_active(true); } } diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index ec87addc5..3807e98c8 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -47,6 +47,7 @@ protected: Gtk::RadioButton _fillet_chamfer_type_fillet; Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; Gtk::RadioButton _fillet_chamfer_type_chamfer; + Gtk::RadioButton _fillet_chamfer_type_inverse_chamfer; Gtk::Label _fillet_chamfer_chamfer_subdivisions_label; Gtk::SpinButton _fillet_chamfer_chamfer_subdivisions; -- cgit v1.2.3 From 692ee3551c1a101b16134b0b446ab98231fa4d1f Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 15 Nov 2014 10:37:38 -0800 Subject: Purged GTKish macros SP_SCRIPT/SP_IS_SCRIPT. (bzr r13712) --- src/ui/dialog/document-properties.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/ui/dialog') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index dc8a0fee2..6064c2a5e 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1205,10 +1205,10 @@ void DocumentProperties::removeExternalScript(){ const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); while ( current ) { - if (current->data && SP_IS_OBJECT(current->data)) { - SPObject* obj = SP_OBJECT(current->data); - SPScript* script = SP_SCRIPT(obj); - if (name == script->xlinkhref){ + SPObject* obj = reinterpret_cast(current->data); + if (obj) { + SPScript* script = dynamic_cast(obj); + if (script && (name == script->xlinkhref)) { //XML Tree being used directly here while it shouldn't be. Inkscape::XML::Node *repr = obj->getRepr(); @@ -1354,10 +1354,15 @@ void DocumentProperties::populate_script_lists(){ _ExternalScriptsListStore->clear(); _EmbeddedScriptsListStore->clear(); const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - if (current) _scripts_observer.set(SP_OBJECT(current->data)->parent); + if (current) { + SPObject *obj = reinterpret_cast(current->data); + g_assert(obj != NULL); + _scripts_observer.set(obj->parent); + } while ( current ) { - SPObject* obj = SP_OBJECT(current->data); - SPScript* script = SP_SCRIPT(obj); + SPObject* obj = reinterpret_cast(current->data); + SPScript* script = dynamic_cast(obj); + g_assert(script != NULL); if (script->xlinkhref) { Gtk::TreeModel::Row row = *(_ExternalScriptsListStore->append()); -- cgit v1.2.3