From 98bca1e5a1676e6bd459a85f0d54349d4a5df5ce Mon Sep 17 00:00:00 2001 From: joncruz Date: Mon, 8 Oct 2007 06:43:46 +0000 Subject: [PATCH] Adding profile manager and user-visible drop-down in CMS picker --- src/Makefile_insert | 2 + src/color-profile.cpp | 40 +++++++------- src/document.cpp | 10 ++++ src/document.h | 3 ++ src/profile-manager.cpp | 78 +++++++++++++++++++++++++++ src/profile-manager.h | 52 ++++++++++++++++++ src/widgets/sp-color-icc-selector.cpp | 42 +++++++++++++++ src/widgets/sp-color-icc-selector.h | 2 + 8 files changed, 210 insertions(+), 19 deletions(-) create mode 100644 src/profile-manager.cpp create mode 100644 src/profile-manager.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 97ac2988c..2efbd806e 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -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 \ diff --git a/src/color-profile.cpp b/src/color-profile.cpp index 9fc1f990e..b094b650d 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -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 ); } diff --git a/src/document.cpp b/src/document.cpp index 2a482648f..cfbcf95fe 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -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); diff --git a/src/document.h b/src/document.h index c04ed5441..e9546ae23 100644 --- a/src/document.h +++ b/src/document.h @@ -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 index 000000000..c2d344629 --- /dev/null +++ b/src/profile-manager.cpp @@ -0,0 +1,78 @@ +/* + * Inkscape::ProfileManager - a view of a document's color profiles. + * + * Copyright 2007 Jon A. Cruz + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#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 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 diff1; + std::set_difference( _knownProfiles.begin(), _knownProfiles.end(), newList.begin(), newList.end(), + std::insert_iterator >(diff1, diff1.begin()) ); + + std::vector diff2; + std::set_difference( newList.begin(), newList.end(), _knownProfiles.begin(), _knownProfiles.end(), + std::insert_iterator >(diff2, diff2.begin()) ); + + if ( !diff1.empty() ) { + for ( std::vector::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::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 index 000000000..c52101ca3 --- /dev/null +++ b/src/profile-manager.h @@ -0,0 +1,52 @@ +/* + * Inkscape::ProfileManager - a view of a document's color profiles. + * + * Copyright 2007 Jon A. Cruz + * + * 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 + +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 _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 : diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp index b4fff1d3f..984a1e296 100644 --- a/src/widgets/sp-color-icc-selector.cpp +++ b/src/widgets/sp-color-icc-selector.cpp @@ -3,6 +3,7 @@ #endif #include #include +#include #include #include #include @@ -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), "" ); + 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, ""); + + // 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(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():"")); #endif // DEBUG_LCMS + _profilesChanged( (color.icc) ? color.icc->colorProfile : std::string("") ); ColorScales::setScaled( _adj, alpha ); #if ENABLE_LCMS diff --git a/src/widgets/sp-color-icc-selector.h b/src/widgets/sp-color-icc-selector.h index 3ac8ab920..766bc9741 100644 --- a/src/widgets/sp-color-icc-selector.h +++ b/src/widgets/sp-color-icc-selector.h @@ -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; -- 2.30.2