Code

Adding profile manager and user-visible drop-down in CMS picker
authorjoncruz <joncruz@users.sourceforge.net>
Mon, 8 Oct 2007 06:43:46 +0000 (06:43 +0000)
committerjoncruz <joncruz@users.sourceforge.net>
Mon, 8 Oct 2007 06:43:46 +0000 (06:43 +0000)
src/Makefile_insert
src/color-profile.cpp
src/document.cpp
src/document.h
src/profile-manager.cpp [new file with mode: 0644]
src/profile-manager.h [new file with mode: 0644]
src/widgets/sp-color-icc-selector.cpp
src/widgets/sp-color-icc-selector.h

index 97ac2988c3133b376703e7e77d7bcb5c6a0319db..2efbd806efcef0462a6db1b6cbe22036f5867e25 100644 (file)
@@ -126,6 +126,8 @@ libinkpre_a_SOURCES =       \
        prefs-utils.cpp \
        prefs-utils.h   \
        print.cpp print.h       \
+       profile-manager.cpp     \
+       profile-manager.h       \
        rect-context.cpp rect-context.h \
        require-config.h \
        rubberband.cpp rubberband.h     \
index 9fc1f990e6770801ab30351b998472031dcc614b..b094b650d08314ee0dccb0acd6ce42987cafc7fd 100644 (file)
@@ -127,6 +127,12 @@ static void Inkscape::colorprofile_init( ColorProfile *cprof )
  */
 static void Inkscape::colorprofile_release( SPObject *object )
 {
+    // Unregister ourselves
+    SPDocument* document = SP_OBJECT_DOCUMENT(object);
+    if ( document ) {
+        sp_document_remove_resource (SP_OBJECT_DOCUMENT (object), "iccprofile", SP_OBJECT (object));
+    }
+
     ColorProfile *cprof = COLORPROFILE(object);
     if ( cprof->href ) {
         g_free( cprof->href );
@@ -174,6 +180,11 @@ static void Inkscape::colorprofile_build( SPObject *object, SPDocument *document
     sp_object_read_attr( object, "local" );
     sp_object_read_attr( object, "name" );
     sp_object_read_attr( object, "rendering-intent" );
+
+    // Register
+    if ( document ) {
+        sp_document_add_resource( document, "iccprofile", object );
+    }
 }
 
 /**
@@ -328,29 +339,21 @@ static Inkscape::XML::Node* Inkscape::colorprofile_write( SPObject *object, Inks
 #if ENABLE_LCMS
 
 
-static SPObject* bruteFind( SPObject* curr, gchar const* name )
+static SPObject* bruteFind( SPDocument* document, gchar const* name )
 {
     SPObject* result = 0;
-
-    if ( curr ) {
-        if ( IS_COLORPROFILE(curr) ) {
-            ColorProfile* prof = COLORPROFILE(curr);
+    const GSList * current = sp_document_get_resource_list(document, "iccprofile");
+    while ( current && !result ) {
+        if ( IS_COLORPROFILE(current->data) ) {
+            ColorProfile* prof = COLORPROFILE(current->data);
             if ( prof ) {
                 if ( prof->name && (strcmp(prof->name, name) == 0) ) {
-                    result = curr;
+                    result = SP_OBJECT(current->data);
+                    break;
                 }
             }
-        } else {
-            if ( curr->hasChildren() ) {
-                SPObject* child = curr->firstChild();
-                while ( child && !result ) {
-                    result = bruteFind( child, name );
-                    if ( !result ) {
-                        child = child->next;
-                    }
-                };
-            }
         }
+        current = g_slist_next(current);
     }
 
     return result;
@@ -360,8 +363,7 @@ cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* inte
 {
     cmsHPROFILE prof = 0;
 
-    SPObject* root = SP_DOCUMENT_ROOT(document);
-    SPObject* thing = bruteFind( root, name );
+    SPObject* thing = bruteFind( document, name );
     if ( thing ) {
         prof = COLORPROFILE(thing)->profHandle;
     }
@@ -401,7 +403,7 @@ private:
 ProfileInfo::ProfileInfo( cmsHPROFILE prof, Glib::ustring const & path )
 {
     _path = path;
-    _name = cmsTakeProductName(prof);
+    _name = cmsTakeProductDesc(prof);
     _profileSpace = cmsGetColorSpace( prof );
     _profileClass = cmsGetDeviceClass( prof );
 }
index 2a482648f1044ea6f22e61f5f5f9744e4facf78a..cfbcf95fe0926dc6bf7b0b7041eb9d05b5fb253d 100644 (file)
@@ -54,6 +54,7 @@
 #include "libnr/nr-rect.h"
 #include "sp-item-group.h"
 #include "perspective3d.h"
+#include "profile-manager.h"
 
 #include "display/nr-arena-item.h"
 
@@ -132,6 +133,9 @@ SPDocument::SPDocument() {
 
     priv = p;
 
+    // Once things are set, hook in the manager
+    profileManager = new Inkscape::ProfileManager(this);
+
     // XXX only for testing!
     priv->undoStackObservers.add(p->console_output_undo_observer);
 }
@@ -139,6 +143,12 @@ SPDocument::SPDocument() {
 SPDocument::~SPDocument() {
     collectOrphans();
 
+    // kill/unhook this first
+    if ( profileManager ) {
+        delete profileManager;
+        profileManager = 0;
+    }
+
     if (priv) {
         if (priv->partial) {
             sp_repr_free_log(priv->partial);
index c04ed5441db175af559cb5b8a33b5f65e229ae05..e9546ae23eaa79829d54dee8a748875df4f34761 100644 (file)
@@ -45,6 +45,7 @@ namespace Inkscape {
     class Selection; 
     class UndoStackObserver;
     class EventLog;
+    class ProfileManager;
     namespace XML {
         class Document;
         class Node;
@@ -96,6 +97,8 @@ struct SPDocument : public Inkscape::GC::Managed<>,
        /// Handler ID
        guint modified_id;
 
+    Inkscape::ProfileManager* profileManager;
+
        // Instance of the connector router
        Avoid::Router *router;
 
diff --git a/src/profile-manager.cpp b/src/profile-manager.cpp
new file mode 100644 (file)
index 0000000..c2d3446
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Inkscape::ProfileManager - a view of a document's color profiles.
+ *
+ * Copyright 2007  Jon A. Cruz  <jon@joncruz.org>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <algorithm>
+
+#include "profile-manager.h"
+#include "document.h"
+
+namespace Inkscape {
+
+ProfileManager::ProfileManager(SPDocument *document) :
+    _doc(document),
+    _knownProfiles()
+{
+    _resource_connection = sp_document_resources_changed_connect( _doc, "iccprofile", sigc::mem_fun(*this, &ProfileManager::_resourcesChanged) );
+}
+
+ProfileManager::~ProfileManager()
+{
+}
+
+void ProfileManager::_resourcesChanged()
+{
+    std::vector<SPObject*> newList;
+    const GSList *current = sp_document_get_resource_list( _doc, "iccprofile" );
+    while ( current ) {
+        newList.push_back(SP_OBJECT(current->data));
+        current = g_slist_next(current);
+    }
+    sort( newList.begin(), newList.end() );
+
+    std::vector<SPObject*> diff1;
+    std::set_difference( _knownProfiles.begin(), _knownProfiles.end(), newList.begin(), newList.end(),
+                         std::insert_iterator<std::vector<SPObject*> >(diff1, diff1.begin()) );
+
+    std::vector<SPObject*> diff2;
+    std::set_difference( newList.begin(), newList.end(), _knownProfiles.begin(), _knownProfiles.end(),
+                         std::insert_iterator<std::vector<SPObject*> >(diff2, diff2.begin()) );
+
+    if ( !diff1.empty() ) {
+        for ( std::vector<SPObject*>::iterator it = diff1.begin(); it < diff1.end(); ++it ) {
+            SPObject* tmp = *it;
+            _knownProfiles.erase( remove(_knownProfiles.begin(), _knownProfiles.end(), tmp), _knownProfiles.end() );
+            if ( includes(tmp) ) {
+                _removeOne(tmp);
+            }
+        }
+    }
+
+    if ( !diff2.empty() ) {
+        for ( std::vector<SPObject*>::iterator it = diff2.begin(); it < diff2.end(); ++it ) {
+            SPObject* tmp = *it;
+            _knownProfiles.push_back(tmp);
+            _addOne(tmp);
+        }
+        sort( _knownProfiles.begin(), _knownProfiles.end() );
+    }
+}
+
+
+}
+
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/profile-manager.h b/src/profile-manager.h
new file mode 100644 (file)
index 0000000..c52101c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Inkscape::ProfileManager - a view of a document's color profiles.
+ *
+ * Copyright 2007  Jon A. Cruz  <jon@joncruz.org>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_INKSCAPE_PROFILE_MANAGER_H
+#define SEEN_INKSCAPE_PROFILE_MANAGER_H
+
+#include "document-subset.h"
+#include "gc-finalized.h"
+#include <vector>
+
+class SPDocument;
+
+
+namespace Inkscape {
+
+class ProfileManager : public DocumentSubset,
+                       public GC::Finalized
+{
+public:
+    ProfileManager(SPDocument *document);
+    ~ProfileManager();
+
+private:
+    ProfileManager(ProfileManager const &); // no copy
+    void operator=(ProfileManager const &); // no assign
+
+    void _resourcesChanged();
+
+    SPDocument* _doc;
+    sigc::connection _resource_connection;
+    std::vector<SPObject*> _knownProfiles;
+};
+
+}
+
+#endif // SEEN_INKSCAPE_PROFILE_MANAGER_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:encoding=utf-8:textwidth=99 :
index b4fff1d3f1a1fa586b49331ddf87fd31b1b4823a..984a1e296ac0354fb5324798a4c60da39412e8b7 100644 (file)
@@ -3,6 +3,7 @@
 #endif
 #include <math.h>
 #include <gtk/gtkbutton.h>
+#include <gtk/gtkcombobox.h>
 #include <gtk/gtksignal.h>
 #include <gtk/gtklabel.h>
 #include <gtk/gtktable.h>
@@ -12,6 +13,7 @@
 #include "sp-color-icc-selector.h"
 #include "sp-color-scales.h"
 #include "svg/svg-icc-color.h"
+#include "document.h"
 #include "inkscape.h"
 
 #define noDEBUG_LCMS
@@ -302,6 +304,15 @@ void ColorICCSelector::init()
     gtk_widget_show( _fixupBtn );
     gtk_table_attach( GTK_TABLE (t), _fixupBtn, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD );
 
+
+    _profileSel = gtk_combo_box_new_text();
+    gtk_combo_box_append_text( GTK_COMBO_BOX(_profileSel), "<none>" );
+    gtk_widget_show( _profileSel );
+    gtk_combo_box_set_active( GTK_COMBO_BOX(_profileSel), 0 );
+    gtk_table_attach( GTK_TABLE(t), _profileSel, 1, 2, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD );
+
+    gtk_widget_set_sensitive( _profileSel, false );
+
     row++;
 
     _fooCount = 4;
@@ -442,6 +453,36 @@ void ColorICCSelector::_fixupHit( GtkWidget* src, gpointer data )
     self->_adjustmentChanged( self->_fooAdj[0], SP_COLOR_ICC_SELECTOR(self->_csel) );
 }
 
+void ColorICCSelector::_profilesChanged( std::string const & name )
+{
+    GtkComboBox* combo = GTK_COMBO_BOX(_profileSel);
+    GtkTreeModel* model = gtk_combo_box_get_model( combo );
+    GtkTreeIter iter;
+    while ( gtk_tree_model_get_iter_first( model, &iter ) ) {
+        gtk_combo_box_remove_text( combo, 0 );
+    }
+
+    gtk_combo_box_append_text( combo, "<none>");
+
+    // TODO supress signal emit
+    gtk_combo_box_set_active( combo, 0 );
+
+    int index = 1;
+    const GSList *current = sp_document_get_resource_list( SP_ACTIVE_DOCUMENT, "iccprofile" );
+    while ( current ) {
+        SPObject* obj = SP_OBJECT(current->data);
+        Inkscape::ColorProfile* prof = reinterpret_cast<Inkscape::ColorProfile*>(obj);
+        gtk_combo_box_append_text( combo, prof->name );
+        if ( name == prof->name ) {
+            gtk_combo_box_set_active( combo, index );
+        }
+
+        index++;
+        current = g_slist_next(current);
+    }
+
+}
+
 /* Helpers for setting color value */
 
 void ColorICCSelector::_colorChanged( const SPColor& color, gfloat alpha )
@@ -459,6 +500,7 @@ void ColorICCSelector::_colorChanged( const SPColor& color, gfloat alpha )
     g_message("FLIPPIES!!!!     %p   '%s'", color.icc, (color.icc?color.icc->colorProfile.c_str():"<null>"));
 #endif // DEBUG_LCMS
 
+    _profilesChanged( (color.icc) ? color.icc->colorProfile : std::string("") );
     ColorScales::setScaled( _adj, alpha );
 
 #if ENABLE_LCMS
index 3ac8ab9201033bc28fbf4c4fd8588376101196ef..766bc9741bbea399e225cbfe9e9ea1a28c62e925 100644 (file)
@@ -43,12 +43,14 @@ protected:
     void _setProfile( SVGICCColor* profile );
 #endif // ENABLE_LCMS
     void _updateSliders( gint ignore );
+    void _profilesChanged( std::string const & name );
 
     gboolean _updating : 1;
     gboolean _dragging : 1;
 
     guint32 _fixupNeeded;
     GtkWidget* _fixupBtn;
+    GtkWidget* _profileSel;
 
     guint _fooCount;
     guint const* _fooScales;