summaryrefslogtreecommitdiffstats
path: root/src/object/uri-references.h
blob: 2b891637c036b0e4538d908c8e17cc162dd86514 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef SEEN_SP_URI_REFERENCES_H
#define SEEN_SP_URI_REFERENCES_H

/*
 * Helper methods for resolving URI References
 *
 * Authors:
 *   Lauris Kaplinski <lauris@kaplinski.com>
 *   Abhishek Sharma
 *
 * Copyright (C) 2001-2002 Lauris Kaplinski
 * Copyright (C) 2001 Ximian, Inc.
 *
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */

#include <cstddef>
#include <vector>
#include <set>
#include <sigc++/connection.h>
#include <sigc++/trackable.h>

class SPObject;
class SPDocument;

namespace Inkscape {

class URI;

/**
 * A class encapsulating a reference to a particular URI; observers can
 * be notified when the URI comes to reference a different SPObject.
 *
 * The URIReference increments and decrements the SPObject's hrefcount
 * automatically.
 *
 * @see SPObject
 */
class URIReference : public sigc::trackable {
public:
    /**
     * Constructor.
     *
     * @param owner The object on whose behalf this URIReference
     *              is holding a reference to the target object.
     */
    URIReference(SPObject *owner);
    URIReference(SPDocument *owner_document);

    /* Definition-less to prevent accidental use. */
    void operator=(URIReference const& ref) = delete;

    /**
     * Destructor.  Calls shutdown() if the reference has not been
     * shut down yet.
     */
    virtual ~URIReference();

    /**
     * Attaches to a URI, relative to the specified document.
     *
     * Throws a BadURIException if the URI is unsupported,
     * or the fragment identifier is xpointer and malformed.
     *
     * @param uri the URI to watch
     */
    void attach(URI const& uri);

    /**
     * Try to attach to a URI. Return false if URL is malformed and detach any
     * previous attachment.
     */
    bool try_attach(char const *uri);

    /**
     * Detaches from the currently attached URI target, if any;
     * the current referrent is signaled as NULL.
     */
    void detach();

    /**
     * @brief Returns a pointer to the current referrent of the
     * attached URI, or NULL.
     *
     * @return a pointer to the referenced SPObject or NULL
     */
    SPObject *getObject() const { return _obj; }

    /**
     * @brief Returns a pointer to the URIReference's owner
     *
     * @return a pointer to the URIReference's owner
     */
    SPObject *getOwner() const { return _owner; }

    /**
     * Accessor for the referrent change notification signal;
     * this signal is emitted whenever the URIReference's
     * referrent changes.
     *
     * Signal handlers take two parameters: the old and new
     * referrents.
     *
     * @returns a signal
     */
    sigc::signal<void, SPObject *, SPObject *> changedSignal() {
        return _changed_signal;
    }

    /**
     * Returns a pointer to a URI containing the currently attached
     * URI, or NULL if no URI is currently attached.
     *
     * @returns the currently attached URI, or NULL
     */
    URI const* getURI() const {
        return _uri;
    }

    /**
     * Returns true if there is currently an attached URI
     *
     * @returns true if there is an attached URI
     */
    bool isAttached() const {
        return (bool)_uri;
    }

    SPDocument *getOwnerDocument() { return _owner_document; }
    SPObject   *getOwnerObject()   { return _owner; }

protected:
    virtual bool _acceptObject(SPObject *obj) const;
private:
    SPObject *_owner;
    SPDocument *_owner_document;
    sigc::connection _connection;
    sigc::connection _release_connection;
    SPObject *_obj;
    URI *_uri;

    sigc::signal<void, SPObject *, SPObject *> _changed_signal;

    void _setObject(SPObject *object);
    void _release(SPObject *object);
};

}

/**
 * Resolves an item referenced by a URI in CSS form contained in "url(...)"
 */
SPObject* sp_css_uri_reference_resolve( SPDocument *document, const char *uri );

SPObject *sp_uri_reference_resolve (SPDocument *document, const char *uri);

#endif // SEEN_SP_URI_REFERENCES_H

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :