Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / ui / dialog / swatches.cpp
index 6cef5bedd2ee6ec0502b5dc7b2e2859f2ab14dc0..b2b1b26da5372ffa90117f8302a27e68f6588f9f 100644 (file)
@@ -5,6 +5,7 @@
 /* Authors:
  *   Jon A. Cruz
  *   John Bintz
+ *   Abhishek Sharma
  *
  * Copyright (C) 2005 Jon A. Cruz
  * Copyright (C) 2008 John Bintz
@@ -14,6 +15,7 @@
 
 #include <errno.h>
 #include <map>
+#include <algorithm>
 
 #include <gtk/gtkdialog.h> //for GTK_RESPONSE* types
 #include <gtk/gtkdnd.h>
@@ -49,7 +51,7 @@
 #include "widgets/eek-preview.h"
 #include "display/nr-plain-stuff.h"
 #include "sp-gradient-reference.h"
-
+#include "dialog-manager.h"
 
 namespace Inkscape {
 namespace UI {
@@ -72,7 +74,8 @@ static std::map<SwatchesPanel*, SPDocument*> docPerPanel;
 class SwatchesPanelHook : public SwatchesPanel
 {
 public:
-    static void convertGradient( GtkMenuItem * menuitem, gpointer userData );
+    static void convertGradient( GtkMenuItem *menuitem, gpointer userData );
+    static void deleteGradient( GtkMenuItem *menuitem, gpointer userData );
 };
 
 static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) {
@@ -111,11 +114,37 @@ static void redirSecondaryClick( GtkMenuItem *menuitem, gpointer /*user_data*/ )
     }
 }
 
-static void editGradientImpl( SPGradient* gr )
+static void editGradientImpl( SPDesktop* desktop, SPGradient* gr )
 {
     if ( gr ) {
-        GtkWidget *dialog = sp_gradient_vector_editor_new( gr );
-        gtk_widget_show( dialog );
+        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<GSList *>(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);
+            }
+        }
+
+        if (!shown) {
+            GtkWidget *dialog = sp_gradient_vector_editor_new( gr );
+            gtk_widget_show( dialog );
+        }
     }
 }
 
@@ -127,11 +156,11 @@ static void editGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ )
         SPDocument *doc = desktop ? desktop->doc() : 0;
         if (doc) {
             std::string targetName(bounceTarget->def.descr);
-            const GSList *gradients = doc->get_resource_list("gradient");
+            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( grad );
+                    editGradientImpl( desktop, grad );
                     break;
                 }
             }
@@ -139,56 +168,45 @@ static void editGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ )
     }
 }
 
-static void addNewGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ )
+void SwatchesPanelHook::convertGradient( GtkMenuItem * /*menuitem*/, gpointer userData )
 {
     if ( bounceTarget ) {
         SwatchesPanel* swp = bouncePanel;
         SPDesktop* desktop = swp ? swp->getDesktop() : 0;
         SPDocument *doc = desktop ? desktop->doc() : 0;
-        if (doc) {
-            Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
-
-            Inkscape::XML::Node *repr = xml_doc->createElement("svg:linearGradient");
-            repr->setAttribute("osb:paint", "solid");
-            Inkscape::XML::Node *stop = xml_doc->createElement("svg:stop");
-            stop->setAttribute("offset", "0");
-            stop->setAttribute("style", "stop-color:#000;stop-opacity:1;");
-            repr->appendChild(stop);
-            Inkscape::GC::release(stop);
-
-            SP_OBJECT_REPR( SP_DOCUMENT_DEFS(doc) )->addChild(repr, NULL);
-
-            SPGradient * gr = static_cast<SPGradient *>(doc->getObjectByRepr(repr));
-
-            Inkscape::GC::release(repr);
-
+        gint index = GPOINTER_TO_INT(userData);
+        if ( doc && (index >= 0) && (static_cast<guint>(index) < popupItems.size()) ) {
+            Glib::ustring targetName = popupItems[index];
 
-            editGradientImpl( gr );
+            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 SwatchesPanelHook::convertGradient( GtkMenuItem * /*menuitem*/, gpointer userData )
+void SwatchesPanelHook::deleteGradient( 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<guint>(index) < popupItems.size()) ) {
-            Glib::ustring targetName = popupItems[index];
-
-            const GSList *gradients = doc->get_resource_list("gradient");
+        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() ) {
-                                       //XML Tree being used directly here while it shouldn't be
-                    grad->getRepr()->setAttribute("osb:paint", "solid"); // TODO make conditional
-
-                    SPDocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT,
-                                     _("Add gradient stop"));
-
-                    handleGradientsChange(doc); // work-around for signal not being emitted
+                    grad->setSwatch(false);
+                    DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT,
+                                       _("Delete"));
                     break;
                 }
             }
@@ -251,17 +269,13 @@ gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, g
             gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child);
             popupExtras.push_back(child);
 
-            child = gtk_menu_item_new_with_label(_("Add"));
+            child = gtk_menu_item_new_with_label(_("Delete"));
             g_signal_connect( G_OBJECT(child),
                               "activate",
-                              G_CALLBACK(addNewGradient),
+                              G_CALLBACK(SwatchesPanelHook::deleteGradient),
                               user_data );
             gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child);
             popupExtras.push_back(child);
-
-            child = gtk_menu_item_new_with_label(_("Delete"));
-            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..."));
@@ -307,7 +321,7 @@ gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, g
                     SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt);
                     if ( dtw && dtw->desktop ) {
                         // Pick up all gradients with vectors
-                        const GSList *gradients = (dtw->desktop->doc())->get_resource_list("gradient");
+                        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);
@@ -423,7 +437,7 @@ void _loadPaletteFile( gchar const *filename )
                                     if ( !hasErr && *ptr ) {
                                         char* n = trim(ptr);
                                         if (n != NULL) {
-                                            name = n;
+                                            name = g_dpgettext2(NULL, "Palette", n);
                                         }
                                     }
                                     if ( !hasErr ) {
@@ -760,7 +774,7 @@ void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document )
             }
             docPerPanel[panel] = document;
             if (!found) {
-                sigc::connection conn1 = document->resources_changed_connect( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) );
+                sigc::connection conn1 = document->connectResourcesChanged( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) );
                 sigc::connection conn2 = SP_DOCUMENT_DEFS(document)->connectRelease( sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document)) );
                 sigc::connection conn3 = SP_DOCUMENT_DEFS(document)->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document))) );
 
@@ -798,7 +812,7 @@ static void recalcSwatchContents(SPDocument* doc,
 {
     std::vector<SPGradient*> newList;
 
-    const GSList *gradients = doc->get_resource_list("gradient");
+    const GSList *gradients = doc->getResourceList("gradient");
     for (const GSList *item = gradients; item; item = item->next) {
         SPGradient* grad = SP_GRADIENT(item->data);
         if ( grad->isSwatch() ) {
@@ -807,6 +821,7 @@ static void recalcSwatchContents(SPDocument* doc,
     }
 
     if ( !newList.empty() ) {
+        std::reverse(newList.begin(), newList.end());
         for ( std::vector<SPGradient*>::iterator it = newList.begin(); it != newList.end(); ++it )
         {
             SPGradient* grad = *it;
@@ -888,21 +903,25 @@ void SwatchesPanel::handleDefsModified(SPDocument *document)
         std::map<ColorItem*, SPGradient*> tmpGrads;
         recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads);
 
-        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->setPixData(tmpPrevs[newColor], PREVIEW_PIXBUF_WIDTH, VBLOCK);
+        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->setPixData(tmpPrevs[newColor], PREVIEW_PIXBUF_WIDTH, VBLOCK);
+                }
             }
         }
     }
@@ -949,7 +968,7 @@ void SwatchesPanel::_updateFromSelection()
                             }
                         }
                         if ( target ) {
-                                                       //XML Tree being used directly here while it shouldn't be
+                            //XML Tree being used directly here while it shouldn't be
                             gchar const* id = target->getRepr()->attribute("id");
                             if ( id ) {
                                 fillId = id;
@@ -981,8 +1000,7 @@ void SwatchesPanel::_updateFromSelection()
                             }
                         }
                         if ( target ) {
-
-                                                       //XML Tree being used directly here while it shouldn't be
+                            //XML Tree being used directly here while it shouldn't be
                             gchar const* id = target->getRepr()->attribute("id");
                             if ( id ) {
                                 strokeId = id;
@@ -1060,4 +1078,4 @@ void SwatchesPanel::_rebuild()
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :