diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt index a72ba71e6c..65d56aa778 100644 --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -1,550 +1,551 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/qtlockedfile ${EXIV2_INCLUDE_DIR} ) include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR} ${OCIO_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ) add_subdirectory( tests ) if (APPLE) find_library(FOUNDATION_LIBRARY Foundation) endif () set(kritaui_LIB_SRCS canvas/kis_canvas_widget_base.cpp canvas/kis_canvas2.cpp canvas/kis_canvas_updates_compressor.cpp canvas/kis_canvas_controller.cpp canvas/kis_paintop_transformation_connector.cpp canvas/kis_display_color_converter.cpp canvas/kis_display_filter.cpp canvas/kis_exposure_gamma_correction_interface.cpp canvas/kis_tool_proxy.cpp canvas/kis_canvas_decoration.cc canvas/kis_coordinates_converter.cpp canvas/kis_grid_manager.cpp canvas/kis_grid_decoration.cpp canvas/kis_grid_config.cpp canvas/kis_prescaled_projection.cpp canvas/kis_qpainter_canvas.cpp canvas/kis_projection_backend.cpp canvas/kis_update_info.cpp canvas/kis_image_patch.cpp canvas/kis_image_pyramid.cpp canvas/kis_infinity_manager.cpp canvas/kis_change_guides_command.cpp canvas/kis_guides_decoration.cpp canvas/kis_guides_manager.cpp canvas/kis_guides_config.cpp canvas/kis_snap_config.cpp canvas/kis_snap_line_strategy.cpp canvas/KisSnapPointStrategy.cpp dialogs/kis_about_application.cpp dialogs/kis_dlg_adj_layer_props.cc dialogs/kis_dlg_adjustment_layer.cc dialogs/kis_dlg_filter.cpp dialogs/kis_dlg_generator_layer.cpp dialogs/kis_dlg_file_layer.cpp dialogs/kis_dlg_filter.cpp dialogs/kis_dlg_stroke_selection_properties.cpp dialogs/kis_dlg_image_properties.cc dialogs/kis_dlg_layer_properties.cc dialogs/kis_dlg_preferences.cc dialogs/slider_and_spin_box_sync.cpp dialogs/kis_dlg_blacklist_cleanup.cpp dialogs/kis_dlg_layer_style.cpp dialogs/kis_dlg_png_import.cpp dialogs/kis_dlg_import_image_sequence.cpp dialogs/kis_delayed_save_dialog.cpp dialogs/kis_dlg_internal_color_selector.cpp flake/kis_node_dummies_graph.cpp flake/kis_dummies_facade_base.cpp flake/kis_dummies_facade.cpp flake/kis_node_shapes_graph.cpp flake/kis_node_shape.cpp flake/kis_shape_controller.cpp flake/kis_shape_layer.cc flake/kis_shape_layer_canvas.cpp flake/kis_shape_selection.cpp flake/kis_shape_selection_canvas.cpp flake/kis_shape_selection_model.cpp flake/kis_take_all_shapes_command.cpp brushhud/kis_uniform_paintop_property_widget.cpp brushhud/kis_brush_hud.cpp brushhud/kis_round_hud_button.cpp brushhud/kis_dlg_brush_hud_config.cpp brushhud/kis_brush_hud_properties_list.cpp brushhud/kis_brush_hud_properties_config.cpp kis_aspect_ratio_locker.cpp kis_autogradient.cc kis_bookmarked_configurations_editor.cc kis_bookmarked_configurations_model.cc kis_bookmarked_filter_configurations_model.cc kis_base_option.cpp kis_canvas_resource_provider.cpp kis_derived_resources.cpp kis_categories_mapper.cpp kis_categorized_list_model.cpp kis_categorized_item_delegate.cpp kis_clipboard.cc kis_config.cc kis_config_notifier.cpp kis_control_frame.cpp kis_composite_ops_model.cc kis_paint_ops_model.cpp kis_cursor.cc kis_cursor_cache.cpp kis_custom_pattern.cc kis_file_layer.cpp kis_safe_document_loader.cpp kis_splash_screen.cpp kis_filter_manager.cc kis_filters_model.cc kis_histogram_view.cc + KisImageBarrierLockerWithFeedback.cpp kis_image_manager.cc kis_image_view_converter.cpp kis_import_catcher.cc kis_layer_manager.cc kis_mask_manager.cc kis_mimedata.cpp kis_node_commands_adapter.cpp kis_node_manager.cpp kis_node_juggler_compressed.cpp kis_node_selection_adapter.cpp kis_node_insertion_adapter.cpp kis_node_model.cpp kis_node_filter_proxy_model.cpp kis_model_index_converter_base.cpp kis_model_index_converter.cpp kis_model_index_converter_show_all.cpp kis_painting_assistant.cc kis_painting_assistants_decoration.cpp kis_painting_assistants_manager.cpp kis_paintop_box.cc kis_paintop_option.cpp kis_paintop_options_model.cpp kis_paintop_settings_widget.cpp kis_popup_palette.cpp kis_png_converter.cpp kis_preference_set_registry.cpp kis_script_manager.cpp kis_resource_server_provider.cpp KisSelectedShapesProxy.cpp kis_selection_decoration.cc kis_selection_manager.cc kis_statusbar.cc kis_zoom_manager.cc kis_favorite_resource_manager.cpp kis_workspace_resource.cpp kis_action.cpp kis_action_manager.cpp kis_view_plugin.cpp kis_canvas_controls_manager.cpp kis_tooltip_manager.cpp kis_multinode_property.cpp kis_stopgradient_editor.cpp kisexiv2/kis_exif_io.cpp kisexiv2/kis_exiv2.cpp kisexiv2/kis_iptc_io.cpp kisexiv2/kis_xmp_io.cpp opengl/kis_opengl.cpp opengl/kis_opengl_canvas2.cpp opengl/kis_opengl_canvas_debugger.cpp opengl/kis_opengl_image_textures.cpp opengl/kis_texture_tile.cpp opengl/kis_opengl_shader_loader.cpp kis_fps_decoration.cpp recorder/kis_node_query_path_editor.cc recorder/kis_recorded_action_creator.cc recorder/kis_recorded_action_creator_factory.cc recorder/kis_recorded_action_creator_factory_registry.cc recorder/kis_recorded_action_editor_factory.cc recorder/kis_recorded_action_editor_factory_registry.cc recorder/kis_recorded_filter_action_editor.cc recorder/kis_recorded_filter_action_creator.cpp recorder/kis_recorded_paint_action_editor.cc tool/kis_selection_tool_helper.cpp tool/kis_selection_tool_config_widget_helper.cpp tool/kis_rectangle_constraint_widget.cpp tool/kis_shape_tool_helper.cpp tool/kis_tool.cc tool/kis_delegated_tool_policies.cpp tool/kis_tool_freehand.cc tool/kis_speed_smoother.cpp tool/kis_painting_information_builder.cpp tool/kis_stabilized_events_sampler.cpp tool/kis_tool_freehand_helper.cpp tool/kis_tool_multihand_helper.cpp tool/kis_figure_painting_tool_helper.cpp tool/kis_recording_adapter.cpp tool/kis_tool_paint.cc tool/kis_tool_shape.cc tool/kis_tool_ellipse_base.cpp tool/kis_tool_rectangle_base.cpp tool/kis_tool_polyline_base.cpp tool/kis_tool_utils.cpp tool/kis_resources_snapshot.cpp tool/kis_smoothing_options.cpp tool/KisStabilizerDelayedPaintHelper.cpp tool/strokes/freehand_stroke.cpp tool/strokes/kis_painter_based_stroke_strategy.cpp tool/strokes/kis_filter_stroke_strategy.cpp tool/strokes/kis_color_picker_stroke_strategy.cpp widgets/kis_cmb_composite.cc widgets/kis_cmb_contour.cpp widgets/kis_cmb_gradient.cpp widgets/kis_paintop_list_widget.cpp widgets/kis_cmb_idlist.cc widgets/kis_color_space_selector.cc widgets/kis_advanced_color_space_selector.cc widgets/kis_cie_tongue_widget.cpp widgets/kis_tone_curve_widget.cpp widgets/kis_curve_widget.cpp widgets/kis_custom_image_widget.cc widgets/kis_image_from_clipboard_widget.cpp widgets/kis_double_widget.cc widgets/kis_filter_selector_widget.cc widgets/kis_gradient_chooser.cc widgets/kis_gradient_slider_widget.cc widgets/kis_gradient_slider.cpp widgets/kis_iconwidget.cc widgets/kis_mask_widgets.cpp widgets/kis_meta_data_merge_strategy_chooser_widget.cc widgets/kis_multi_bool_filter_widget.cc widgets/kis_multi_double_filter_widget.cc widgets/kis_multi_integer_filter_widget.cc widgets/kis_multipliers_double_slider_spinbox.cpp widgets/kis_paintop_presets_popup.cpp widgets/kis_tool_options_popup.cpp widgets/kis_paintop_presets_chooser_popup.cpp widgets/kis_pattern_chooser.cc widgets/kis_popup_button.cc widgets/kis_preset_chooser.cpp widgets/kis_progress_widget.cpp widgets/kis_selection_options.cc widgets/kis_scratch_pad.cpp widgets/kis_scratch_pad_event_filter.cpp widgets/kis_preset_selector_strip.cpp widgets/kis_slider_spin_box.cpp widgets/kis_size_group.cpp widgets/kis_size_group_p.cpp widgets/kis_wdg_generator.cpp widgets/kis_workspace_chooser.cpp widgets/squeezedcombobox.cpp widgets/kis_categorized_list_view.cpp widgets/kis_widget_chooser.cpp widgets/kis_tool_button.cpp widgets/kis_floating_message.cpp widgets/kis_lod_availability_widget.cpp widgets/kis_color_label_selector_widget.cpp widgets/kis_color_filter_combo.cpp widgets/kis_elided_label.cpp widgets/kis_stopgradient_slider_widget.cpp widgets/kis_spinbox_color_selector.cpp widgets/kis_screen_color_picker.cpp widgets/KoDualColorButton.cpp widgets/kis_color_input.cpp widgets/kis_color_button.cpp widgets/KisVisualColorSelector.cpp widgets/KisVisualColorSelectorShape.cpp widgets/KisVisualEllipticalSelectorShape.cpp widgets/KisVisualRectangleSelectorShape.cpp widgets/KisVisualTriangleSelectorShape.cpp widgets/KoStrokeConfigWidget.cpp widgets/KoFillConfigWidget.cpp widgets/KoShapeFillWrapper.cpp utils/kis_document_aware_spin_box_unit_manager.cpp input/kis_input_manager.cpp input/kis_input_manager_p.cpp input/kis_extended_modifiers_mapper.cpp input/kis_abstract_input_action.cpp input/kis_tool_invocation_action.cpp input/kis_pan_action.cpp input/kis_alternate_invocation_action.cpp input/kis_rotate_canvas_action.cpp input/kis_zoom_action.cpp input/kis_change_frame_action.cpp input/kis_gamma_exposure_action.cpp input/kis_show_palette_action.cpp input/kis_change_primary_setting_action.cpp input/kis_abstract_shortcut.cpp input/kis_single_action_shortcut.cpp input/kis_stroke_shortcut.cpp input/kis_shortcut_matcher.cpp input/kis_select_layer_action.cpp operations/kis_operation.cpp operations/kis_operation_configuration.cpp operations/kis_operation_registry.cpp operations/kis_operation_ui_factory.cpp operations/kis_operation_ui_widget.cpp operations/kis_filter_selection_operation.cpp actions/kis_selection_action_factories.cpp actions/KisPasteActionFactory.cpp input/kis_touch_shortcut.cpp kis_document_undo_store.cpp kis_transaction_based_command.cpp kis_gui_context_command.cpp kis_gui_context_command_p.cpp input/kis_tablet_debugger.cpp input/kis_input_profile_manager.cpp input/kis_input_profile.cpp input/kis_shortcut_configuration.cpp input/config/kis_input_configuration_page.cpp input/config/kis_edit_profiles_dialog.cpp input/config/kis_input_profile_model.cpp input/config/kis_input_configuration_page_item.cpp input/config/kis_action_shortcuts_model.cpp input/config/kis_input_type_delegate.cpp input/config/kis_input_mode_delegate.cpp input/config/kis_input_button.cpp input/config/kis_input_editor_delegate.cpp input/config/kis_mouse_input_editor.cpp input/config/kis_wheel_input_editor.cpp input/config/kis_key_input_editor.cpp processing/fill_processing_visitor.cpp kis_asl_layer_style_serializer.cpp kis_psd_layer_style_resource.cpp canvas/kis_mirror_axis.cpp kis_abstract_perspective_grid.cpp KisApplication.cpp KisAutoSaveRecoveryDialog.cpp KisDetailsPane.cpp KisDocument.cpp KisNodeDelegate.cpp kis_node_view_visibility_delegate.cpp KisNodeToolTip.cpp KisNodeView.cpp kis_node_view_color_scheme.cpp KisImportExportFilter.cpp KisFilterEntry.cpp KisImportExportManager.cpp KisMainWindow.cpp KisOpenPane.cpp KisPart.cpp KisPrintJob.cpp KisTemplate.cpp KisTemplateCreateDia.cpp KisTemplateGroup.cpp KisTemplates.cpp KisTemplatesPane.cpp KisTemplateTree.cpp KisUndoStackAction.cpp KisView.cpp thememanager.cpp kis_mainwindow_observer.cpp KisViewManager.cpp kis_mirror_manager.cpp qtlockedfile/qtlockedfile.cpp qtsingleapplication/qtlocalpeer.cpp qtsingleapplication/qtsingleapplication.cpp KisResourceBundle.cpp KisResourceBundleManifest.cpp kis_md5_generator.cpp KisApplicationArguments.cpp KisNetworkAccessManager.cpp KisMultiFeedRSSModel.cpp KisRemoteFileFetcher.cpp KisPaletteModel.cpp kis_palette_delegate.cpp kis_palette_view.cpp KisColorsetChooser.cpp KisSaveGroupVisitor.cpp ) if(WIN32) if (NOT Qt5Gui_PRIVATE_INCLUDE_DIRS) message(FATAL_ERROR "Qt5Gui Private header are missing!") endif() set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} input/kis_tablet_event.cpp input/wintab/kis_tablet_support_win.cpp input/wintab/kis_screen_size_choice_dialog.cpp qtlockedfile/qtlockedfile_win.cpp ) include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) endif() set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} kis_animation_frame_cache.cpp kis_animation_cache_populator.cpp KisAnimationCacheRegenerator.cpp dialogs/KisAnimationCacheUpdateProgressDialog.cpp canvas/kis_animation_player.cpp kis_animation_exporter.cpp kis_animation_importer.cpp KisSyncedAudioPlayback.cpp ) if(UNIX) set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} input/kis_tablet_event.cpp input/wintab/kis_tablet_support.cpp qtlockedfile/qtlockedfile_unix.cpp ) if(NOT APPLE) set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} input/wintab/kis_tablet_support_x11.cpp input/wintab/qxcbconnection_xi2.cpp input/wintab/qxcbconnection.cpp input/wintab/kis_xi2_event_filter.cpp ) endif() endif() ki18n_wrap_ui(kritaui_LIB_SRCS widgets/KoFillConfigWidget.ui forms/wdgdlgpngimport.ui forms/wdgfullscreensettings.ui forms/wdgautogradient.ui forms/wdggeneralsettings.ui forms/wdgperformancesettings.ui forms/wdggenerators.ui forms/wdgbookmarkedconfigurationseditor.ui forms/wdgapplyprofile.ui forms/wdgcustompattern.ui forms/wdglayerproperties.ui forms/wdgcolorsettings.ui forms/wdgtabletsettings.ui forms/wdgcolorspaceselector.ui forms/wdgcolorspaceselectoradvanced.ui forms/wdgdisplaysettings.ui forms/kis_previewwidgetbase.ui forms/kis_matrix_widget.ui forms/wdgselectionoptions.ui forms/wdggeometryoptions.ui forms/wdgnewimage.ui forms/wdgimageproperties.ui forms/wdgmaskfromselection.ui forms/wdgmasksource.ui forms/wdgfilterdialog.ui forms/wdgmetadatamergestrategychooser.ui forms/wdgpaintoppresets.ui forms/wdgpaintopsettings.ui forms/wdgdlggeneratorlayer.ui forms/wdgdlgfilelayer.ui forms/wdgfilterselector.ui forms/wdgfilternodecreation.ui forms/wdgpaintactioneditor.ui forms/wdgmultipliersdoublesliderspinbox.ui forms/wdgnodequerypatheditor.ui forms/wdgpresetselectorstrip.ui forms/wdgdlgblacklistcleanup.ui forms/wdgrectangleconstraints.ui forms/wdgimportimagesequence.ui forms/wdgstrokeselectionproperties.ui forms/KisDetailsPaneBase.ui forms/KisOpenPaneBase.ui forms/wdgstopgradienteditor.ui brushhud/kis_dlg_brush_hud_config.ui forms/wdgdlginternalcolorselector.ui dialogs/kis_delayed_save_dialog.ui input/config/kis_input_configuration_page.ui input/config/kis_edit_profiles_dialog.ui input/config/kis_input_configuration_page_item.ui input/config/kis_mouse_input_editor.ui input/config/kis_wheel_input_editor.ui input/config/kis_key_input_editor.ui layerstyles/wdgBevelAndEmboss.ui layerstyles/wdgblendingoptions.ui layerstyles/WdgColorOverlay.ui layerstyles/wdgContour.ui layerstyles/wdgdropshadow.ui layerstyles/WdgGradientOverlay.ui layerstyles/wdgInnerGlow.ui layerstyles/wdglayerstyles.ui layerstyles/WdgPatternOverlay.ui layerstyles/WdgSatin.ui layerstyles/WdgStroke.ui layerstyles/wdgstylesselector.ui layerstyles/wdgTexture.ui wdgsplash.ui input/wintab/kis_screen_size_choice_dialog.ui ) QT5_WRAP_CPP(kritaui_HEADERS_MOC KisNodePropertyAction_p.h) add_library(kritaui SHARED ${kritaui_HEADERS_MOC} ${kritaui_LIB_SRCS} ) generate_export_header(kritaui BASE_NAME kritaui) target_link_libraries(kritaui KF5::CoreAddons KF5::Completion KF5::I18n KF5::ItemViews Qt5::Network kritaimpex kritacolor kritaimage kritalibbrush kritawidgets kritawidgetutils ${PNG_LIBRARIES} ${EXIV2_LIBRARIES} ) if (HAVE_QT_MULTIMEDIA) target_link_libraries(kritaui Qt5::Multimedia) endif() if (HAVE_KIO) target_link_libraries(kritaui KF5::KIOCore) endif() if (NOT WIN32 AND NOT APPLE) target_link_libraries(kritaui ${X11_X11_LIB} ${X11_Xinput_LIB} ${XCB_LIBRARIES}) endif() if(APPLE) target_link_libraries(kritaui ${FOUNDATION_LIBRARY}) endif () target_link_libraries(kritaui ${OPENEXR_LIBRARIES}) # Add VSync disable workaround if(NOT WIN32 AND NOT APPLE) target_link_libraries(kritaui ${CMAKE_DL_LIBS} Qt5::X11Extras) endif() if(X11_FOUND) target_link_libraries(kritaui Qt5::X11Extras ${X11_LIBRARIES}) endif() target_include_directories(kritaui PUBLIC $ $ $ $ $ $ $ ) set_target_properties(kritaui PROPERTIES VERSION ${GENERIC_KRITA_LIB_VERSION} SOVERSION ${GENERIC_KRITA_LIB_SOVERSION} ) install(TARGETS kritaui ${INSTALL_TARGETS_DEFAULT_ARGS}) if (APPLE) install(FILES osx.stylesheet DESTINATION ${DATA_INSTALL_DIR}/krita) endif () diff --git a/libs/ui/KisImageBarrierLockerWithFeedback.cpp b/libs/ui/KisImageBarrierLockerWithFeedback.cpp new file mode 100644 index 0000000000..cb7e3e103a --- /dev/null +++ b/libs/ui/KisImageBarrierLockerWithFeedback.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Dmitry Kazakov + * + * 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 "KisImageBarrierLockerWithFeedback.h" + +#include +#include +#include + +#include "kis_image.h" + +namespace KisImageBarrierLockerWithFeedbackImplPrivate { +void blockWithFeedback(KisImageSP image) +{ + if (!image) return; + + // TODO1: find the window corrsponding to the awaited image! + // TODO2: move blocking code from KisViewManager here + KisMainWindow *window = KisPart::instance()->currentMainwindow(); + if (!window) return; + + KisViewManager *viewManager = window->viewManager(); + viewManager->blockUntillOperationsFinishedForced(image); +} +} diff --git a/libs/ui/KisImageBarrierLockerWithFeedback.h b/libs/ui/KisImageBarrierLockerWithFeedback.h new file mode 100644 index 0000000000..0793bb30df --- /dev/null +++ b/libs/ui/KisImageBarrierLockerWithFeedback.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017 Dmitry Kazakov + * + * 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 KISIMAGEBARRIERLOCKERWITHFEEDBACK_H +#define KISIMAGEBARRIERLOCKERWITHFEEDBACK_H + +#include "kis_types.h" +#include "kis_image_barrier_locker.h" + +namespace KisImageBarrierLockerWithFeedbackImplPrivate { +void blockWithFeedback(KisImageSP image); +} + +template +class KisImageBarrierLockerWithFeedbackImpl +{ +public: + KisImageBarrierLockerWithFeedbackImpl(KisImageSP image) { + KisImageBarrierLockerWithFeedbackImplPrivate::blockWithFeedback(image); + m_locker.reset(new InternalLocker(image)); + } + + ~KisImageBarrierLockerWithFeedbackImpl() { + } + +private: + QScopedPointer m_locker; +}; + +typedef KisImageBarrierLockerWithFeedbackImpl KisImageBarrierLockerWithFeedback; +typedef KisImageBarrierLockerWithFeedbackImpl KisImageBarrierLockerWithFeedbackAllowNull; + + +#endif // KISIMAGEBARRIERLOCKERWITHFEEDBACK_H diff --git a/libs/ui/kis_mimedata.cpp b/libs/ui/kis_mimedata.cpp index b26f6e968b..13f5629478 100644 --- a/libs/ui/kis_mimedata.cpp +++ b/libs/ui/kis_mimedata.cpp @@ -1,443 +1,443 @@ /* * Copyright (c) 2011 Boudewijn Rempt * * 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 library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kis_mimedata.h" #include "kis_config.h" #include "kis_node.h" #include "kis_paint_device.h" #include "kis_shared_ptr.h" #include "kis_image.h" #include "kis_layer.h" #include "kis_shape_layer.h" #include "kis_paint_layer.h" #include "KisDocument.h" #include "kis_shape_controller.h" #include "KisPart.h" #include "kis_layer_utils.h" #include "kis_node_insertion_adapter.h" #include "kis_dummies_facade_base.h" #include "kis_node_dummies_graph.h" #include "KisImportExportManager.h" -#include "kis_image_barrier_locker.h" +#include "KisImageBarrierLockerWithFeedback.h" #include #include #include #include #include #include #include #include #include #include #include #include #include KisMimeData::KisMimeData(QList nodes, KisImageSP image, bool forceCopy) : QMimeData() , m_nodes(nodes) , m_forceCopy(forceCopy) , m_image(image) { Q_ASSERT(m_nodes.size() > 0); } void KisMimeData::deepCopyNodes() { KisNodeList newNodes; { - KisImageBarrierLockerAllowNull locker(m_image); + KisImageBarrierLockerWithFeedbackAllowNull locker(m_image); Q_FOREACH (KisNodeSP node, m_nodes) { newNodes << node->clone(); } } m_nodes = newNodes; m_image = 0; } QList KisMimeData::nodes() const { return m_nodes; } QStringList KisMimeData::formats () const { QStringList f = QMimeData::formats(); if (m_nodes.size() > 0) { f << "application/x-krita-node" << "application/x-krita-node-url" << "application/x-qt-image" << "application/zip" << "application/x-krita-node-internal-pointer"; } return f; } KisDocument *createDocument(QList nodes, KisImageSP srcImage) { KisDocument *doc = KisPart::instance()->createDocument(); QRect rc; Q_FOREACH (KisNodeSP node, nodes) { rc |= node->exactBounds(); } KisImageSP image = new KisImage(0, rc.width(), rc.height(), nodes.first()->colorSpace(), nodes.first()->name()); { - KisImageBarrierLockerAllowNull locker(srcImage); + KisImageBarrierLockerWithFeedbackAllowNull locker(srcImage); Q_FOREACH (KisNodeSP node, nodes) { image->addNode(node->clone()); } } doc->setCurrentImage(image); return doc; } QByteArray serializeToByteArray(QList nodes, KisImageSP srcImage) { QScopedPointer doc(createDocument(nodes, srcImage)); return doc->serializeToNativeByteArray(); } QVariant KisMimeData::retrieveData(const QString &mimetype, QVariant::Type preferredType) const { Q_ASSERT(m_nodes.size() > 0); if (mimetype == "application/x-qt-image") { KisConfig cfg; KisDocument *doc = createDocument(m_nodes, m_image); return doc->image()->projection()->convertToQImage(cfg.displayProfile(QApplication::desktop()->screenNumber(qApp->activeWindow())), KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()); } else if (mimetype == "application/x-krita-node" || mimetype == "application/zip") { QByteArray ba = serializeToByteArray(m_nodes, m_image); return ba; } else if (mimetype == "application/x-krita-node-url") { QByteArray ba = serializeToByteArray(m_nodes, m_image); QString temporaryPath = QDir::tempPath() + QDir::separator() + QString("krita_tmp_dnd_layer_%1_%2.kra") .arg(QApplication::applicationPid()) .arg(qrand()); QFile file(temporaryPath); file.open(QFile::WriteOnly); file.write(ba); file.flush(); file.close(); return QUrl::fromLocalFile(temporaryPath).toEncoded(); } else if (mimetype == "application/x-krita-node-internal-pointer") { QDomDocument doc("krita_internal_node_pointer"); QDomElement root = doc.createElement("pointer"); root.setAttribute("application_pid", (qint64)QApplication::applicationPid()); root.setAttribute("force_copy", m_forceCopy); root.setAttribute("image_pointer_value", (qint64)m_image.data()); doc.appendChild(root); Q_FOREACH (KisNodeSP node, m_nodes) { QDomElement element = doc.createElement("node"); element.setAttribute("pointer_value", (qint64)node.data()); root.appendChild(element); } return doc.toByteArray(); } else { return QMimeData::retrieveData(mimetype, preferredType); } } void KisMimeData::initializeExternalNode(KisNodeSP *node, KisImageWSP image, KisShapeController *shapeController) { // layers store a link to the image, so update it KisLayer *layer = qobject_cast(node->data()); if (layer) { layer->setImage(image); } KisShapeLayer *shapeLayer = dynamic_cast(node->data()); if (shapeLayer) { // attach the layer to a new shape controller KisShapeLayer *shapeLayer2 = new KisShapeLayer(*shapeLayer, shapeController); *node = shapeLayer2; } } QList KisMimeData::tryLoadInternalNodes(const QMimeData *data, KisImageSP image, KisShapeController *shapeController, bool /* IN-OUT */ ©Node) { QList nodes; bool forceCopy = false; KisImageSP sourceImage; // Qt 4.7 and Qt 5.5 way const KisMimeData *mimedata = qobject_cast(data); if (mimedata) { nodes = mimedata->nodes(); forceCopy = mimedata->m_forceCopy; sourceImage = mimedata->m_image; } // Qt 4.8 way if (nodes.isEmpty() && data->hasFormat("application/x-krita-node-internal-pointer")) { QByteArray nodeXml = data->data("application/x-krita-node-internal-pointer"); QDomDocument doc; doc.setContent(nodeXml); QDomElement element = doc.documentElement(); qint64 pid = element.attribute("application_pid").toLongLong(); forceCopy = element.attribute("force_copy").toInt(); qint64 imagePointerValue = element.attribute("image_pointer_value").toLongLong(); sourceImage = reinterpret_cast(imagePointerValue); if (pid == QApplication::applicationPid()) { QDomNode n = element.firstChild(); while (!n.isNull()) { QDomElement e = n.toElement(); if (!e.isNull()) { qint64 pointerValue = e.attribute("pointer_value").toLongLong(); if (pointerValue) { nodes << reinterpret_cast(pointerValue); } } n = n.nextSibling(); } } } if (!nodes.isEmpty() && (forceCopy || copyNode || sourceImage != image)) { - KisImageBarrierLockerAllowNull locker(sourceImage); + KisImageBarrierLockerWithFeedbackAllowNull locker(sourceImage); QList clones; Q_FOREACH (KisNodeSP node, nodes) { node = node->clone(); if ((forceCopy || copyNode) && sourceImage == image) { KisLayerUtils::addCopyOfNameTag(node); } initializeExternalNode(&node, image, shapeController); clones << node; } nodes = clones; copyNode = true; } return nodes; } QList KisMimeData::loadNodes(const QMimeData *data, const QRect &imageBounds, const QPoint &preferredCenter, bool forceRecenter, KisImageWSP image, KisShapeController *shapeController) { bool alwaysRecenter = false; QList nodes; if (data->hasFormat("application/x-krita-node")) { KisDocument *tempDoc = KisPart::instance()->createDocument(); QByteArray ba = data->data("application/x-krita-node"); QBuffer buf(&ba); KisImportExportFilter *filter = tempDoc->importExportManager()->filterForMimeType(tempDoc->nativeFormatMimeType(), KisImportExportManager::Import); filter->setBatchMode(true); bool result = (filter->convert(tempDoc, &buf) == KisImportExportFilter::OK); if (result) { KisImageWSP tempImage = tempDoc->image(); Q_FOREACH (KisNodeSP node, tempImage->root()->childNodes(QStringList(), KoProperties())) { tempImage->removeNode(node); initializeExternalNode(&node, image, shapeController); nodes << node; } } delete filter; delete tempDoc; } if (nodes.isEmpty() && data->hasFormat("application/x-krita-node-url")) { QByteArray ba = data->data("application/x-krita-node-url"); KisDocument *tempDoc = KisPart::instance()->createDocument(); Q_ASSERT(QUrl::fromEncoded(ba).isLocalFile()); bool result = tempDoc->openUrl(QUrl::fromEncoded(ba)); if (result) { KisImageWSP tempImage = tempDoc->image(); Q_FOREACH (KisNodeSP node, tempImage->root()->childNodes(QStringList(), KoProperties())) { tempImage->removeNode(node); initializeExternalNode(&node, image, shapeController); nodes << node; } } delete tempDoc; QFile::remove(QUrl::fromEncoded(ba).toLocalFile()); } if (nodes.isEmpty() && data->hasImage()) { QImage qimage = qvariant_cast(data->imageData()); KisPaintDeviceSP device = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8()); device->convertFromQImage(qimage, 0); nodes << new KisPaintLayer(image.data(), image->nextLayerName(), OPACITY_OPAQUE_U8, device); alwaysRecenter = true; } if (!nodes.isEmpty()) { Q_FOREACH (KisNodeSP node, nodes) { QRect bounds = node->projection()->exactBounds(); if (alwaysRecenter || forceRecenter || (!imageBounds.contains(bounds) && !imageBounds.intersects(bounds))) { QPoint pt = preferredCenter - bounds.center(); node->setX(pt.x()); node->setY(pt.y()); } } } return nodes; } QMimeData* KisMimeData::mimeForLayers(const KisNodeList &nodes, KisImageSP image, bool forceCopy) { KisNodeList inputNodes = nodes; KisNodeList sortedNodes; KisLayerUtils::sortMergableNodes(image->root(), inputNodes, sortedNodes); if (sortedNodes.isEmpty()) return 0; KisMimeData* data = new KisMimeData(sortedNodes, image, forceCopy); return data; } QMimeData* KisMimeData::mimeForLayersDeepCopy(const KisNodeList &nodes, KisImageSP image, bool forceCopy) { KisNodeList inputNodes = nodes; KisNodeList sortedNodes; KisLayerUtils::sortMergableNodes(image->root(), inputNodes, sortedNodes); if (sortedNodes.isEmpty()) return 0; KisMimeData* data = new KisMimeData(sortedNodes, image, forceCopy); data->deepCopyNodes(); return data; } bool nodeAllowsAsChild(KisNodeSP parent, KisNodeList nodes) { bool result = true; Q_FOREACH (KisNodeSP node, nodes) { if (!parent->allowAsChild(node)) { result = false; break; } } return result; } bool correctNewNodeLocation(KisNodeList nodes, KisNodeDummy* &parentDummy, KisNodeDummy* &aboveThisDummy) { KisNodeSP parentNode = parentDummy->node(); bool result = true; if(!nodeAllowsAsChild(parentDummy->node(), nodes)) { aboveThisDummy = parentDummy; parentDummy = parentDummy->parent(); result = (!parentDummy) ? false : correctNewNodeLocation(nodes, parentDummy, aboveThisDummy); } return result; } bool KisMimeData::insertMimeLayers(const QMimeData *data, KisImageSP image, KisShapeController *shapeController, KisNodeDummy *parentDummy, KisNodeDummy *aboveThisDummy, bool copyNode, KisNodeInsertionAdapter *nodeInsertionAdapter) { QList nodes = KisMimeData::tryLoadInternalNodes(data, image, shapeController, copyNode /* IN-OUT */); if (nodes.isEmpty()) { QRect imageBounds = image->bounds(); nodes = KisMimeData::loadNodes(data, imageBounds, imageBounds.center(), false, image, shapeController); /** * Don't try to move a node originating from another image, * just copy it. */ copyNode = true; } if (nodes.isEmpty()) return false; bool result = true; if (!correctNewNodeLocation(nodes, parentDummy, aboveThisDummy)) { return false; } KIS_ASSERT_RECOVER(nodeInsertionAdapter) { return false; } Q_ASSERT(parentDummy); KisNodeSP aboveThisNode = aboveThisDummy ? aboveThisDummy->node() : 0; if (copyNode) { nodeInsertionAdapter->addNodes(nodes, parentDummy->node(), aboveThisNode); } else { Q_ASSERT(nodes.first()->graphListener() == image.data()); nodeInsertionAdapter->moveNodes(nodes, parentDummy->node(), aboveThisNode); } return result; }