Code

Refactoring SPColor to C++ and removing legacy CMYK implementation
[inkscape.git] / src / dialogs / swatches.cpp
index 1d429603d571fb168f86c6f9b00cb6a8e709beee..3a41c1ec4a4629b096f828952bd921657a997711 100644 (file)
@@ -30,6 +30,7 @@
 #include "path-prefix.h"
 #include "swatches.h"
 #include "sp-item.h"
+#include "prefs-utils.h"
 
 #include "eek-preview.h"
 
@@ -42,6 +43,7 @@ SwatchesPanel* SwatchesPanel::instance = 0;
 
 ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) :
     def( r, g, b, name ),
+    _isLive(false),
     _linkIsTone(false),
     _linkPercent(0),
     _linkGray(0),
@@ -96,19 +98,24 @@ typedef enum {
 } colorFlavorType;
 
 static const GtkTargetEntry sourceColorEntries[] = {
+#if ENABLE_MAGIC_COLORS
 //    {"application/x-inkscape-color-id", GTK_TARGET_SAME_APP, APP_X_INKY_COLOR_ID},
     {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
+#endif // ENABLE_MAGIC_COLORS
     {"application/x-color", 0, APP_X_COLOR},
     {"text/plain", 0, TEXT_DATA},
 };
 
-static void dragGetColorData( GtkWidget *widget,
-                              GdkDragContext *drag_context,
-                              GtkSelectionData *data,
-                              guint info,
-                              guint time,
-                              gpointer user_data)
+void ColorItem::_dragGetColorData( GtkWidget *widget,
+                                   GdkDragContext *drag_context,
+                                   GtkSelectionData *data,
+                                   guint info,
+                                   guint time,
+                                   gpointer user_data)
 {
+    (void)widget;
+    (void)drag_context;
+    (void)time;
     static GdkAtom typeXColor = gdk_atom_intern("application/x-color", FALSE);
     static GdkAtom typeText = gdk_atom_intern("text/plain", FALSE);
 
@@ -148,19 +155,19 @@ static void dragGetColorData( GtkWidget *widget,
 //         } else {
 //             g_message("Unable to find the color");
 //         }
-        int itemCount = 4 + 1 + 1 + paletteName.length();
+        int itemCount = 4 + 2 + 1 + paletteName.length();
 
-        guint16* tmp = new guint16[itemCount]
-;
+        guint16* tmp = new guint16[itemCount];
         tmp[0] = (item->def.getR() << 8) | item->def.getR();
         tmp[1] = (item->def.getG() << 8) | item->def.getG();
         tmp[2] = (item->def.getB() << 8) | item->def.getB();
         tmp[3] = 0xffff;
+        tmp[4] = (item->_isLive || !item->_listeners.empty() || (item->_linkSrc != 0) ) ? 1 : 0;
 
-        tmp[4] = index;
-        tmp[5] = paletteName.length();
+        tmp[5] = index;
+        tmp[6] = paletteName.length();
         for ( unsigned int i = 0; i < paletteName.length(); i++ ) {
-            tmp[6 + i] = paletteName[i];
+            tmp[7 + i] = paletteName[i];
         }
         gtk_selection_data_set( data,
                                 typeXColor,
@@ -184,6 +191,7 @@ static void dragGetColorData( GtkWidget *widget,
 
 static void dragBegin( GtkWidget *widget, GdkDragContext* dc, gpointer data )
 {
+    (void)widget;
     ColorItem* item = reinterpret_cast<ColorItem*>(data);
     if ( item )
     {
@@ -210,18 +218,31 @@ static void dragBegin( GtkWidget *widget, GdkDragContext* dc, gpointer data )
 //     return TRUE;
 // }
 
-static void bouncy( GtkWidget* widget, gpointer callback_data ) {
-    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
-    if ( item ) {
-        item->buttonClicked(false);
+static gboolean onButtonPressed (GtkWidget *widget, GdkEventButton *event, gpointer userdata)
+{
+    (void)widget;
+    /* single click with the right mouse button? */
+    if(event->type == GDK_BUTTON_RELEASE)
+    {
+        ColorItem* item = reinterpret_cast<ColorItem*>(userdata);
+        if(item)
+        {
+            if (event->button == 1)
+            { 
+                               if(event->state & GDK_SHIFT_MASK)
+                                       item->buttonClicked(true);      /* the button was pressed with shift held down. set the stroke */
+                else item->buttonClicked(false);
+                return TRUE; /* we handled this */    
+            }
+            else if (event->button == 3)
+            {
+                item->buttonClicked(true);
+                return TRUE; /* we handled this */
+            }
+        }
     }
-}
 
-static void bouncy2( GtkWidget* widget, gint arg1, gpointer callback_data ) {
-    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
-    if ( item ) {
-        item->buttonClicked(true);
-    }
+    return FALSE; /* we did not handle this */
 }
 
 static void dieDieDie( GtkObject *obj, gpointer user_data )
@@ -230,8 +251,10 @@ static void dieDieDie( GtkObject *obj, gpointer user_data )
 }
 
 static const GtkTargetEntry destColorTargets[] = {
+#if ENABLE_MAGIC_COLORS
 //    {"application/x-inkscape-color-id", GTK_TARGET_SAME_APP, APP_X_INKY_COLOR_ID},
     {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
+#endif // ENABLE_MAGIC_COLORS
     {"application/x-color", 0, APP_X_COLOR},
 };
 
@@ -245,6 +268,11 @@ void ColorItem::_dropDataIn( GtkWidget *widget,
                              guint event_time,
                              gpointer user_data)
 {
+    (void)widget;
+    (void)drag_context;
+    (void)x;
+    (void)y;
+    (void)event_time;
 //     g_message("    droppy droppy   %d", info);
      switch (info) {
          case APP_X_INKY_COLOR:
@@ -299,7 +327,7 @@ static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::u
     bool changed = false;
 
     if ( node ) {
-        gchar const * val = node->attribute("HOTFill");
+        gchar const * val = node->attribute("inkscape:x-fill-tag");
         if ( val  && (match == val) ) {
             SPObject *obj = document->getObjectByRepr( node );
 
@@ -314,7 +342,7 @@ static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::u
             changed = true;
         }
 
-        val = node->attribute("HOTStroke");
+        val = node->attribute("inkscape:x-stroke-tag");
         if ( val  && (match == val) ) {
             SPObject *obj = document->getObjectByRepr( node );
 
@@ -351,7 +379,9 @@ void ColorItem::_colorDefChanged(void* data)
                                        (item->def.getG() << 8) | item->def.getG(),
                                        (item->def.getB() << 8) | item->def.getB() );
 
-                eek_preview_set_linked( preview, (LinkType)((item->_linkSrc ? PREVIEW_LINK_IN:0) | (item->_listeners.empty() ? 0:PREVIEW_LINK_OUT)) );
+                eek_preview_set_linked( preview, (LinkType)((item->_linkSrc ? PREVIEW_LINK_IN:0)
+                                                            | (item->_listeners.empty() ? 0:PREVIEW_LINK_OUT)
+                                                            | (item->_isLive ? PREVIEW_LINK_OTHER:0)) );
 
                 widget->queue_draw();
             }
@@ -380,7 +410,7 @@ void ColorItem::_colorDefChanged(void* data)
         {
             SPDesktop *desktop = SP_ACTIVE_DESKTOP;
             if ( desktop ) {
-                SPDocument* document = SP_DT_DOCUMENT( desktop );
+                SPDocument* document = sp_desktop_document( desktop );
                 Inkscape::XML::Node *rroot =  sp_document_repr_root( document );
                 if ( rroot ) {
 
@@ -409,7 +439,8 @@ void ColorItem::_colorDefChanged(void* data)
                         str = 0;
 
                         if ( bruteForce( document, rroot, paletteName, item->def.getR(), item->def.getG(), item->def.getB() ) ) {
-                            sp_document_done( document );
+                            sp_document_done( document , SP_VERB_DIALOG_SWATCHES, 
+                                              _("Change color definition"));
                         }
                     }
                 }
@@ -419,7 +450,7 @@ void ColorItem::_colorDefChanged(void* data)
 }
 
 
-Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, Gtk::BuiltinIconSize size)
+Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, Inkscape::IconSize size)
 {
     Gtk::Widget* widget = 0;
     if ( style == PREVIEW_STYLE_BLURB ) {
@@ -428,7 +459,7 @@ Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, Gtk::Built
         widget = lbl;
     } else {
         Glib::ustring blank("          ");
-        if ( size == Gtk::ICON_SIZE_MENU ) {
+        if ( size == Inkscape::ICON_SIZE_MENU || size == Inkscape::ICON_SIZE_DECORATION ) {
             blank = " ";
         }
 
@@ -439,7 +470,9 @@ Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, Gtk::Built
         eek_preview_set_color( preview, (def.getR() << 8) | def.getR(), (def.getG() << 8) | def.getG(), (def.getB() << 8) | def.getB());
 
         eek_preview_set_details( preview, (::PreviewStyle)style, (::ViewType)view, (::GtkIconSize)size );
-        eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0) | (_listeners.empty() ? 0:PREVIEW_LINK_OUT)) );
+        eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0)
+                                                    | (_listeners.empty() ? 0:PREVIEW_LINK_OUT)
+                                                    | (_isLive ? PREVIEW_LINK_OTHER:0)) );
 
         def.addCallback( _colorDefChanged, this );
 
@@ -468,15 +501,10 @@ Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, Gtk::Built
         sigc::signal<void> type_signal_something;
 */
         g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "clicked",
-                          G_CALLBACK(bouncy),
-                          this);
-
-        g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "alt-clicked",
-                          G_CALLBACK(bouncy2),
+                          "button-release-event",
+                          G_CALLBACK(onButtonPressed),
                           this);
-
+                          
         gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()),
                              GDK_BUTTON1_MASK,
                              sourceColorEntries,
@@ -485,7 +513,7 @@ Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, Gtk::Built
 
         g_signal_connect( G_OBJECT(newBlot->gobj()),
                           "drag-data-get",
-                          G_CALLBACK(dragGetColorData),
+                          G_CALLBACK(ColorItem::_dragGetColorData),
                           this);
 
         g_signal_connect( G_OBJECT(newBlot->gobj()),
@@ -541,7 +569,8 @@ void ColorItem::buttonClicked(bool secondary)
         sp_desktop_set_style(desktop, css);
 
         sp_repr_css_attr_unref(css);
-        sp_document_done (SP_DT_DOCUMENT (desktop));
+        sp_document_done (sp_desktop_document (desktop), SP_VERB_DIALOG_SWATCHES, 
+                          secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"));
     }
 }
 
@@ -584,12 +613,12 @@ bool parseNum( char*& str, int& val ) {
 static bool getBlock( std::string& dst, guchar ch, std::string const str )
 {
     bool good = false;
-    size_t pos = str.find(ch);
+    std::string::size_type pos = str.find(ch);
     if ( pos != std::string::npos )
     {
-        size_t pos2 = str.find( '(', pos );
+        std::string::size_type pos2 = str.find( '(', pos );
         if ( pos2 != std::string::npos ) {
-            size_t endPos = str.find( ')', pos2 );
+            std::string::size_type endPos = str.find( ')', pos2 );
             if ( endPos != std::string::npos ) {
                 dst = str.substr( pos2 + 1, (endPos - pos2 - 1) );
                 good = true;
@@ -602,7 +631,7 @@ static bool getBlock( std::string& dst, guchar ch, std::string const str )
 static bool popVal( guint64& numVal, std::string& str )
 {
     bool good = false;
-    size_t endPos = str.find(',');
+    std::string::size_type endPos = str.find(',');
     if ( endPos == std::string::npos ) {
         endPos = str.length();
     }
@@ -632,11 +661,11 @@ void ColorItem::_wireMagicColors( void* p )
     {
         for ( std::vector<ColorItem*>::iterator it = onceMore->_colors.begin(); it != onceMore->_colors.end(); ++it )
         {
-            size_t pos = (*it)->def.descr.find("*{");
+            std::string::size_type pos = (*it)->def.descr.find("*{");
             if ( pos != std::string::npos )
             {
                 std::string subby = (*it)->def.descr.substr( pos + 2 );
-                size_t endPos = subby.find("}*");
+                std::string::size_type endPos = subby.find("}*");
                 if ( endPos != std::string::npos )
                 {
                     subby.erase( endPos );
@@ -645,10 +674,14 @@ void ColorItem::_wireMagicColors( void* p )
 
                     if ( subby.find('E') != std::string::npos )
                     {
-                        //g_message("                   HOT!");
                         (*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 ) ) {
@@ -823,7 +856,9 @@ void _loadPaletteFile( gchar const *filename )
                 } while ( result && !hasErr );
                 if ( !hasErr ) {
                     possible.push_back(onceMore);
+#if ENABLE_MAGIC_COLORS
                     ColorItem::_wireMagicColors( onceMore );
+#endif // ENABLE_MAGIC_COLORS
                 } else {
                     delete onceMore;
                 }
@@ -843,6 +878,7 @@ static void loadEmUp()
         std::list<gchar *> 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()) {
@@ -859,13 +895,13 @@ static void loadEmUp()
                     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, ".gpl") ) {
                             gchar* full = g_build_filename(dirname, filename, NULL);
                             if ( !Inkscape::IO::file_test( full, (GFileTest)(G_FILE_TEST_IS_DIR ) ) ) {
                                 _loadPaletteFile(full);
                             }
                             g_free(full);
-                        }
+//                      }
                         g_free(lower);
                     }
                     g_dir_close(directory);
@@ -901,15 +937,33 @@ SwatchesPanel& SwatchesPanel::getInstance()
 /**
  * Constructor
  */
-SwatchesPanel::SwatchesPanel() :
-    Inkscape::UI::Widget::Panel ("dialogs.swatches"),
+SwatchesPanel::SwatchesPanel(gchar const* prefsPath) :
+    Inkscape::UI::Widget::Panel( Glib::ustring(), prefsPath, true ),
     _holder(0)
 {
+    Gtk::RadioMenuItem* hotItem = 0;
     _holder = new PreviewHolder();
     loadEmUp();
 
     if ( !possible.empty() ) {
-        JustForNow* first = possible.front();
+        JustForNow* first = 0;
+        gchar const* targetName = 0;
+        if ( _prefs_path ) {
+            targetName = prefs_get_string_attribute( _prefs_path, "palette" );
+            if ( targetName ) {
+                for ( std::vector<JustForNow*>::iterator iter = possible.begin(); iter != possible.end(); ++iter ) {
+                    if ( (*iter)->_name == targetName ) {
+                        first = *iter;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if ( !first ) {
+            first = possible.front();
+        }
+
         if ( first->_prefWidth > 0 ) {
             _holder->setColumnPref( first->_prefWidth );
         }
@@ -924,6 +978,9 @@ SwatchesPanel::SwatchesPanel() :
         for ( std::vector<JustForNow*>::iterator it = possible.begin(); it != possible.end(); it++ ) {
             JustForNow* curr = *it;
             Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name));
+            if ( curr == first ) {
+                hotItem = single;
+            }
             _regItem( single, 3, i );
             i++;
         }
@@ -937,6 +994,9 @@ SwatchesPanel::SwatchesPanel() :
     show_all_children();
 
     restorePanelPrefs();
+    if ( hotItem ) {
+        hotItem->set_active();
+    }
 }
 
 SwatchesPanel::~SwatchesPanel()
@@ -962,6 +1022,11 @@ void SwatchesPanel::_handleAction( int setId, int itemId )
             if ( itemId >= 0 && itemId < static_cast<int>(possible.size()) ) {
                 _holder->clear();
                 JustForNow* curr = possible[itemId];
+
+                if ( _prefs_path ) {
+                    prefs_set_string_attribute( _prefs_path, "palette", curr->_name.c_str() );
+                }
+
                 if ( curr->_prefWidth > 0 ) {
                     _holder->setColumnPref( curr->_prefWidth );
                 }