diff --git a/krita/data/CMakeLists.txt b/krita/data/CMakeLists.txt index b1b313b14e..50e35120da 100644 --- a/krita/data/CMakeLists.txt +++ b/krita/data/CMakeLists.txt @@ -1,24 +1,25 @@ add_subdirectory( actions ) add_subdirectory( brushes ) add_subdirectory( bundles ) add_subdirectory( patterns ) add_subdirectory( gradients ) add_subdirectory( profiles ) add_subdirectory( templates ) add_subdirectory( workspaces ) add_subdirectory( themes ) add_subdirectory( predefined_image_sizes ) add_subdirectory( input ) add_subdirectory( shortcuts ) add_subdirectory( paintoppresets ) add_subdirectory( palettes ) add_subdirectory( symbols ) add_subdirectory( preset_icons ) +add_subdirectory( metadata/schemas ) ########### install files ############### install( FILES kritarc DESTINATION ${CONFIG_INSTALL_DIR} ) diff --git a/krita/data/metadata/schemas/CMakeLists.txt b/krita/data/metadata/schemas/CMakeLists.txt new file mode 100644 index 0000000000..29dd66cf51 --- /dev/null +++ b/krita/data/metadata/schemas/CMakeLists.txt @@ -0,0 +1,12 @@ +########### install schemas ############# +install( FILES + dc.schema + exif.schema + tiff.schema + mkn.schema + xmp.schema + xmpmm.schema + xmprights.schema + + DESTINATION ${DATA_INSTALL_DIR}/krita/metadata/schemas) + diff --git a/krita/data/schemas/dc.schema b/krita/data/metadata/schemas/dc.schema similarity index 100% rename from krita/data/schemas/dc.schema rename to krita/data/metadata/schemas/dc.schema diff --git a/krita/data/schemas/exif.schema b/krita/data/metadata/schemas/exif.schema similarity index 100% rename from krita/data/schemas/exif.schema rename to krita/data/metadata/schemas/exif.schema diff --git a/krita/data/schemas/mkn.schema b/krita/data/metadata/schemas/mkn.schema similarity index 100% rename from krita/data/schemas/mkn.schema rename to krita/data/metadata/schemas/mkn.schema diff --git a/krita/data/schemas/tiff.schema b/krita/data/metadata/schemas/tiff.schema similarity index 100% rename from krita/data/schemas/tiff.schema rename to krita/data/metadata/schemas/tiff.schema diff --git a/krita/data/schemas/xmp.schema b/krita/data/metadata/schemas/xmp.schema similarity index 100% rename from krita/data/schemas/xmp.schema rename to krita/data/metadata/schemas/xmp.schema diff --git a/krita/data/schemas/xmpmm.schema b/krita/data/metadata/schemas/xmpmm.schema similarity index 100% rename from krita/data/schemas/xmpmm.schema rename to krita/data/metadata/schemas/xmpmm.schema diff --git a/krita/data/schemas/xmprights.schema b/krita/data/metadata/schemas/xmprights.schema similarity index 100% rename from krita/data/schemas/xmprights.schema rename to krita/data/metadata/schemas/xmprights.schema diff --git a/libs/image/CMakeLists.txt b/libs/image/CMakeLists.txt index 02c8411517..b515ef9b0b 100644 --- a/libs/image/CMakeLists.txt +++ b/libs/image/CMakeLists.txt @@ -1,388 +1,376 @@ add_subdirectory( tests ) add_subdirectory( tiles3 ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/metadata ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty ${CMAKE_CURRENT_SOURCE_DIR}/brushengine ${CMAKE_CURRENT_SOURCE_DIR}/commands ${CMAKE_CURRENT_SOURCE_DIR}/commands_new ${CMAKE_CURRENT_SOURCE_DIR}/filter ${CMAKE_CURRENT_SOURCE_DIR}/floodfill ${CMAKE_CURRENT_SOURCE_DIR}/generator ${CMAKE_CURRENT_SOURCE_DIR}/layerstyles ${CMAKE_CURRENT_SOURCE_DIR}/processing ${CMAKE_SOURCE_DIR}/sdk/tests ) include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR} ) if(FFTW3_FOUND) include_directories(${FFTW3_INCLUDE_DIR}) endif() if(HAVE_VC) include_directories(SYSTEM ${Vc_INCLUDE_DIR} ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS}) ko_compile_for_all_implementations(__per_arch_circle_mask_generator_objs kis_brush_mask_applicator_factories.cpp) else() set(__per_arch_circle_mask_generator_objs kis_brush_mask_applicator_factories.cpp) endif() set(kritaimage_LIB_SRCS tiles3/kis_tile.cc tiles3/kis_tile_data.cc tiles3/kis_tile_data_store.cc tiles3/kis_tile_data_pooler.cc tiles3/kis_tiled_data_manager.cc tiles3/KisTiledExtentManager.cpp tiles3/kis_memento_manager.cc tiles3/kis_hline_iterator.cpp tiles3/kis_vline_iterator.cpp tiles3/kis_random_accessor.cc tiles3/swap/kis_abstract_compression.cpp tiles3/swap/kis_lzf_compression.cpp tiles3/swap/kis_abstract_tile_compressor.cpp tiles3/swap/kis_legacy_tile_compressor.cpp tiles3/swap/kis_tile_compressor_2.cpp tiles3/swap/kis_chunk_allocator.cpp tiles3/swap/kis_memory_window.cpp tiles3/swap/kis_swapped_data_store.cpp tiles3/swap/kis_tile_data_swapper.cpp kis_distance_information.cpp kis_painter.cc kis_painter_blt_multi_fixed.cpp kis_marker_painter.cpp KisPrecisePaintDeviceWrapper.cpp kis_progress_updater.cpp brushengine/kis_paint_information.cc brushengine/kis_random_source.cpp brushengine/KisPerStrokeRandomSource.cpp brushengine/kis_stroke_random_source.cpp brushengine/kis_paintop.cc brushengine/kis_paintop_factory.cpp brushengine/kis_paintop_preset.cpp brushengine/kis_paintop_registry.cc brushengine/kis_paintop_settings.cpp brushengine/kis_paintop_settings_update_proxy.cpp brushengine/kis_paintop_utils.cpp brushengine/kis_no_size_paintop_settings.cpp brushengine/kis_locked_properties.cc brushengine/kis_locked_properties_proxy.cpp brushengine/kis_locked_properties_server.cpp brushengine/kis_paintop_config_widget.cpp brushengine/kis_uniform_paintop_property.cpp brushengine/kis_combo_based_paintop_property.cpp brushengine/kis_slider_based_paintop_property.cpp brushengine/kis_standard_uniform_properties_factory.cpp brushengine/KisStrokeSpeedMeasurer.cpp brushengine/KisPaintopSettingsIds.cpp commands/kis_deselect_global_selection_command.cpp commands/kis_image_change_layers_command.cpp commands/kis_image_change_visibility_command.cpp commands/kis_image_command.cpp commands/kis_image_set_projection_color_space_command.cpp commands/kis_image_layer_add_command.cpp commands/kis_image_layer_move_command.cpp commands/kis_image_layer_remove_command.cpp commands/kis_image_layer_remove_command_impl.cpp commands/kis_image_lock_command.cpp commands/kis_node_command.cpp commands/kis_node_compositeop_command.cpp commands/kis_node_opacity_command.cpp commands/kis_node_property_list_command.cpp commands/kis_reselect_global_selection_command.cpp commands/kis_set_global_selection_command.cpp commands_new/kis_saved_commands.cpp commands_new/kis_processing_command.cpp commands_new/kis_image_resize_command.cpp commands_new/kis_image_set_resolution_command.cpp commands_new/kis_node_move_command2.cpp commands_new/kis_set_layer_style_command.cpp commands_new/kis_selection_move_command2.cpp commands_new/kis_update_command.cpp commands_new/kis_switch_current_time_command.cpp commands_new/kis_change_projection_color_command.cpp commands_new/kis_activate_selection_mask_command.cpp processing/kis_do_nothing_processing_visitor.cpp processing/kis_simple_processing_visitor.cpp processing/kis_crop_processing_visitor.cpp processing/kis_crop_selections_processing_visitor.cpp processing/kis_transform_processing_visitor.cpp processing/kis_mirror_processing_visitor.cpp filter/kis_filter.cc filter/kis_filter_category_ids.cpp filter/kis_filter_configuration.cc filter/kis_color_transformation_configuration.cc filter/kis_filter_registry.cc filter/kis_color_transformation_filter.cc generator/kis_generator.cpp generator/kis_generator_layer.cpp generator/kis_generator_registry.cpp floodfill/kis_fill_interval_map.cpp floodfill/kis_scanline_fill.cpp lazybrush/kis_min_cut_worker.cpp lazybrush/kis_lazy_fill_tools.cpp lazybrush/kis_multiway_cut.cpp lazybrush/KisWatershedWorker.cpp lazybrush/kis_colorize_mask.cpp lazybrush/kis_colorize_stroke_strategy.cpp KisDelayedUpdateNodeInterface.cpp kis_adjustment_layer.cc kis_selection_based_layer.cpp kis_node_filter_interface.cpp kis_base_accessor.cpp kis_base_node.cpp kis_base_processor.cpp kis_bookmarked_configuration_manager.cc kis_node_uuid_info.cpp kis_clone_layer.cpp kis_colorspace_convert_visitor.cpp kis_config_widget.cpp kis_convolution_kernel.cc kis_convolution_painter.cc kis_gaussian_kernel.cpp kis_edge_detection_kernel.cpp kis_cubic_curve.cpp kis_default_bounds.cpp kis_default_bounds_base.cpp kis_effect_mask.cc kis_fast_math.cpp kis_fill_painter.cc kis_filter_mask.cpp kis_filter_strategy.cc kis_transform_mask.cpp kis_transform_mask_params_interface.cpp kis_recalculate_transform_mask_job.cpp kis_recalculate_generator_layer_job.cpp kis_transform_mask_params_factory_registry.cpp kis_safe_transform.cpp kis_gradient_painter.cc kis_gradient_shape_strategy.cpp kis_cached_gradient_shape_strategy.cpp kis_polygonal_gradient_shape_strategy.cpp kis_iterator_ng.cpp kis_async_merger.cpp kis_merge_walker.cc kis_updater_context.cpp kis_update_job_item.cpp kis_stroke_strategy_undo_command_based.cpp kis_simple_stroke_strategy.cpp KisRunnableBasedStrokeStrategy.cpp KisRunnableStrokeJobData.cpp KisRunnableStrokeJobsInterface.cpp KisFakeRunnableStrokeJobsExecutor.cpp kis_stroke_job_strategy.cpp kis_stroke_strategy.cpp kis_stroke.cpp kis_strokes_queue.cpp KisStrokesQueueMutatedJobInterface.cpp kis_simple_update_queue.cpp kis_update_scheduler.cpp kis_queues_progress_updater.cpp kis_composite_progress_proxy.cpp kis_sync_lod_cache_stroke_strategy.cpp kis_lod_capable_layer_offset.cpp kis_update_time_monitor.cpp KisImageConfigNotifier.cpp kis_group_layer.cc kis_count_visitor.cpp kis_histogram.cc kis_image_interfaces.cpp kis_image_animation_interface.cpp kis_time_range.cpp kis_node_graph_listener.cpp kis_image.cc kis_image_signal_router.cpp kis_image_config.cpp kis_projection_updates_filter.cpp kis_suspend_projection_updates_stroke_strategy.cpp kis_regenerate_frame_stroke_strategy.cpp kis_switch_time_stroke_strategy.cpp kis_crop_saved_extra_data.cpp kis_timed_signal_threshold.cpp kis_layer.cc kis_indirect_painting_support.cpp kis_abstract_projection_plane.cpp kis_layer_projection_plane.cpp kis_layer_utils.cpp kis_mask_projection_plane.cpp kis_projection_leaf.cpp kis_mask.cc kis_base_mask_generator.cpp kis_rect_mask_generator.cpp kis_circle_mask_generator.cpp kis_gauss_circle_mask_generator.cpp kis_gauss_rect_mask_generator.cpp ${__per_arch_circle_mask_generator_objs} kis_curve_circle_mask_generator.cpp kis_curve_rect_mask_generator.cpp kis_math_toolbox.cpp kis_memory_statistics_server.cpp kis_name_server.cpp kis_node.cpp kis_node_facade.cpp kis_node_progress_proxy.cpp kis_busy_progress_indicator.cpp kis_node_visitor.cpp kis_paint_device.cc kis_paint_device_debug_utils.cpp kis_fixed_paint_device.cpp KisOptimizedByteArray.cpp kis_paint_layer.cc kis_perspective_math.cpp kis_pixel_selection.cpp kis_processing_information.cpp kis_properties_configuration.cc kis_random_accessor_ng.cpp kis_random_generator.cc kis_random_sub_accessor.cpp kis_wrapped_random_accessor.cpp kis_selection.cc kis_selection_mask.cpp kis_update_outline_job.cpp kis_update_selection_job.cpp kis_serializable_configuration.cc kis_transaction_data.cpp kis_transform_worker.cc kis_perspectivetransform_worker.cpp bsplines/kis_bspline_1d.cpp bsplines/kis_bspline_2d.cpp bsplines/kis_nu_bspline_2d.cpp kis_warptransform_worker.cc kis_cage_transform_worker.cpp kis_liquify_transform_worker.cpp kis_green_coordinates_math.cpp kis_transparency_mask.cc kis_undo_adapter.cpp kis_macro_based_undo_store.cpp kis_surrogate_undo_adapter.cpp kis_legacy_undo_adapter.cpp kis_post_execution_undo_adapter.cpp kis_processing_visitor.cpp kis_processing_applicator.cpp krita_utils.cpp kis_outline_generator.cpp kis_layer_composition.cpp kis_selection_filters.cpp KisProofingConfiguration.h metadata/kis_meta_data_entry.cc metadata/kis_meta_data_filter.cc metadata/kis_meta_data_filter_p.cc metadata/kis_meta_data_filter_registry.cc metadata/kis_meta_data_filter_registry_model.cc metadata/kis_meta_data_io_backend.cc metadata/kis_meta_data_merge_strategy.cc metadata/kis_meta_data_merge_strategy_p.cc metadata/kis_meta_data_merge_strategy_registry.cc metadata/kis_meta_data_parser.cc metadata/kis_meta_data_schema.cc metadata/kis_meta_data_schema_registry.cc metadata/kis_meta_data_store.cc metadata/kis_meta_data_type_info.cc metadata/kis_meta_data_validator.cc metadata/kis_meta_data_value.cc kis_keyframe.cpp kis_keyframe_channel.cpp kis_keyframe_commands.cpp kis_scalar_keyframe_channel.cpp kis_raster_keyframe_channel.cpp kis_onion_skin_compositor.cpp kis_onion_skin_cache.cpp kis_idle_watcher.cpp kis_psd_layer_style.cpp kis_layer_properties_icons.cpp layerstyles/kis_multiple_projection.cpp layerstyles/kis_layer_style_filter.cpp layerstyles/kis_layer_style_filter_environment.cpp layerstyles/kis_layer_style_filter_projection_plane.cpp layerstyles/kis_layer_style_projection_plane.cpp layerstyles/kis_ls_drop_shadow_filter.cpp layerstyles/kis_ls_satin_filter.cpp layerstyles/kis_ls_stroke_filter.cpp layerstyles/kis_ls_bevel_emboss_filter.cpp layerstyles/kis_ls_overlay_filter.cpp layerstyles/kis_ls_utils.cpp layerstyles/gimp_bump_map.cpp KisProofingConfiguration.cpp kis_node_query_path.cc ) set(einspline_SRCS 3rdparty/einspline/bspline_create.cpp 3rdparty/einspline/bspline_data.cpp 3rdparty/einspline/multi_bspline_create.cpp 3rdparty/einspline/nubasis.cpp 3rdparty/einspline/nubspline_create.cpp 3rdparty/einspline/nugrid.cpp ) add_library(kritaimage SHARED ${kritaimage_LIB_SRCS} ${einspline_SRCS}) generate_export_header(kritaimage BASE_NAME kritaimage) target_link_libraries(kritaimage PUBLIC kritaversion kritawidgets kritaglobal kritapsd kritaodf kritapigment kritacommand kritawidgetutils Qt5::Concurrent ) target_link_libraries(kritaimage PUBLIC ${Boost_SYSTEM_LIBRARY}) if(OPENEXR_FOUND) target_link_libraries(kritaimage PUBLIC ${OPENEXR_LIBRARIES}) endif() if(FFTW3_FOUND) target_link_libraries(kritaimage PRIVATE ${FFTW3_LIBRARIES}) endif() if(HAVE_VC) target_link_libraries(kritaimage PUBLIC ${Vc_LIBRARIES}) endif() if (NOT GSL_FOUND) message (WARNING "KRITA WARNING! No GNU Scientific Library was found! Krita's Shaped Gradients might be non-normalized! Please install GSL library.") else () target_link_libraries(kritaimage PRIVATE ${GSL_LIBRARIES} ${GSL_CBLAS_LIBRARIES}) endif () target_include_directories(kritaimage PUBLIC $ $ $ $ $ $ ) set_target_properties(kritaimage PROPERTIES VERSION ${GENERIC_KRITA_LIB_VERSION} SOVERSION ${GENERIC_KRITA_LIB_SOVERSION} ) install(TARGETS kritaimage ${INSTALL_TARGETS_DEFAULT_ARGS}) - -########### install schemas ############# -install( FILES - metadata/schemas/dc.schema - metadata/schemas/exif.schema - metadata/schemas/tiff.schema - metadata/schemas/mkn.schema - metadata/schemas/xmp.schema - metadata/schemas/xmpmm.schema - metadata/schemas/xmprights.schema - - DESTINATION ${DATA_INSTALL_DIR}/krita/metadata/schemas) diff --git a/libs/image/metadata/kis_meta_data_entry.cc b/libs/image/metadata/kis_meta_data_entry.cc index 4ca9e21fa6..a95c50a14a 100644 --- a/libs/image/metadata/kis_meta_data_entry.cc +++ b/libs/image/metadata/kis_meta_data_entry.cc @@ -1,148 +1,150 @@ /* * Copyright (c) 2007 Cyrille Berger * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_meta_data_entry.h" #include #include #include "kis_meta_data_value.h" #include "kis_meta_data_schema.h" using namespace KisMetaData; struct Q_DECL_HIDDEN Entry::Private { QString name; const Schema* schema; Value value; bool valid; }; Entry::Entry() : d(new Private) { d->schema = 0; d->valid = false; } Entry::Entry(const Schema* schema, QString name, const Value& value) : d(new Private) { Q_ASSERT(!name.isEmpty()); if (!isValidName(name)) { errKrita << "Invalid metadata name:" << name; d->name = QString("INVALID: %s").arg(name); } else { d->name = name; } d->schema = schema; d->value = value; d->valid = true; } Entry::Entry(const Entry& e) : d(new Private()) { d->valid = false; *this = e; } Entry::~Entry() { delete d; } QString Entry::name() const { return d->name; } const Schema* Entry::schema() const { Q_ASSERT(d->schema); return d->schema; } void Entry::setSchema(const KisMetaData::Schema* schema) { + Q_ASSERT(schema); d->schema = schema; } QString Entry::qualifiedName() const { + Q_ASSERT(d->schema); return d->schema->generateQualifiedName(d->name); } const Value& Entry::value() const { return d->value; } Value& Entry::value() { return d->value; } bool Entry::isValid() const { return d->valid; } bool Entry::isValidName(const QString& _name) { if (_name.length() < 1) { dbgMetaData << "Too small"; return false; } if (!_name[0].isLetter()) { dbgMetaData << _name << " doesn't start by a letter"; return false; } for (int i = 1; i < _name.length(); ++i) { QChar c = _name[i]; if (!c.isLetterOrNumber()) { dbgMetaData << _name << " " << i << "th character isn't a letter or a digit"; return false; } } return true; } bool Entry::operator==(const Entry& e) const { return qualifiedName() == e.qualifiedName(); } Entry& Entry::operator=(const Entry & e) { if (e.isValid()) { Q_ASSERT(!isValid() || *this == e); d->name = e.d->name; d->schema = e.d->schema; d->value = e.d->value; d->valid = true; } return *this; } QDebug operator<<(QDebug debug, const Entry &c) { debug.nospace() << "Name: " << c.name() << " Qualified name: " << c.qualifiedName() << " Value: " << c.value(); return debug.space(); } diff --git a/libs/image/metadata/kis_meta_data_schema_registry.cc b/libs/image/metadata/kis_meta_data_schema_registry.cc index 2172fda7b4..36725fccb9 100644 --- a/libs/image/metadata/kis_meta_data_schema_registry.cc +++ b/libs/image/metadata/kis_meta_data_schema_registry.cc @@ -1,109 +1,111 @@ /* * Copyright (c) 2007,2009 Cyrille Berger * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_meta_data_schema_registry.h" #include #include #include "kis_debug.h" #include "kis_meta_data_schema_p.h" using namespace KisMetaData; // ---- Schema Registry ---- // struct Q_DECL_HIDDEN SchemaRegistry::Private { static SchemaRegistry *singleton; QHash uri2Schema; QHash prefix2Schema; }; SchemaRegistry *SchemaRegistry::Private::singleton = 0; SchemaRegistry* SchemaRegistry::instance() { if (SchemaRegistry::Private::singleton == 0) { SchemaRegistry::Private::singleton = new SchemaRegistry(); } return SchemaRegistry::Private::singleton; } SchemaRegistry::SchemaRegistry() : d(new Private) { + KoResourcePaths::addResourceType("metadata_schema", "data", "/metadata/schemas/"); - QStringList schemasFilenames; - schemasFilenames += KoResourcePaths::findAllResources("metadata_schema", "*.schema"); + QStringList schemasFilenames = KoResourcePaths::findAllResources("metadata_schema", "*.schema"); + + qDebug() << "schemasFilenames" << schemasFilenames; Q_FOREACH (const QString& fileName, schemasFilenames) { Schema* schema = new Schema(); schema->d->load(fileName); if (schemaFromUri(schema->uri())) { errMetaData << "Schema already exist uri: " << schema->uri(); } else if (schemaFromPrefix(schema->prefix())) { errMetaData << "Schema already exist prefix: " << schema->prefix(); } else { d->uri2Schema[schema->uri()] = schema; d->prefix2Schema[schema->prefix()] = schema; } } // DEPRECATED WRITE A SCHEMA FOR EACH OF THEM create(Schema::MakerNoteSchemaUri, "mkn"); create(Schema::IPTCSchemaUri, "Iptc4xmpCore"); create(Schema::PhotoshopSchemaUri, "photoshop"); } SchemaRegistry::~SchemaRegistry() { delete d; } const Schema* SchemaRegistry::schemaFromUri(const QString & uri) const { return d->uri2Schema[uri]; } const Schema* SchemaRegistry::schemaFromPrefix(const QString & prefix) const { return d->prefix2Schema[prefix]; } const Schema* SchemaRegistry::create(const QString & uri, const QString & prefix) { // First search for the schema const Schema* schema = schemaFromUri(uri); if (schema) { return schema; } // Second search for the prefix schema = schemaFromPrefix(prefix); if (schema) { return 0; // A schema with the same prefix already exist } // The schema doesn't exist yet, create it Schema* nschema = new Schema(uri, prefix); d->uri2Schema[uri] = nschema; d->prefix2Schema[prefix] = nschema; return nschema; } diff --git a/libs/image/metadata/kis_meta_data_store.cc b/libs/image/metadata/kis_meta_data_store.cc index bfcf9dd2e1..d0939012d6 100644 --- a/libs/image/metadata/kis_meta_data_store.cc +++ b/libs/image/metadata/kis_meta_data_store.cc @@ -1,213 +1,216 @@ /* * Copyright (c) 2007 Cyrille Berger * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_meta_data_store.h" #include #include #include "kis_meta_data_entry.h" #include "kis_meta_data_filter.h" #include "kis_meta_data_schema.h" #include "kis_meta_data_schema_registry.h" #include "kis_meta_data_value.h" using namespace KisMetaData; uint qHash(const Entry& e) { return qHash(e.qualifiedName()); } struct Q_DECL_HIDDEN Store::Private { QHash entries; }; Store::Store() : d(new Private) { } Store::Store(const Store& s) : d(new Private(*s.d)) { // TODO: reaffect all schemas } Store::~Store() { delete d; } void Store::copyFrom(const Store* store) { for (QHash::const_iterator entryIt = store->begin(); entryIt != store->end(); ++entryIt) { const Entry& entry = entryIt.value(); if (entry.value().type() != KisMetaData::Value::Invalid) { if (containsEntry(entry.qualifiedName())) { getEntry(entry.qualifiedName()).value() = entry.value(); } else { addEntry(entry); } } } } bool Store::addEntry(const Entry& entry) { Q_ASSERT(!entry.name().isEmpty()); if (d->entries.contains(entry.qualifiedName()) && d->entries[entry.qualifiedName()].isValid()) { dbgMetaData << "Entry" << entry.qualifiedName() << " already exists in the store, cannot be included twice"; return false; } d->entries.insert(entry.qualifiedName(), entry); return true; } bool Store::empty() const { return d->entries.isEmpty(); } bool Store::isEmpty() const { return d->entries.isEmpty(); } bool Store::containsEntry(const QString & entryKey) const { return d->entries.contains(entryKey); } bool Store::containsEntry(const QString & uri, const QString & entryName) const { const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri); return containsEntry(schema->generateQualifiedName(entryName)); } bool Store::containsEntry(const KisMetaData::Schema* schema, const QString & entryName) const { - return containsEntry(schema->generateQualifiedName(entryName)); + if (schema) { + return containsEntry(schema->generateQualifiedName(entryName)); + } + return false; } Entry& Store::getEntry(const QString & entryKey) { if (!d->entries.contains(entryKey)) { QStringList splitKey = entryKey.split(':'); QString prefix = splitKey[0]; splitKey.pop_front(); d->entries[entryKey] = Entry(SchemaRegistry::instance()->schemaFromPrefix(prefix), splitKey.join(":"), Value()); } return d->entries [entryKey]; } Entry& Store::getEntry(const QString & uri, const QString & entryName) { const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri); Q_ASSERT(schema); return getEntry(schema, entryName); } Entry& Store::getEntry(const KisMetaData::Schema* schema, const QString & entryName) { return getEntry(schema->generateQualifiedName(entryName)); } const Entry& Store::getEntry(const QString & entryKey) const { return d->entries[entryKey]; } const Entry& Store::getEntry(const QString & uri, const QString & entryName) const { const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri); Q_ASSERT(schema); return getEntry(schema, entryName); } const Entry& Store::getEntry(const KisMetaData::Schema* schema, const QString & entryName) const { return getEntry(schema->generateQualifiedName(entryName)); } void Store::removeEntry(const QString & entryKey) { d->entries.remove(entryKey); } void Store::removeEntry(const QString & uri, const QString & entryName) { const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri); Q_ASSERT(schema); removeEntry(schema, entryName); } void Store::removeEntry(const KisMetaData::Schema* schema, const QString & entryName) { removeEntry(schema->generateQualifiedName(entryName)); } const Value& Store::getValue(const QString & uri, const QString & entryName) const { return getEntry(uri, entryName).value(); } QHash::const_iterator Store::begin() const { return d->entries.constBegin(); } QHash::const_iterator Store::end() const { return d->entries.constEnd(); } void Store::debugDump() const { dbgMetaData << "=== Dumping MetaData Store ==="; dbgMetaData << " - Metadata (there are" << d->entries.size() << " entries)"; Q_FOREACH (const Entry& e, d->entries) { if (e.isValid()) { dbgMetaData << e; } else { dbgMetaData << "Invalid entry"; } } } void Store::applyFilters(const QList & filters) { dbgMetaData << "Apply " << filters.size() << " filters"; Q_FOREACH (const Filter* filter, filters) { filter->filter(this); } } QList Store::keys() const { return d->entries.keys(); } QList Store::entries() const { return d->entries.values(); } diff --git a/libs/image/tests/kis_meta_data_test.cpp b/libs/image/tests/kis_meta_data_test.cpp index aad524c858..9295c6404b 100644 --- a/libs/image/tests/kis_meta_data_test.cpp +++ b/libs/image/tests/kis_meta_data_test.cpp @@ -1,586 +1,592 @@ /* * Copyright (c) 2008-2009 Cyrille Berger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_meta_data_test.h" #include #include "kis_meta_data_entry.h" #include "kis_meta_data_filter_registry.h" #include "kis_meta_data_value.h" #include "kis_meta_data_schema.h" #include "kis_meta_data_schema_registry.h" #include "kis_meta_data_store.h" #include "kis_meta_data_type_info.h" #include "kis_meta_data_type_info_p.h" #include "kis_meta_data_parser.h" #include "kis_meta_data_validator.h" +#include "sdk/tests/kistest.h" + using namespace KisMetaData; KisMetaData::Value KisMetaDataTest::createRationalValue() { return KisMetaData::Value(Rational(12, -42)); } KisMetaData::Value KisMetaDataTest::createIntegerValue(int v) { return KisMetaData::Value(v); } KisMetaData::Value KisMetaDataTest::createStringValue() { return KisMetaData::Value("Hello World !"); } KisMetaData::Value KisMetaDataTest::createListValue() { QList list; list << createRationalValue() << createIntegerValue() << createStringValue(); return list; } + +#define TEST_SCHEMA(uriStr) \ + { \ + const Schema* schema = SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::uriStr); \ + QVERIFY(schema); \ + QCOMPARE(schema->uri(), KisMetaData::Schema::uriStr); \ + QCOMPARE(schema, SchemaRegistry::instance()->schemaFromPrefix(schema->prefix()) ); \ + QVERIFY( !SchemaRegistry::instance()->create("http://tartampion.com", schema->prefix())); \ + QCOMPARE(schema, SchemaRegistry::instance()->create(KisMetaData::Schema::uriStr, "tartampion")); \ + QCOMPARE(QString(schema->prefix() + ":hello"), schema->generateQualifiedName("hello")); \ + } + + +void KisMetaDataTest::testSchemaBasic() +{ + TEST_SCHEMA(TIFFSchemaUri); + TEST_SCHEMA(EXIFSchemaUri); + TEST_SCHEMA(DublinCoreSchemaUri); + TEST_SCHEMA(XMPSchemaUri); + TEST_SCHEMA(XMPRightsSchemaUri); + TEST_SCHEMA(MakerNoteSchemaUri); + TEST_SCHEMA(IPTCSchemaUri); + TEST_SCHEMA(PhotoshopSchemaUri); +} + + + void KisMetaDataTest::testRationals() { { KisMetaData::Rational sr(-10, -14); QCOMPARE(sr.numerator, -10); QCOMPARE(sr.denominator, -14); KisMetaData::Rational sr2(14, 10); QVERIFY(sr == sr); QVERIFY(!(sr == sr2)); QVERIFY(sr != sr2); } { KisMetaData::Rational sr(10, 14); QCOMPARE(sr.numerator, 10); QCOMPARE(sr.denominator, 14); KisMetaData::Rational sr2(14, 10); QVERIFY(sr == sr); QVERIFY(!(sr == sr2)); QVERIFY(sr != sr2); } } void KisMetaDataTest::testValueCreation() { { Value v; QCOMPARE(v.type(), Value::Invalid); } { Value v(10); QCOMPARE(v.type(), Value::Variant); QCOMPARE(v.asVariant().toInt(), 10); QCOMPARE(v.asInteger(), 10); QCOMPARE(createIntegerValue().type(), Value::Variant); } { Value v("Hello World !"); QCOMPARE(v.type(), Value::Variant); QCOMPARE(v.asVariant().toString(), QString("Hello World !")); QCOMPARE(createStringValue().type(), Value::Variant); } { KisMetaData::Rational sr(42, -12); Value v(sr); QCOMPARE(v.type(), Value::Rational); QCOMPARE(v.asRational(), sr); QCOMPARE(createRationalValue().type(), Value::Rational); QCOMPARE(v.asInteger(), -42 / 12); QCOMPARE(v.asDouble(), -42.0 / 12.0); } { KisMetaData::Rational sr(42, 12); Value v(sr); QCOMPARE(v.type(), Value::Rational); QCOMPARE(v.asRational(), sr); QCOMPARE(createRationalValue().type(), Value::Rational); QCOMPARE(v.asInteger(), 42 / 12); QCOMPARE(v.asDouble(), 42.0 / 12.0); } { QList list; list << createRationalValue() << createIntegerValue() << createStringValue(); Value v(list); QCOMPARE(v.type(), Value::OrderedArray); QVERIFY(v.isArray()); QCOMPARE(v.asArray(), list); QCOMPARE(createListValue().type(), Value::OrderedArray); } { Value v(QList(), Value::OrderedArray); QCOMPARE(v.type(), Value::OrderedArray); QVERIFY(v.isArray()); } { Value v(QList(), Value::UnorderedArray); QCOMPARE(v.type(), Value::UnorderedArray); QVERIFY(v.isArray()); } { Value v(QList(), Value::AlternativeArray); QCOMPARE(v.type(), Value::AlternativeArray); QVERIFY(v.isArray()); } } void KisMetaDataTest::testValueEquality() { QVERIFY(createRationalValue() == createRationalValue()); QVERIFY(createIntegerValue() == createIntegerValue()); QVERIFY(createStringValue() == createStringValue()); QVERIFY(createListValue() == createListValue()); } #define TEST_VALUE_COPY(func) \ { \ Value v1 = func(); \ Value v2(v1); \ Value v3 = v1; \ QCOMPARE(v1, v2); \ QCOMPARE(v1, v3); \ } void KisMetaDataTest::testValueCopy() { TEST_VALUE_COPY(createRationalValue); TEST_VALUE_COPY(createIntegerValue); TEST_VALUE_COPY(createStringValue); TEST_VALUE_COPY(createListValue); } - -#define TEST_SCHEMA(uriStr) \ - { \ - const Schema* schema = SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::uriStr); \ - QVERIFY(schema); \ - QCOMPARE(schema->uri(), KisMetaData::Schema::uriStr); \ - QCOMPARE(schema, SchemaRegistry::instance()->schemaFromPrefix(schema->prefix()) ); \ - QVERIFY( !SchemaRegistry::instance()->create("http://tartampion.com", schema->prefix())); \ - QCOMPARE(schema, SchemaRegistry::instance()->create(KisMetaData::Schema::uriStr, "tartampion")); \ - QCOMPARE(QString(schema->prefix() + ":hello"), schema->generateQualifiedName("hello")); \ - } - - -void KisMetaDataTest::testSchemaBasic() -{ - TEST_SCHEMA(TIFFSchemaUri); - TEST_SCHEMA(EXIFSchemaUri); - TEST_SCHEMA(DublinCoreSchemaUri); - TEST_SCHEMA(XMPSchemaUri); - TEST_SCHEMA(XMPRightsSchemaUri); - TEST_SCHEMA(MakerNoteSchemaUri); - TEST_SCHEMA(IPTCSchemaUri); - TEST_SCHEMA(PhotoshopSchemaUri); -} - void KisMetaDataTest::testEntry() { const Schema* schema = SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri); Value v1 = createIntegerValue(42); Value v2 = createIntegerValue(12); Entry e(schema, "test", v1); QVERIFY(schema); QCOMPARE(e.name(), QString("test")); QCOMPARE(e.schema(), schema); QCOMPARE(e.qualifiedName(), schema->generateQualifiedName("test")); QCOMPARE(e.value(), v1); e.value() = v2; QCOMPARE(e.value(), v2); } void KisMetaDataTest::testStore() { const Schema* schema = SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri); + QVERIFY(schema); Store s; Entry e(schema, "test", createIntegerValue()); QVERIFY(!s.containsEntry(schema, "test")); s.addEntry(e); QVERIFY(s.containsEntry(schema, "test")); QVERIFY(s.containsEntry(e.qualifiedName())); QVERIFY(s.containsEntry(KisMetaData::Schema::TIFFSchemaUri, "test")); s.removeEntry(schema, "test"); QVERIFY(!s.containsEntry(schema, "test")); Entry& e2 = s.getEntry(schema, "hello"); QVERIFY(s.containsEntry(schema, "hello")); QVERIFY(e2.name() == "hello"); QVERIFY(e2.schema() == schema); } void KisMetaDataTest::testFilters() { // Test anonymizer { Store s; const KisMetaData::Filter* filter = FilterRegistry::instance()->get("Anonymizer"); QVERIFY(filter); const KisMetaData::Schema* dcSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::DublinCoreSchemaUri); + QVERIFY(dcSchema); s.addEntry(Entry(dcSchema, "contributor", Value("somevalue"))); s.addEntry(Entry(dcSchema, "creator", Value("somevalue"))); s.addEntry(Entry(dcSchema, "publisher", Value("somevalue"))); s.addEntry(Entry(dcSchema, "rights", Value("somevalue"))); const KisMetaData::Schema* psSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::PhotoshopSchemaUri); s.addEntry(Entry(psSchema, "AuthorsPosition", Value("somevalue"))); s.addEntry(Entry(psSchema, "CaptionWriter", Value("somevalue"))); s.addEntry(Entry(psSchema, "Credit", Value("somevalue"))); s.addEntry(Entry(psSchema, "City", Value("somevalue"))); s.addEntry(Entry(psSchema, "Country", Value("somevalue"))); QList filters; filters << filter; s.applyFilters(filters); QVERIFY(!s.containsEntry(dcSchema, "contributor")); QVERIFY(!s.containsEntry(dcSchema, "creator")); QVERIFY(!s.containsEntry(dcSchema, "publisher")); QVERIFY(!s.containsEntry(dcSchema, "rights")); QVERIFY(!s.containsEntry(psSchema, "AuthorsPosition")); QVERIFY(!s.containsEntry(psSchema, "CaptionWriter")); QVERIFY(!s.containsEntry(psSchema, "Credit")); QVERIFY(!s.containsEntry(psSchema, "City")); QVERIFY(!s.containsEntry(psSchema, "Country")); } } void KisMetaDataTest::testTypeInfo() { QVERIFY(TypeInfo::Private::Boolean->propertyType() == TypeInfo::BooleanType); QVERIFY(TypeInfo::Private::Boolean->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Boolean->choices().size() == 0); QVERIFY(TypeInfo::Private::Boolean->hasCorrectType(Value(true))); QVERIFY(!TypeInfo::Private::Boolean->hasCorrectType(createIntegerValue())); QVERIFY(!TypeInfo::Private::Boolean->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Boolean->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::Integer->propertyType() == TypeInfo::IntegerType); QVERIFY(TypeInfo::Private::Integer->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Integer->choices().size() == 0); QVERIFY(!TypeInfo::Private::Integer->hasCorrectType(Value(true))); QVERIFY(TypeInfo::Private::Integer->hasCorrectType(createIntegerValue())); QVERIFY(!TypeInfo::Private::Integer->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Integer->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::Text->propertyType() == TypeInfo::TextType); QVERIFY(TypeInfo::Private::Text->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Text->choices().size() == 0); QVERIFY(!TypeInfo::Private::Text->hasCorrectType(Value(true))); QVERIFY(!TypeInfo::Private::Text->hasCorrectType(createIntegerValue())); QVERIFY(TypeInfo::Private::Text->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Text->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::Date->propertyType() == TypeInfo::DateType); QVERIFY(TypeInfo::Private::Date->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Date->choices().size() == 0); QVERIFY(TypeInfo::Private::Date->hasCorrectType(Value(QDateTime()))); QVERIFY(!TypeInfo::Private::Date->hasCorrectType(createIntegerValue())); QVERIFY(!TypeInfo::Private::Date->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Date->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::Rational->propertyType() == TypeInfo::RationalType); QVERIFY(TypeInfo::Private::Rational->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Rational->choices().size() == 0); QVERIFY(TypeInfo::Private::Rational->hasCorrectType(createRationalValue())); QVERIFY(!TypeInfo::Private::Rational->hasCorrectType(createIntegerValue())); QVERIFY(!TypeInfo::Private::Rational->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Rational->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::GPSCoordinate->propertyType() == TypeInfo::GPSCoordinateType); QVERIFY(TypeInfo::Private::GPSCoordinate->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::GPSCoordinate->choices().size() == 0); QVERIFY(TypeInfo::Private::LangArray->propertyType() == TypeInfo::LangArrayType); QVERIFY(TypeInfo::Private::LangArray->embeddedPropertyType() == TypeInfo::Private::Text); QVERIFY(TypeInfo::Private::LangArray->choices().size() == 0); // Create List of integer Value QList< Value > goodIntegerList; goodIntegerList.push_back(createIntegerValue()); goodIntegerList.push_back(createIntegerValue(12)); QList< Value > badIntegerList; badIntegerList.push_back(createIntegerValue()); badIntegerList.push_back(createStringValue()); badIntegerList.push_back(createIntegerValue(12)); // Test OrderedArray const TypeInfo* arrOA1 = TypeInfo::Private::orderedArray(TypeInfo::Private::Integer); QVERIFY(arrOA1->propertyType() == TypeInfo::OrderedArrayType); QVERIFY(arrOA1->embeddedPropertyType() == TypeInfo::Private::Integer); QVERIFY(arrOA1->choices().size() == 0); QVERIFY(arrOA1 == TypeInfo::Private::orderedArray(TypeInfo::Private::Integer)); const TypeInfo* arrOA2 = TypeInfo::Private::orderedArray(TypeInfo::Private::Text); QVERIFY(arrOA1 != arrOA2); QVERIFY(arrOA2->embeddedPropertyType() == TypeInfo::Private::Text); QVERIFY(!arrOA1->hasCorrectType(Value(true))); QVERIFY(!arrOA1->hasCorrectType(createIntegerValue())); QVERIFY(!arrOA1->hasCorrectType(createStringValue())); QVERIFY(!arrOA1->hasCorrectType(createListValue())); QVERIFY(arrOA1->hasCorrectType(Value(goodIntegerList, Value::OrderedArray))); QVERIFY(!arrOA1->hasCorrectType(Value(badIntegerList, Value::OrderedArray))); // Test UnarderedArray const TypeInfo* arrUOA1 = TypeInfo::Private::unorderedArray(TypeInfo::Private::Integer); QVERIFY(arrUOA1->propertyType() == TypeInfo::UnorderedArrayType); QVERIFY(arrUOA1->embeddedPropertyType() == TypeInfo::Private::Integer); QVERIFY(arrUOA1->choices().size() == 0); QVERIFY(arrUOA1 == TypeInfo::Private::unorderedArray(TypeInfo::Private::Integer)); const TypeInfo* arrUOA2 = TypeInfo::Private::unorderedArray(TypeInfo::Private::Text); QVERIFY(arrUOA1 != arrUOA2); QVERIFY(arrUOA2->embeddedPropertyType() == TypeInfo::Private::Text); QVERIFY(arrUOA1 != arrOA1); QVERIFY(arrUOA2 != arrOA2); QVERIFY(!arrUOA1->hasCorrectType(Value(true))); QVERIFY(!arrUOA1->hasCorrectType(createIntegerValue())); QVERIFY(!arrUOA1->hasCorrectType(createStringValue())); QVERIFY(!arrUOA1->hasCorrectType(createListValue())); QVERIFY(arrUOA1->hasCorrectType(Value(goodIntegerList, Value::UnorderedArray))); QVERIFY(!arrUOA1->hasCorrectType(Value(badIntegerList, Value::UnorderedArray))); // Test AlternativeArray const TypeInfo* arrAA1 = TypeInfo::Private::alternativeArray(TypeInfo::Private::Integer); QVERIFY(arrAA1->propertyType() == TypeInfo::AlternativeArrayType); QVERIFY(arrAA1->embeddedPropertyType() == TypeInfo::Private::Integer); QVERIFY(arrAA1->choices().size() == 0); QVERIFY(arrAA1 == TypeInfo::Private::alternativeArray(TypeInfo::Private::Integer)); const TypeInfo* arrAA2 = TypeInfo::Private::alternativeArray(TypeInfo::Private::Text); QVERIFY(arrAA1 != arrAA2); QVERIFY(arrAA2->embeddedPropertyType() == TypeInfo::Private::Text); QVERIFY(arrAA1 != arrOA1); QVERIFY(arrAA1 != arrUOA1); QVERIFY(arrAA2 != arrOA2); QVERIFY(arrAA2 != arrUOA2); QVERIFY(!arrAA1->hasCorrectType(Value(true))); QVERIFY(!arrAA1->hasCorrectType(createIntegerValue())); QVERIFY(!arrAA1->hasCorrectType(createStringValue())); QVERIFY(!arrAA1->hasCorrectType(createListValue())); QVERIFY(arrAA1->hasCorrectType(Value(goodIntegerList, Value::AlternativeArray))); QVERIFY(!arrAA1->hasCorrectType(Value(badIntegerList, Value::AlternativeArray))); // Test Choice QList< TypeInfo::Choice > choices; choices.push_back(TypeInfo::Choice(Value(12), "Hello")); choices.push_back(TypeInfo::Choice(Value(42), "World")); const TypeInfo* oChoice = TypeInfo::Private::createChoice(TypeInfo::OpenedChoice, TypeInfo::Private::Integer, choices); QVERIFY(oChoice->propertyType() == TypeInfo::OpenedChoice); QVERIFY(oChoice->embeddedPropertyType() == TypeInfo::Private::Integer); QVERIFY(oChoice->choices().size() == 2); QVERIFY(oChoice->choices()[0].value() == Value(12)); QVERIFY(oChoice->choices()[0].hint() == "Hello"); QVERIFY(oChoice->choices()[1].value() == Value(42)); QVERIFY(oChoice->choices()[1].hint() == "World"); QVERIFY(!oChoice->hasCorrectType(Value(true))); QVERIFY(oChoice->hasCorrectType(createIntegerValue(12))); QVERIFY(oChoice->hasCorrectType(createIntegerValue(-12))); QVERIFY(oChoice->hasCorrectType(createIntegerValue(42))); QVERIFY(!oChoice->hasCorrectType(createStringValue())); QVERIFY(!oChoice->hasCorrectType(createListValue())); QVERIFY(!oChoice->hasCorrectType(Value(goodIntegerList, Value::AlternativeArray))); QVERIFY(!oChoice->hasCorrectType(Value(badIntegerList, Value::AlternativeArray))); const TypeInfo* cChoice = TypeInfo::Private::createChoice(TypeInfo::ClosedChoice, TypeInfo::Private::Integer, choices); QVERIFY(cChoice->propertyType() == TypeInfo::ClosedChoice); QVERIFY(!cChoice->hasCorrectType(Value(true))); QVERIFY(cChoice->hasCorrectType(createIntegerValue(12))); QVERIFY(cChoice->hasCorrectType(createIntegerValue(-12))); QVERIFY(cChoice->hasCorrectType(createIntegerValue(42))); QVERIFY(!cChoice->hasCorrectType(createStringValue())); QVERIFY(!cChoice->hasCorrectType(createListValue())); QVERIFY(!cChoice->hasCorrectType(Value(goodIntegerList, Value::AlternativeArray))); QVERIFY(!cChoice->hasCorrectType(Value(badIntegerList, Value::AlternativeArray))); QVERIFY(cChoice->hasCorrectValue(createIntegerValue(12))); QVERIFY(!cChoice->hasCorrectValue(createIntegerValue(-12))); QVERIFY(cChoice->hasCorrectValue(createIntegerValue(42))); // Test structure } void KisMetaDataTest::testSchemaParse() { const Schema* exifSchema = SchemaRegistry::instance()->schemaFromUri(Schema::EXIFSchemaUri); QVERIFY(exifSchema); const TypeInfo* colorSpaceType = exifSchema->propertyType("ColorSpace"); QVERIFY(colorSpaceType); QVERIFY(colorSpaceType->propertyType() == TypeInfo::ClosedChoice); QVERIFY(colorSpaceType->choices().size() == 2); QVERIFY(colorSpaceType->choices()[0].value() == Value(1)); QVERIFY(colorSpaceType->choices()[0].hint() == "sRGB"); QVERIFY(colorSpaceType->choices()[1].value() == Value(65635)); QVERIFY(colorSpaceType->choices()[1].hint() == "uncalibrated"); QVERIFY(exifSchema->propertyType("CompressedBitsPerPixel")); QVERIFY(exifSchema->propertyType("CompressedBitsPerPixel")->propertyType() == TypeInfo::RationalType); QVERIFY(exifSchema->propertyType("PixelXDimension")); QVERIFY(exifSchema->propertyType("PixelXDimension")->propertyType() == TypeInfo::IntegerType); QVERIFY(exifSchema->propertyType("UserComment")); QVERIFY(exifSchema->propertyType("UserComment")->propertyType() == TypeInfo::LangArrayType); QVERIFY(exifSchema->propertyType("RelatedSoundFile")); QVERIFY(exifSchema->propertyType("RelatedSoundFile")->propertyType() == TypeInfo::TextType); QVERIFY(exifSchema->propertyType("DateTimeOriginal")); QVERIFY(exifSchema->propertyType("DateTimeOriginal")->propertyType() == TypeInfo::DateType); QVERIFY(exifSchema->propertyType("ISOSpeedRatings")); QVERIFY(exifSchema->propertyType("ISOSpeedRatings")->propertyType() == TypeInfo::OrderedArrayType); QVERIFY(exifSchema->propertyType("ISOSpeedRatings")->embeddedPropertyType() == TypeInfo::Private::Integer); const TypeInfo* oecfType = exifSchema->propertyType("OECF"); QVERIFY(oecfType); QVERIFY(oecfType->propertyType() == TypeInfo::StructureType); QVERIFY(oecfType == exifSchema->structure("OECFSFR")); QVERIFY(oecfType->structureName() == "OECFSFR"); QVERIFY(oecfType->structureSchema()); QVERIFY(oecfType->structureSchema()->propertyType("Columns")->propertyType() == TypeInfo::IntegerType); QVERIFY(oecfType->structureSchema()->propertyType("Rows")->propertyType() == TypeInfo::IntegerType); QVERIFY(oecfType->structureSchema()->propertyType("Names")->propertyType() == TypeInfo::OrderedArrayType); QVERIFY(oecfType->structureSchema()->propertyType("Names")->embeddedPropertyType()->propertyType() == TypeInfo::TextType); QVERIFY(oecfType->structureSchema()->propertyType("Values")->propertyType() == TypeInfo::OrderedArrayType); QVERIFY(oecfType->structureSchema()->propertyType("Values")->embeddedPropertyType()->propertyType() == TypeInfo::RationalType); } void KisMetaDataTest::testParser() { Value intV = TypeInfo::Private::Integer->parser()->parse("1242"); QVERIFY(intV.type() == Value::Variant); QVERIFY(intV.asVariant() == 1242); QVERIFY(intV.asVariant().type() == QVariant::Int); Value textV = TypeInfo::Private::Text->parser()->parse("Bouh"); QVERIFY(textV.type() == Value::Variant); QVERIFY(textV.asVariant() == "Bouh"); QVERIFY(textV.asVariant().type() == QVariant::String); Value dateV1 = TypeInfo::Private::Date->parser()->parse("2005-10-31"); QVERIFY(dateV1.type() == Value::Variant); QDateTime d1 = dateV1.asVariant().toDateTime(); QVERIFY(d1.date().year() == 2005); QVERIFY(d1.date().month() == 10); QVERIFY(d1.date().day() == 31); Value dateV2 = TypeInfo::Private::Date->parser()->parse("2005"); QVERIFY(dateV2.type() == Value::Variant); QDateTime d2 = dateV2.asVariant().toDateTime(); QVERIFY(d2.date().year() == 2005); Value dateV3 = TypeInfo::Private::Date->parser()->parse("2005-12"); QVERIFY(dateV3.type() == Value::Variant); QDateTime d3 = dateV3.asVariant().toDateTime(); QVERIFY(d3.date().year() == 2005); QVERIFY(d3.date().month() == 12); Value dateV4 = TypeInfo::Private::Date->parser()->parse("2005-10-31T12:20"); QVERIFY(dateV4.type() == Value::Variant); QDateTime d4 = dateV4.asVariant().toDateTime(); QVERIFY(d4.date().year() == 2005); QVERIFY(d4.date().month() == 10); QVERIFY(d4.date().day() == 31); QVERIFY(d4.time().hour() == 12); QVERIFY(d4.time().minute() == 20); Value dateV5 = TypeInfo::Private::Date->parser()->parse("2005-10-31T12:20:32"); QVERIFY(dateV5.type() == Value::Variant); QDateTime d5 = dateV5.asVariant().toDateTime(); QVERIFY(d5.date().year() == 2005); QVERIFY(d5.date().month() == 10); QVERIFY(d5.date().day() == 31); QVERIFY(d5.time().hour() == 12); QVERIFY(d5.time().minute() == 20); QVERIFY(d5.time().second() == 32); Value dateV6 = TypeInfo::Private::Date->parser()->parse("2005-10-31T12:20:32-06:00"); QVERIFY(dateV6.type() == Value::Variant); QDateTime d6 = dateV6.asVariant().toDateTime(); QVERIFY(d6.date().year() == 2005); QVERIFY(d6.date().month() == 10); QVERIFY(d6.date().day() == 31); QVERIFY(d6.time().hour() == 18); QVERIFY(d6.time().minute() == 20); QVERIFY(d6.time().second() == 32); Value rational1 = TypeInfo::Private::Rational->parser()->parse("-10/20"); QVERIFY(rational1.type() == Value::Rational); QVERIFY(rational1.asRational().numerator == -10); QVERIFY(rational1.asRational().denominator == 20); Value rational2 = TypeInfo::Private::Rational->parser()->parse("10/20"); QVERIFY(rational2.type() == Value::Rational); QVERIFY(rational2.asRational().numerator == 10); QVERIFY(rational2.asRational().denominator == 20); } void KisMetaDataTest::testValidator() { Store store; const Schema* exif = SchemaRegistry::instance()->schemaFromUri(Schema::EXIFSchemaUri); QVERIFY(exif); store.addEntry(Entry(exif, "PixelXDimension", createIntegerValue())); store.addEntry(Entry(exif, "PixelYDimension", createIntegerValue())); store.addEntry(Entry(exif, "RelatedSoundFile", createStringValue())); store.addEntry(Entry(exif, "ColorSpace", createIntegerValue(1))); store.addEntry(Entry(exif, "ExposureTime", createRationalValue())); Validator validator(&store); QCOMPARE(validator.countInvalidEntries(), 0); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries().size(), 0); // Unknown entry store.addEntry(Entry(exif, "azerty", createIntegerValue())); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("azerty")].type(), Validator::Reason::UNKNOWN_ENTRY); store.removeEntry(exif, "azerty"); // Invalid type for rational store.addEntry(Entry(exif, "FNumber", createIntegerValue())); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("FNumber")].type(), Validator::Reason::INVALID_TYPE); store.removeEntry(exif, "FNumber"); // Invalid type for integer store.addEntry(Entry(exif, "SubjectLocation", createStringValue())); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("SubjectLocation")].type(), Validator::Reason::INVALID_TYPE); store.removeEntry(exif, "SubjectLocation"); // Invalid type for choice store.addEntry(Entry(exif, "SensingMethod", createStringValue())); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("SensingMethod")].type(), Validator::Reason::INVALID_TYPE); store.removeEntry(exif, "SensingMethod"); // Invalid value for choice store.addEntry(Entry(exif, "SensingMethod", createIntegerValue(1242))); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("SensingMethod")].type(), Validator::Reason::INVALID_VALUE); store.removeEntry(exif, "SensingMethod"); } -QTEST_MAIN(KisMetaDataTest) +KISTEST_MAIN(KisMetaDataTest) diff --git a/libs/image/tests/kis_meta_data_test.h b/libs/image/tests/kis_meta_data_test.h index 9a6dd0c225..f2a4b767fd 100644 --- a/libs/image/tests/kis_meta_data_test.h +++ b/libs/image/tests/kis_meta_data_test.h @@ -1,53 +1,53 @@ /* * Copyright (c) 2008 Cyrille Berger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIS_META_DATA_TEST_H #define KIS_META_DATA_TEST_H #include namespace KisMetaData { class Value; } class KisMetaDataTest : public QObject { Q_OBJECT private Q_SLOTS: + void testSchemaBasic(); void testRationals(); void testValueCreation(); void testValueEquality(); void testValueCopy(); - void testSchemaBasic(); void testEntry(); void testStore(); void testFilters(); void testTypeInfo(); void testSchemaParse(); void testParser(); void testValidator(); private: KisMetaData::Value createRationalValue(); KisMetaData::Value createIntegerValue(int v = 42); KisMetaData::Value createStringValue(); KisMetaData::Value createListValue(); }; #endif