clipboard.cpp revision 1a47b2cac3a626601cae7f54072e4428312d913d
475N/A * @brief System-wide clipboard management - implementation 943N/A * Krzysztof KosiĆski <tweenk@o2.pl> 919N/A * Copyright (C) 2008 authors 919N/A * This program is free software; you can redistribute it and/or 919N/A * modify it under the terms of the GNU General Public License 919N/A * as published by the Free Software Foundation; either version 2 919N/A * of the License, or (at your option) any later version. 919N/A * See the file COPYING for details. 919N/A// TODO: reduce header bloat if possible #
include "svg/svg.h" // for sp_svg_transform_write, used in _copySelection#
include "file.h" // for file_import, used in _pasteImage#
include "prefs-utils.h" // for prefs_get_string_attribute, used in _pasteImage/// @brief Made up mimetype to represent Gdk::Pixbuf clipboard contents * @brief Default implementation of the clipboard manager // push supported clipboard targets, in order of preference * @brief Copy selection contents to the clipboard // Special case for when the gradient dragger is active - copies gradient color // Special case for when the color picker ("dropper") is active - copies color under cursor // Special case for when the text tool is active - if some text is selected, copy plain text, // not the object that holds it * @brief Copy a Live Path Effect path parameter to the clipboard * @param pp The path parameter to store in the clipboard * @brief Paste from the system clipboard into the active desktop * @param in_place Whether to put the contents where they were when copied // do any checking whether we really are able to paste before requesting the contents // Special cases of clipboard content handling go here 00ff00 // Note that target priority is determined in _getBestTarget. // if there is an image on the clipboard, paste it // if there's only text, paste it into a selected text object or create a new one // otherwise, use the import extensions * @brief Returns the id of the first visible copied object * @brief Implements the Paste Style action // check whether something is selected * @brief Resize the selection or each object in the selection to match the clipboard's size * @param separately Whether to scale each object in the selection separately * @param apply_x Whether to scale the width of objects / selection * @param apply_y Whether to scale the height of objects / selection // FIXME: actually, this should accept arbitrary documents // retrieve size ifomration from the clipboard // resize each object in the selection // resize the selection as a whole * @brief Applies a path effect from the clipboard to the selected path /** @todo FIXME: pastePathEffect crashes when moving the path with the applied effect, segfaulting in fork_private_if_necessary(). */ // make sure all selected items are converted to paths first (i.e. rectangles) * @brief Get LPE path data from the clipboard * @return The retrieved path data (contents of the d attribute), or "" if no path was found * @brief Get object id of a shape or text item from the clipboard * @return The retrieved id string (contents of the id attribute), or "" if no shape or text item was found * @brief Iterate over a list of items and copy them to the clipboard. // copy the defs used by all items // copy the representation of the items // copy complete inherited style // write the complete accumulated transform passed to us // (we're dealing with unattached representations, so we write to their attributes // instead of using sp_item_set_transform) // copy style for Paste Style action // copy path effect from the first path * @brief Recursively copy all the definitions used by a given item to the clipboard defs // copy fill and stroke styles (patterns and gradients) // For shapes, copy all of the shape's markers // For lpe items, copy lpe stack if applicable // For 3D boxes, copy perspectives // recurse into the mask for its gradients etc. * @brief Copy a single gradient to the clipboard's defs element // climb up the refs, copying each one in the chain * @brief Copy a single pattern to the clipboard document's defs element // climb up the references, copying each one in the chain // items in the pattern may also use gradients and other patterns, so recurse * @brief Copy a text path to the clipboard's defs element // Do not copy the text path to defs if it's already copied * @brief Copy a single XML node from one document to another * @param node The node to be copied * @param target_doc The document to which the node is to be copied * @param parent The node in the target document which will become the parent of the copied node * @return Pointer to the copied node * @brief Paste the contents of a document into the active desktop * @param clipdoc The document to paste * @param in_place Whether to paste the selection where it was when copied * @pre @c clipdoc is not empty and items can be added to the current layer // Don't copy metadata, defs, named views and internal clipboard contents to the document // move the selection to the right position // this formula was discovered empyrically * @brief Paste SVG defs from the document retrieved from the clipboard into the active document * @param clipdoc The document to paste * @pre @c clipdoc != NULL and pasting into the active document is possible // boilerplate vars copied from _pasteDocument /// @todo TODO: implement def id collision resolution in ClipboardManagerImpl::_pasteDefs() // simplistic solution: when a collision occurs, add "a" to id until it's unique Glib::ustring pasted_id = def->attribute("id"); if ( pasted_id.empty() ) continue; // defs without id are useless Glib::ustring pasted_id_original = pasted_id; while(sp_repr_lookup_child(target_defs, "id", pasted_id.data())) { if ( pasted_id != pasted_id_original ) { def->setAttribute("id", pasted_id.data()); // Update the id in the rest of the document so there are no dangling references _changeIdReferences(clipdoc, pasted_id_original, pasted_id); continue;
// skip duplicate defs - temporary non-solution * @brief Retrieve a bitmap image from the clipboard and paste it into the active document // Very stupid hack: Write into a file, then import the file into the document. // To avoid using tmpfile and POSIX file handles, make the filename based on current time. // and just can't think of something saner at the moment. Pasting more than // one image per second will overwrite the image. // However, I don't think anyone is able to copy a _different_ image into inkscape * @brief Paste text into the selected text object or create a new one to hold it // if the text editing tool is active, paste the text into the active text object // try to parse the text as a color and, if successful, apply it as the current style * @brief Attempt to parse the passed string as a hexadecimal RGB or RGBA color * @param text The Glib::ustring to parse * @return New CSS style representation if the parsing was successful, NULL otherwise if ( !
str || ( *
str ==
'\0' ) )
return NULL;
// this is OK due to boolean short-circuit // those conditionals guard against parsing e.g. the string "fab" as "fab000" // (incomplete color) and "45fab71" as "45fab710" (incomplete alpha) // skip a leading #, if present // try to parse first 6 digits if (
attempt_alpha) {
// try to parse alpha if there's enough characters // print and set properties * @brief Applies a pasted path effect to a given item // if the effect is not used by anyone, we might as well take it * @brief Retrieve the clipboard contents as a document * @return Clipboard contents converted to SPDocument, or NULL if no suitable content was present // doing this synchronously makes better sense // TODO: use another method because this one is badly broken imo. // from documentation: "Returns: A SelectionData object, which will be invalid if retrieving the given target failed." // I don't know how to check whether an object is 'valid' or not, unusable if that's not possible... // there is no specific plain SVG input extension, so if we can paste the Inkscape SVG format, // we use the image/svg+xml mimetype to look up the input extension return NULL;
// this shouldn't happen unless _getBestTarget returns something bogus // FIXME: Temporary hack until we add memory input. // Save the clipboard contents to some file, then read it * @brief Callback called when some other application requests data from Inkscape * Finds a suitable output extension to save the internal clipboard document, * then saves it to memory and sets the clipboard contents. if(
target ==
"")
return;
// this shouldn't happen if (
out ==
outlist.
end() )
return;
// this also shouldn't happen // FIXME: Temporary hack until we add support for memory output. // Save to a temporary file, read it back and then set the clipboard contents * @brief Callback when someone else takes the clipboard * When the clipboard owner changes, this callback clears the internal clipboard document * to reduce memory usage. // why is this called before _onGet??? //_discardInternalClipboard(); * @brief Creates an internal clipboard document from scratch //g_assert( _clipboardSPDoc != NULL ); * @brief Deletes the internal clipboard document * @brief Get the scale to resize an item, based on the command and desktop state // If the "lock aspect ratio" button is pressed and we paste only a single coordinate, // resize the second one by the same ratio too * @brief Find the most suitable clipboard target // clipboard target debugging snippet g_debug("Begin clipboard targets"); for ( std::list<Glib::ustring>::iterator x = targets.begin() ; x != targets.end(); ++x ) g_debug("Clipboard target: %s", (*x).data()); g_debug("End clipboard targets\n"); * @brief Set the clipboard targets to reflect the mimetypes Inkscape can output * @brief Set the string representation of a 32-bit RGBA color as the clipboard contents * @brief Put a notification on the mesage stack /* ####################################### ####################################### */ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :