090cb42ca665297ca2d63c9856b126e95a6570b5
1 /** \file
2 *
3 * Document metadata dialog, Gtkmm-style
4 *
5 * Authors:
6 * bulia byak <buliabyak@users.sf.net>
7 * Bryce W. Harrington <bryce@bryceharrington.org>
8 * Lauris Kaplinski <lauris@kaplinski.com>
9 * Jon Phillips <jon@rejon.org>
10 * Ralf Stephan <ralf@ark.in-berlin.de> (Gtkmm)
11 *
12 * Copyright (C) 2000 - 2006 Authors
13 *
14 * Released under GNU GPL. Read the file 'COPYING' for more information
15 */
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
23 #include "ui/widget/entity-entry.h"
25 #include "xml/node-event-vector.h"
26 #include "dialogs/rdf.h"
28 #include "inkscape.h"
29 #include "verbs.h"
30 #include "desktop-handles.h"
31 #include "desktop.h"
32 #include "sp-namedview.h"
34 #include "document-metadata.h"
36 //using std::pair;
38 namespace Inkscape {
39 namespace UI {
40 namespace Dialog {
42 #define SPACE_SIZE_X 15
43 #define SPACE_SIZE_Y 15
45 //===================================================
47 //---------------------------------------------------
49 static DocumentMetadata *_instance = 0;
51 static void on_repr_attr_changed (Inkscape::XML::Node *, gchar const *, gchar const *, gchar const *, bool, gpointer);
52 static void on_doc_replaced (SPDesktop* dt, SPDocument* doc);
53 static void on_activate_desktop (Inkscape::Application *, SPDesktop* dt, void*);
54 static void on_deactivate_desktop (Inkscape::Application *, SPDesktop* dt, void*);
56 static Inkscape::XML::NodeEventVector const _repr_events = {
57 NULL, /* child_added */
58 NULL, /* child_removed */
59 on_repr_attr_changed,
60 NULL, /* content_changed */
61 NULL /* order_changed */
62 };
65 DocumentMetadata*
66 DocumentMetadata::create()
67 {
68 if (_instance) return _instance;
69 _instance = new DocumentMetadata;
70 _instance->init();
71 return _instance;
72 }
74 void
75 DocumentMetadata::destroy()
76 {
77 if (_instance)
78 {
79 delete _instance;
80 _instance = 0;
81 }
82 }
84 DocumentMetadata::DocumentMetadata()
85 : Dialog ("dialogs.documentmetadata", SP_VERB_DIALOG_METADATA),
86 _page_metadata1(1, 1), _page_metadata2(1, 1),
87 _prefs_path("dialogs.documentmetadata")
88 {
89 hide();
90 set_resizable (false);
91 _tt.enable();
92 get_vbox()->set_spacing (4);
93 get_vbox()->pack_start (_notebook, true, true);
95 _notebook.append_page(_page_metadata1, _("Metadata"));
96 _notebook.append_page(_page_metadata2, _("License"));
98 build_metadata();
99 }
101 void
102 DocumentMetadata::init()
103 {
104 update();
106 Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
107 repr->addListener (&_repr_events, this);
109 _doc_replaced_connection = SP_ACTIVE_DESKTOP->connectDocumentReplaced (sigc::ptr_fun (on_doc_replaced));
111 g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop",
112 G_CALLBACK(on_activate_desktop), 0);
114 g_signal_connect(G_OBJECT(INKSCAPE), "deactivate_desktop",
115 G_CALLBACK(on_deactivate_desktop), 0);
117 show_all_children();
118 present();
119 }
121 DocumentMetadata::~DocumentMetadata()
122 {
123 Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
124 repr->removeListenerByData (this);
125 _doc_replaced_connection.disconnect();
127 for (RDElist::iterator it = _rdflist.begin(); it != _rdflist.end(); it++)
128 delete (*it);
129 }
131 //========================================================================
133 /**
134 * Helper function that attachs widgets in a 3xn table. The widgets come in an
135 * array that has two entries per table row. The two entries code for four
136 * possible cases: (0,0) means insert space in first column; (0, non-0) means
137 * widget in columns 2-3; (non-0, 0) means label in columns 1-3; and
138 * (non-0, non-0) means two widgets in columns 2 and 3.
139 **/
140 inline void
141 attach_all (Gtk::Table &table, const Gtk::Widget *arr[], unsigned size, int start = 0)
142 {
143 for (unsigned i=0, r=start; i<size/sizeof(Gtk::Widget*); i+=2)
144 {
145 if (arr[i] && arr[i+1])
146 {
147 table.attach (const_cast<Gtk::Widget&>(*arr[i]), 1, 2, r, r+1,
148 Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
149 table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 2, 3, r, r+1,
150 Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
151 }
152 else
153 {
154 if (arr[i+1])
155 table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 1, 3, r, r+1,
156 Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
157 else if (arr[i])
158 {
159 Gtk::Label& label = reinterpret_cast<Gtk::Label&> (const_cast<Gtk::Widget&>(*arr[i]));
160 label.set_alignment (0.0);
161 table.attach (label, 0, 3, r, r+1,
162 Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
163 }
164 else
165 {
166 Gtk::HBox *space = manage (new Gtk::HBox);
167 space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
168 table.attach (*space, 0, 1, r, r+1,
169 (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0);
170 }
171 }
172 ++r;
173 }
174 }
176 void
177 DocumentMetadata::build_metadata()
178 {
179 _page_metadata1.show();
181 Gtk::Label *label = manage (new Gtk::Label);
182 label->set_markup (_("<b>Dublin Core Entities</b>"));
183 label->set_alignment (0.0);
184 _page_metadata1.table().attach (*label, 0,3,0,1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
185 /* add generic metadata entry areas */
186 struct rdf_work_entity_t * entity;
187 int row = 1;
188 for (entity = rdf_work_entities; entity && entity->name; entity++, row++) {
189 if ( entity->editable == RDF_EDIT_GENERIC ) {
190 EntityEntry *w = EntityEntry::create (entity, _tt, _wr);
191 _rdflist.push_back (w);
192 Gtk::HBox *space = manage (new Gtk::HBox);
193 space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
194 _page_metadata1.table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
195 _page_metadata1.table().attach (w->_label, 1,2, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
196 _page_metadata1.table().attach (*w->_packable, 2,3, row, row+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
197 }
198 }
200 _page_metadata2.show();
202 row = 0;
203 Gtk::Label *llabel = manage (new Gtk::Label);
204 llabel->set_markup (_("<b>License</b>"));
205 llabel->set_alignment (0.0);
206 _page_metadata2.table().attach (*llabel, 0,3, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
207 /* add license selector pull-down and URI */
208 ++row;
209 _licensor.init (_tt, _wr);
210 Gtk::HBox *space = manage (new Gtk::HBox);
211 space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
212 _page_metadata2.table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
213 _page_metadata2.table().attach (_licensor, 1,3, row, row+1, Gtk::EXPAND|Gtk::FILL, (Gtk::AttachOptions)0,0,0);
214 }
216 /**
217 * Update dialog widgets from desktop.
218 */
219 void
220 DocumentMetadata::update()
221 {
222 if (_wr.isUpdating()) return;
224 _wr.setUpdating (true);
225 set_sensitive (true);
227 //-----------------------------------------------------------meta pages
228 /* update the RDF entities */
229 for (RDElist::iterator it = _rdflist.begin(); it != _rdflist.end(); it++)
230 (*it)->update (SP_ACTIVE_DOCUMENT);
232 _licensor.update (SP_ACTIVE_DOCUMENT);
234 _wr.setUpdating (false);
235 }
237 //--------------------------------------------------------------------
239 void
240 DocumentMetadata::on_response (int id)
241 {
242 if (id == Gtk::RESPONSE_CLOSE)
243 hide();
244 }
246 /**
247 * Called when XML node attribute changed; updates dialog widgets.
248 */
249 static void
250 on_repr_attr_changed (Inkscape::XML::Node *, gchar const *, gchar const *, gchar const *, bool, gpointer)
251 {
252 if (!_instance)
253 return;
255 _instance->update();
256 }
258 static void
259 on_activate_desktop (Inkscape::Application *, SPDesktop* dt, void*)
260 {
261 if (!_instance)
262 return;
264 Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
265 repr->addListener (&_repr_events, _instance);
266 _instance->_doc_replaced_connection = SP_ACTIVE_DESKTOP->connectDocumentReplaced (sigc::ptr_fun (on_doc_replaced));
267 _instance->update();
268 }
270 static void
271 on_deactivate_desktop (Inkscape::Application *, SPDesktop* dt, void*)
272 {
273 if (!_instance)
274 return;
276 Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
277 repr->removeListenerByData (_instance);
278 _instance->_doc_replaced_connection.disconnect();
279 }
281 static void
282 on_doc_replaced (SPDesktop* dt, SPDocument* doc)
283 {
284 if (!_instance)
285 return;
287 Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(dt));
288 repr->addListener (&_repr_events, _instance);
289 _instance->update();
290 }
293 } // namespace Dialog
294 } // namespace UI
295 } // namespace Inkscape
297 /*
298 Local Variables:
299 mode:c++
300 c-file-style:"stroustrup"
301 c-file-offsets:((innamespace . 0)(inline-open . 0))
302 indent-tabs-mode:nil
303 fill-column:99
304 End:
305 */
306 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :