Code

moving trunk for module inkscape
[inkscape.git] / src / ui / view / edit-widget.cpp
1 /**
2  * \brief This class implements the functionality of the window layout, menus,
3  *        and signals.
4  * 
5  * This is a reimplementation into C++/Gtkmm of Sodipodi's SPDesktopWidget class.
6  * Both SPDesktopWidget and EditWidget adhere to the EditWidgetInterface, so
7  * they both can serve as widget for the same SPDesktop/Edit class.
8  *
9  * Ideally, this class should only contain the handling of the Window (i.e.,
10  * content construction and window signals) and implement its 
11  * EditWidgetInterface.
12  *
13  * Authors:
14  *   Ralf Stephan <ralf@ark.in-berlin.de>
15  *   Bryce W. Harrington <bryce@bryceharrington.org>
16  *   Derek P. Moore <derekm@hackunix.org>
17  *   Lauris Kaplinski <lauris@kaplinski.com>
18  *   Frank Felfe <innerspace@iname.com>
19  *
20  * Copyright (C) 1999-2005 Authors
21  * Copyright (C) 2000-2001 Ximian, Inc.
22  *
23  * Released under GNU GPL.  Read the file 'COPYING' for more information.
24  */
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
30 #include <gtk/gtkwindow.h>
31 #include <gtkmm/radioaction.h>
32 #include <gtkmm/menubar.h>
33 #include <gtkmm/messagedialog.h>
34 #include <gtkmm/stock.h>
35 #include <gtkmm/accelmap.h>
36 #include <gtkmm/separator.h>
38 #include "macros.h"
39 #include "path-prefix.h"
40 #include "prefs-utils.h"
41 #include "file.h"
42 #include "application/editor.h"
43 #include "edit-widget.h"
44 #include "ui/stock.h"
45 #include "ui/stock-items.h"
46 #include "ui/icons.h"
48 #include "display/sodipodi-ctrlrect.h"
49 #include "helper/units.h"
50 #include "shortcuts.h"
51 #include "widgets/spw-utilities.h"
52 #include "event-context.h"
53 #include "document.h"
54 #include "sp-namedview.h"
55 #include "sp-item.h"
56 #include "interface.h"
57 #include "extension/db.h"
59 #ifdef WITH_INKBOARD
60 #include "ui/dialog/whiteboard-connect.h"
61 #include "ui/dialog/whiteboard-sharewithuser.h"
62 #include "ui/dialog/whiteboard-sharewithchat.h"
63 #endif
65 using namespace Inkscape::UI;
66 using namespace Inkscape::UI::Widget;
68 namespace Inkscape {
69 namespace UI {
70 namespace View {
72 EditWidget::EditWidget (SPDocument *doc)
73     : _main_window_table(4),
74       _viewport_table(3,3),
75       _act_grp(Gtk::ActionGroup::create()),
76       _ui_mgr(Gtk::UIManager::create()),
77       _update_s_f(false),
78       _update_a_f(false)
79 {
80     g_warning("Creating new EditWidget");
82     _desktop = 0;
83     Icons::init();
84     Stock::init();
85     initActions();
86     initAccelMap();
87     initUIManager();
88     initLayout();
89     initEdit (doc);
90     g_warning("Done creating new EditWidget");
91 }
93 EditWidget::~EditWidget()
94 {
95     destroyEdit();
96 }
98 void
99 EditWidget::initActions()
101     initMenuActions();
102     initToolbarActions();
105 void
106 EditWidget::initUIManager()
108     _ui_mgr->insert_action_group(_act_grp);
109     add_accel_group(_ui_mgr->get_accel_group());
111     gchar *filename_utf8 = g_build_filename(INKSCAPE_UIDIR, "menus-bars.xml", NULL);
112     if (_ui_mgr->add_ui_from_file(filename_utf8) == 0) {
113         g_warning("Error merging ui from file '%s'", filename_utf8);
114         // fixme-charset: What charset should we pass to g_warning?
115     }
116     g_free(filename_utf8);
119 void
120 EditWidget::initLayout()
122     set_title("New document 1 - Inkscape");
123     set_resizable();
124     set_default_size(640, 480);
126     // top level window into which all other portions of the UI get inserted
127     add(_main_window_table);
128     // attach box for horizontal toolbars
129     _main_window_table.attach(_toolbars_vbox, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
130     // attach sub-window for viewport and vertical toolbars
131     _main_window_table.attach(_sub_window_hbox, 0, 1, 2, 3);
132     // viewport table with 3 rows by 3 columns
133     _sub_window_hbox.pack_end(_viewport_table);
135     // Menus and Bars
136     initMenuBar();
137     initCommandsBar();
138     initToolControlsBar();
139     initUriBar();
140     initToolsBar();
142     // Canvas Viewport
143     initLeftRuler();
144     initTopRuler();
145     initStickyZoom();
146     initBottomScrollbar();
147     initRightScrollbar();
148     _viewport_table.attach(_svg_canvas.widget(), 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
149     _svg_canvas.widget().show_all();
152     // The statusbar comes last and appears at the bottom of _main_window_table
153     initStatusbar();
155     signal_size_allocate().connect (sigc::mem_fun (*this, &EditWidget::onWindowSizeAllocate), false);
156     signal_realize().connect (sigc::mem_fun (*this, &EditWidget::onWindowRealize));
157     show_all_children();
160 void
161 EditWidget::onMenuItem()
163     g_warning("onMenuItem called");
166 void
167 EditWidget::onActionFileNew()
169 //    g_warning("onActionFileNew called");
170     sp_file_new_default();
173 void
174 EditWidget::onActionFileOpen()
176 //    g_warning("onActionFileOpen called");
177     sp_file_open_dialog (NULL, NULL);
180 void
181 EditWidget::onActionFileQuit()
183     g_warning("onActionFileQuit");
184     sp_ui_close_all();
187 void
188 EditWidget::onActionFilePrint()
190     g_warning("onActionFilePrint");
193 void
194 EditWidget::onToolbarItem()
196     g_warning("onToolbarItem called");
199 void
200 EditWidget::onSelectTool()
202     _tool_ctrl->remove();
203     _tool_ctrl->add(*_select_ctrl);
206 void
207 EditWidget::onNodeTool()
209     _tool_ctrl->remove();
210     _tool_ctrl->add(*_node_ctrl);
213 void
214 EditWidget::onDialogInkscapePreferences()
216     _dlg_mgr.showDialog("InkscapePreferences");
219 void
220 EditWidget::onDialogAbout()
224 void
225 EditWidget::onDialogAlignAndDistribute()
227     _dlg_mgr.showDialog("AlignAndDistribute");
230 void
231 EditWidget::onDialogDocumentProperties()
233 //    manage (Inkscape::UI::Dialog::DocumentPreferences::create());
234     _dlg_mgr.showDialog("DocumentPreferences");
237 void
238 EditWidget::onDialogExport()
240     _dlg_mgr.showDialog("Export");
243 void
244 EditWidget::onDialogExtensionEditor()
246     _dlg_mgr.showDialog("ExtensionEditor");
249 void
250 EditWidget::onDialogFillAndStroke()
252     _dlg_mgr.showDialog("FillAndStroke");
255 void
256 EditWidget::onDialogFind()
258     _dlg_mgr.showDialog("Find");
261 void
262 EditWidget::onDialogLayerEditor()
264     _dlg_mgr.showDialog("LayerEditor");
267 void
268 EditWidget::onDialogMessages()
270     _dlg_mgr.showDialog("Messages");
273 void
274 EditWidget::onDialogObjectProperties()
276     _dlg_mgr.showDialog("ObjectProperties");
279 void 
280 EditWidget::onDialogTextProperties()
282     _dlg_mgr.showDialog("TextProperties");
285 void
286 EditWidget::onDialogTrace()
290 void 
291 EditWidget::onDialogTransformation()
293     _dlg_mgr.showDialog("Transformation");
296 void
297 EditWidget::onDialogXmlEditor()
299     _dlg_mgr.showDialog("XmlEditor");
302 #ifdef WITH_INKBOARD
303 void
304 EditWidget::onDialogWhiteboardConnect()
306         Dialog::WhiteboardConnectDialogImpl* dlg = dynamic_cast< Dialog::WhiteboardConnectDialogImpl* >(_dlg_mgr.getDialog("WhiteboardConnect"));
307         dlg->setSessionManager();
308         _dlg_mgr.showDialog("WhiteboardConnect");
311 void
312 EditWidget::onDialogWhiteboardShareWithUser()
314                 Dialog::WhiteboardShareWithUserDialogImpl* dlg = dynamic_cast< Dialog::WhiteboardShareWithUserDialogImpl* >(_dlg_mgr.getDialog("WhiteboardShareWithUser"));
315                 dlg->setSessionManager();
316                 _dlg_mgr.showDialog("WhiteboardShareWithUser");
319 void
320 EditWidget::onDialogWhiteboardShareWithChat()
322         Dialog::WhiteboardShareWithChatroomDialogImpl* dlg = dynamic_cast< Dialog::WhiteboardShareWithChatroomDialogImpl* >(_dlg_mgr.getDialog("WhiteboardShareWithChat"));
323         dlg->setSessionManager();
324         _dlg_mgr.showDialog("WhiteboardShareWithChat");
327 void
328 EditWidget::onDialogOpenSessionFile()
330         g_log(NULL, G_LOG_LEVEL_DEBUG, "not reimplemented yet");
333 void
334 EditWidget::onDumpXMLTracker()
336         g_log(NULL, G_LOG_LEVEL_DEBUG, "not reimplemented yet");
339 #endif
341 void
342 EditWidget::onUriChanged()
344     g_message("onUriChanged called");
345     
348 // FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled
349 // See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details
351 void
352 EditWidget::initMenuActions()
354 //    _act_grp->add(Gtk::Action::create("MenuFile",   _("PLACEHOLDER, do not translate")));
355 //    _act_grp->add(Gtk::Action::create("MenuEdit",   _("PLACEHOLDER, do not translate")));
356 //    _act_grp->add(Gtk::Action::create("MenuView",   _("PLACEHOLDER, do not translate")));
357 //    _act_grp->add(Gtk::Action::create("MenuLayer",  _("PLACEHOLDER, do not translate")));
358 //    _act_grp->add(Gtk::Action::create("MenuObject", _("PLACEHOLDER, do not translate")));
359 //    _act_grp->add(Gtk::Action::create("MenuPath",   _("PLACEHOLDER, do not translate")));
360 //    _act_grp->add(Gtk::Action::create("MenuText",   _("PLACEHOLDER, do not translate")));
361 #ifdef WITH_INKBOARD
362 //    _act_grp->add(Gtk::Action::create("MenuWhiteboard",   _("PLACEHOLDER, do not translate")));
363 #endif
364 //    _act_grp->add(Gtk::Action::create("MenuHelp",   _("PLACEHOLDER, do not translate")));
365 // temporarily replaced with non-gettext version to have a well-sized menu
366 // for testing:
368     _act_grp->add(Gtk::Action::create("MenuFile",   "File"));
369     _act_grp->add(Gtk::Action::create("MenuEdit",   "Edit"));
370     _act_grp->add(Gtk::Action::create("MenuView",   "View"));
371     _act_grp->add(Gtk::Action::create("MenuLayer",  "Layer"));
372     _act_grp->add(Gtk::Action::create("MenuObject", "Object"));
373     _act_grp->add(Gtk::Action::create("MenuPath",   "Path"));
374     _act_grp->add(Gtk::Action::create("MenuText",   "Text"));
375 #ifdef WITH_INKBOARD
376     _act_grp->add(Gtk::Action::create("MenuWhiteboard",   "Whiteboard"));
377 #endif
378     _act_grp->add(Gtk::Action::create("MenuHelp",   "Help"));
380     // File menu
381     _act_grp->add(Gtk::Action::create("New",
382                                       Gtk::Stock::NEW, Glib::ustring(),
383                                       _("PLACEHOLDER, do not translate")),
384                   sigc::mem_fun(*this, &EditWidget::onActionFileNew));
386     _act_grp->add(Gtk::Action::create("Open",
387                                       Gtk::Stock::OPEN, Glib::ustring(),
388                                       _("PLACEHOLDER, do not translate")),
389                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
391     _act_grp->add(Gtk::Action::create("OpenRecent",
392                                       Stock::OPEN_RECENT));
394     _act_grp->add(Gtk::Action::create("Revert",
395                                       Gtk::Stock::REVERT_TO_SAVED, Glib::ustring(),
396                                       _("PLACEHOLDER, do not translate")),
397                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
399     _act_grp->add(Gtk::Action::create("Save",
400                                       Gtk::Stock::SAVE, Glib::ustring(),
401                                       _("PLACEHOLDER, do not translate")),
402                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
404     _act_grp->add(Gtk::Action::create("SaveAs",
405                                       Gtk::Stock::SAVE_AS, Glib::ustring(),
406                                       _("PLACEHOLDER, do not translate")),
407                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
409     _act_grp->add(Gtk::Action::create("Import",
410                                       Stock::IMPORT, Glib::ustring(),
411                                       _("PLACEHOLDER, do not translate")),
412                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
414     _act_grp->add(Gtk::Action::create("Export",
415                                       Stock::EXPORT, Glib::ustring(),
416                                       _("PLACEHOLDER, do not translate")),
417                   sigc::mem_fun(*this, &EditWidget::onDialogExport));
419     _act_grp->add(Gtk::Action::create("Print",
420                                       Gtk::Stock::PRINT, Glib::ustring(),
421                                       _("PLACEHOLDER, do not translate")),
422                   sigc::mem_fun(*this, &EditWidget::onActionFilePrint));
424     _act_grp->add(Gtk::Action::create("PrintPreview",
425                                       Gtk::Stock::PRINT_PREVIEW),
426                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
428     _act_grp->add(Gtk::Action::create("VacuumDefs",
429                                       Stock::VACUUM_DEFS),
430                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
432     _act_grp->add(Gtk::Action::create("DocumentProperties",
433                                       Gtk::Stock::PROPERTIES, Glib::ustring(),
434                                       _("PLACEHOLDER, do not translate")),
435                   sigc::mem_fun(*this, &EditWidget::onDialogDocumentProperties));
437     _act_grp->add(Gtk::Action::create("InkscapePreferences",
438                                       Gtk::Stock::PREFERENCES, Glib::ustring(),
439                                       _("PLACEHOLDER, do not translate")),
440                   sigc::mem_fun(*this, &EditWidget::onDialogInkscapePreferences));
442     _act_grp->add(Gtk::Action::create("Close",
443                                       Gtk::Stock::CLOSE),
444                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
446     _act_grp->add(Gtk::Action::create("Quit",
447                                       Gtk::Stock::QUIT),
448                   sigc::mem_fun(*this, &EditWidget::onActionFileQuit));
450     // EditWidget menu
451     _act_grp->add(Gtk::Action::create("Undo",
452                                       Gtk::Stock::UNDO, Glib::ustring(),
453                                       _("PLACEHOLDER, do not translate")));
455     _act_grp->add(Gtk::Action::create("Redo",
456                                       Gtk::Stock::REDO, Glib::ustring(),
457                                       _("PLACEHOLDER, do not translate")));
459     _act_grp->add(Gtk::Action::create("Cut",
460                                       Gtk::Stock::CUT, Glib::ustring(),
461                                       _("PLACEHOLDER, do not translate")));
463     _act_grp->add(Gtk::Action::create("Copy",
464                                       Gtk::Stock::COPY, Glib::ustring(),
465                                       _("PLACEHOLDER, do not translate")));
467     _act_grp->add(Gtk::Action::create("Paste",
468                                       Gtk::Stock::PASTE, Glib::ustring(),
469                                       _("PLACEHOLDER, do not translate")));
471     _act_grp->add(Gtk::Action::create("PasteInPlace",
472                                       Stock::PASTE_IN_PLACE));
474     _act_grp->add(Gtk::Action::create("PasteStyle",
475                                       Stock::PASTE_STYLE));
477     _act_grp->add(Gtk::Action::create("Find",
478                                       Gtk::Stock::FIND),
479                   sigc::mem_fun(*this, &EditWidget::onDialogFind));
481     _act_grp->add(Gtk::Action::create("Duplicate",
482                                       Stock::DUPLICATE, Glib::ustring(),
483                                       _("PLACEHOLDER, do not translate")));
485     _act_grp->add(Gtk::Action::create("Clone",
486                                       Stock::CLONE, Glib::ustring(),
487                                       _("PLACEHOLDER, do not translate")));
489     _act_grp->add(Gtk::Action::create("CloneUnlink",
490                                       Stock::CLONE_UNLINK, Glib::ustring(),
491                                       _("PLACEHOLDER, do not translate")));
493     _act_grp->add(Gtk::Action::create("CloneSelectOrig",
494                                       Stock::CLONE_SELECT_ORIG));
496     _act_grp->add(Gtk::Action::create("MakeBitmap",
497                                       Stock::MAKE_BITMAP));
499     _act_grp->add(Gtk::Action::create("Tile",
500                                      Stock::TILE));
502     _act_grp->add(Gtk::Action::create("Untile",
503                                       Stock::UNTILE));
505     _act_grp->add(Gtk::Action::create("Delete",
506                                       Gtk::Stock::DELETE));
508     _act_grp->add(Gtk::Action::create("SelectAll",
509                                       Stock::SELECT_ALL));
511     _act_grp->add(Gtk::Action::create("SelectAllInAllLayers",
512                                       Stock::SELECT_ALL_IN_ALL_LAYERS));
514     _act_grp->add(Gtk::Action::create("SelectInvert",
515                                       Stock::SELECT_INVERT));
517     _act_grp->add(Gtk::Action::create("SelectNone",
518                                       Stock::SELECT_NONE));
520     _act_grp->add(Gtk::Action::create("XmlEditor",
521                                       Stock::XML_EDITOR, Glib::ustring(),
522                                       _("PLACEHOLDER, do not translate")),
523                   sigc::mem_fun(*this, &EditWidget::onDialogXmlEditor));
525     // View menu
526     _act_grp->add(Gtk::Action::create("Zoom",
527                                       Stock::ZOOM));
529     _act_grp->add(Gtk::Action::create("ZoomIn",
530                                       Stock::ZOOM_IN, Glib::ustring(),
531                                       _("PLACEHOLDER, do not translate")));
533     _act_grp->add(Gtk::Action::create("ZoomOut",
534                                       Stock::ZOOM_OUT, Glib::ustring(),
535                                       _("PLACEHOLDER, do not translate")));
537     _act_grp->add(Gtk::Action::create("Zoom100",
538                                       Stock::ZOOM_100, Glib::ustring(),
539                                       _("PLACEHOLDER, do not translate")));
541     _act_grp->add(Gtk::Action::create("Zoom50",
542                                       Stock::ZOOM_50, Glib::ustring(),
543                                       _("PLACEHOLDER, do not translate")));
545     _act_grp->add(Gtk::Action::create("Zoom200",
546                                       Stock::ZOOM_200, Glib::ustring(),
547                                       _("PLACEHOLDER, do not translate")));
549     _act_grp->add(Gtk::Action::create("ZoomSelection",
550                                       Stock::ZOOM_SELECTION, Glib::ustring(),
551                                       _("PLACEHOLDER, do not translate")));
553     _act_grp->add(Gtk::Action::create("ZoomDrawing",
554                                       Stock::ZOOM_DRAWING, Glib::ustring(),
555                                       _("PLACEHOLDER, do not translate")));
557     _act_grp->add(Gtk::Action::create("ZoomPage",
558                                       Stock::ZOOM_PAGE, Glib::ustring(),
559                                       _("PLACEHOLDER, do not translate")));
561     _act_grp->add(Gtk::Action::create("ZoomWidth",
562                                       Stock::ZOOM_WIDTH, Glib::ustring(),
563                                       _("PLACEHOLDER, do not translate")));
565     _act_grp->add(Gtk::Action::create("ZoomPrev",
566                                       Stock::ZOOM_PREV, Glib::ustring(),
567                                       _("PLACEHOLDER, do not translate")));
569     _act_grp->add(Gtk::Action::create("ZoomNext",
570                                       Stock::ZOOM_NEXT, Glib::ustring(),
571                                       _("PLACEHOLDER, do not translate")));
573     _act_grp->add(Gtk::Action::create("ShowHide",
574                                       Stock::SHOW_HIDE));
576     _act_grp->add(Gtk::ToggleAction::create("ShowHideCommandsBar",
577                                             Stock::SHOW_HIDE_COMMANDS_BAR));
579     _act_grp->add(Gtk::ToggleAction::create("ShowHideToolControlsBar",
580                                             Stock::SHOW_HIDE_TOOL_CONTROLS_BAR));
582     _act_grp->add(Gtk::ToggleAction::create("ShowHideToolsBar",
583                                             Stock::SHOW_HIDE_TOOLS_BAR));
585     _act_grp->add(Gtk::ToggleAction::create("ShowHideRulers",
586                                             Stock::SHOW_HIDE_RULERS));
588     _act_grp->add(Gtk::ToggleAction::create("ShowHideScrollbars",
589                                             Stock::SHOW_HIDE_SCROLLBARS));
591     _act_grp->add(Gtk::ToggleAction::create("ShowHideStatusbar",
592                                             Stock::SHOW_HIDE_STATUSBAR));
594     _act_grp->add(Gtk::Action::create("ShowHideDialogs",
595                                       Stock::SHOW_HIDE_DIALOGS));
597     _act_grp->add(Gtk::Action::create("Grid",
598                                       Stock::GRID));
600     _act_grp->add(Gtk::Action::create("Guides",
601                                       Stock::GUIDES));
603     _act_grp->add(Gtk::Action::create("Fullscreen",
604                                       Stock::FULLSCREEN));
606     _act_grp->add(Gtk::Action::create("Messages",
607                                       Stock::MESSAGES),
608                   sigc::mem_fun(*this, &EditWidget::onDialogMessages));
610     _act_grp->add(Gtk::Action::create("Scripts",
611                                       Stock::SCRIPTS));
613     _act_grp->add(Gtk::Action::create("WindowPrev",
614                                       Stock::WINDOW_PREV));
616     _act_grp->add(Gtk::Action::create("WindowNext",
617                                       Stock::WINDOW_NEXT));
619     _act_grp->add(Gtk::Action::create("WindowDuplicate",
620                                       Stock::WINDOW_DUPLICATE));
622     // Layer menu
623     _act_grp->add(Gtk::Action::create("LayerNew",
624                                       Stock::LAYER_NEW));
626     _act_grp->add(Gtk::Action::create("LayerRename",
627                                       Stock::LAYER_RENAME));
629     _act_grp->add(Gtk::Action::create("LayerDuplicate",
630                                       Stock::LAYER_DUPLICATE));
632     _act_grp->add(Gtk::Action::create("LayerAnchor",
633                                       Stock::LAYER_ANCHOR));
635     _act_grp->add(Gtk::Action::create("LayerMergeDown",
636                                       Stock::LAYER_MERGE_DOWN));
638     _act_grp->add(Gtk::Action::create("LayerDelete",
639                                       Stock::LAYER_DELETE));
641     _act_grp->add(Gtk::Action::create("LayerSelectNext",
642                                       Stock::LAYER_SELECT_NEXT));
644     _act_grp->add(Gtk::Action::create("LayerSelectPrev",
645                                       Stock::LAYER_SELECT_PREV));
647     _act_grp->add(Gtk::Action::create("LayerSelectTop",
648                                       Stock::LAYER_SELECT_TOP));
650     _act_grp->add(Gtk::Action::create("LayerSelectBottom",
651                                       Stock::LAYER_SELECT_BOTTOM));
653     _act_grp->add(Gtk::Action::create("LayerRaise",
654                                       Stock::LAYER_RAISE));
656     _act_grp->add(Gtk::Action::create("LayerLower",
657                                       Stock::LAYER_LOWER));
659     _act_grp->add(Gtk::Action::create("LayerToTop",
660                                       Stock::LAYER_TO_TOP));
662     _act_grp->add(Gtk::Action::create("LayerToBottom",
663                                       Stock::LAYER_TO_BOTTOM));
665     // Object menu
666     _act_grp->add(Gtk::Action::create("FillAndStroke",
667                                       Stock::FILL_STROKE, Glib::ustring(),
668                                       _("PLACEHOLDER, do not translate")),
669                   sigc::mem_fun(*this, &EditWidget::onDialogFillAndStroke));
671     _act_grp->add(Gtk::Action::create("ObjectProperties",
672                                       Stock::OBJECT_PROPERTIES),
673                   sigc::mem_fun(*this, &EditWidget::onDialogObjectProperties));
675     _act_grp->add(Gtk::Action::create("Group",
676                                       Stock::GROUP, Glib::ustring(),
677                                       _("PLACEHOLDER, do not translate")));
679     _act_grp->add(Gtk::Action::create("Ungroup",
680                                       Stock::UNGROUP, Glib::ustring(),
681                                       _("PLACEHOLDER, do not translate")));
683     _act_grp->add(Gtk::Action::create("Raise",
684                                       Stock::RAISE, Glib::ustring(),
685                                       _("PLACEHOLDER, do not translate")));
687     _act_grp->add(Gtk::Action::create("Lower",
688                                       Stock::LOWER, Glib::ustring(),
689                                       _("PLACEHOLDER, do not translate")));
691     _act_grp->add(Gtk::Action::create("RaiseToTop",
692                                       Stock::RAISE_TO_TOP, Glib::ustring(),
693                                       _("PLACEHOLDER, do not translate")));
695     _act_grp->add(Gtk::Action::create("LowerToBottom",
696                                       Stock::LOWER_TO_BOTTOM, Glib::ustring(),
697                                       _("PLACEHOLDER, do not translate")));
699     _act_grp->add(Gtk::Action::create("MoveToNewLayer",
700                                       Stock::MOVE_TO_NEW_LAYER, Glib::ustring(),
701                                       _("PLACEHOLDER, do not translate")));
703     _act_grp->add(Gtk::Action::create("MoveToNextLayer",
704                                       Stock::MOVE_TO_NEXT_LAYER, Glib::ustring(),
705                                       _("PLACEHOLDER, do not translate")));
707     _act_grp->add(Gtk::Action::create("MoveToPrevLayer",
708                                       Stock::MOVE_TO_PREV_LAYER, Glib::ustring(),
709                                       _("PLACEHOLDER, do not translate")));
711     _act_grp->add(Gtk::Action::create("MoveToTopLayer",
712                                       Stock::MOVE_TO_TOP_LAYER, Glib::ustring(),
713                                       _("PLACEHOLDER, do not translate")));
715     _act_grp->add(Gtk::Action::create("MoveToBottomLayer",
716                                       Stock::MOVE_TO_BOTTOM_LAYER, Glib::ustring(),
717                                       _("PLACEHOLDER, do not translate")));
719     _act_grp->add(Gtk::Action::create("Rotate90CW",
720                                       Stock::ROTATE_90_CW, Glib::ustring(),
721                                       _("PLACEHOLDER, do not translate")));
723     _act_grp->add(Gtk::Action::create("Rotate90CCW",
724                                       Stock::ROTATE_90_CCW, Glib::ustring(),
725                                       _("PLACEHOLDER, do not translate")));
727     _act_grp->add(Gtk::Action::create("FlipHoriz",
728                                       Stock::FLIP_HORIZ, Glib::ustring(),
729                                       _("PLACEHOLDER, do not translate")));
731     _act_grp->add(Gtk::Action::create("FlipVert",
732                                       Stock::FLIP_VERT, Glib::ustring(),
733                                       _("PLACEHOLDER, do not translate")));
735     _act_grp->add(Gtk::Action::create("Transformation",
736                                       Stock::TRANSFORMATION, Glib::ustring(),
737                                       _("PLACEHOLDER, do not translate")),
738                   sigc::mem_fun(*this, &EditWidget::onDialogTransformation));
740     _act_grp->add(Gtk::Action::create("AlignAndDistribute",
741                                       Stock::ALIGN_DISTRIBUTE, Glib::ustring(),
742                                       _("PLACEHOLDER, do not translate")),
743                   sigc::mem_fun(*this, &EditWidget::onDialogAlignAndDistribute));
745     // Path menu
746     _act_grp->add(Gtk::Action::create("ObjectToPath",
747                                       Stock::OBJECT_TO_PATH, Glib::ustring(),
748                                       _("PLACEHOLDER, do not translate")));
750     _act_grp->add(Gtk::Action::create("StrokeToPath",
751                                       Stock::STROKE_TO_PATH, Glib::ustring(),
752                                       _("PLACEHOLDER, do not translate")));
754     _act_grp->add(Gtk::Action::create("Trace",
755                                       Stock::TRACE),
756                   sigc::mem_fun(*this, &EditWidget::onDialogTrace));
758     _act_grp->add(Gtk::Action::create("Union",
759                                       Stock::UNION));
761     _act_grp->add(Gtk::Action::create("Difference",
762                                       Stock::DIFFERENCE));
764     _act_grp->add(Gtk::Action::create("Intersection",
765                                       Stock::INTERSECTION));
767     _act_grp->add(Gtk::Action::create("Exclusion",
768                                       Stock::EXCLUSION));
770     _act_grp->add(Gtk::Action::create("Division",
771                                       Stock::DIVISION));
773     _act_grp->add(Gtk::Action::create("CutPath",
774                                       Stock::CUT_PATH));
776     _act_grp->add(Gtk::Action::create("Combine",
777                                       Stock::COMBINE));
779     _act_grp->add(Gtk::Action::create("BreakApart",
780                                       Stock::BREAK_APART));
782     _act_grp->add(Gtk::Action::create("Inset",
783                                       Stock::INSET));
785     _act_grp->add(Gtk::Action::create("Outset",
786                                       Stock::OUTSET));
788     _act_grp->add(Gtk::Action::create("OffsetDynamic",
789                                       Stock::OFFSET_DYNAMIC));
791     _act_grp->add(Gtk::Action::create("OffsetLinked",
792                                       Stock::OFFSET_LINKED));
794     _act_grp->add(Gtk::Action::create("Simplify",
795                                       Stock::SIMPLIFY));
797     _act_grp->add(Gtk::Action::create("Reverse",
798                                       Stock::REVERSE));
800     _act_grp->add(Gtk::Action::create("Cleanup",
801                                       Gtk::Stock::CLEAR,
802                                       _("PLACEHOLDER, do not translate")));
804     // Text menu
805     _act_grp->add(Gtk::Action::create("TextProperties",
806                                       Gtk::Stock::SELECT_FONT, Glib::ustring(),
807                                       _("PLACEHOLDER, do not translate")),
808                   sigc::mem_fun(*this, &EditWidget::onDialogTextProperties));
810     _act_grp->add(Gtk::Action::create("PutOnPath",
811                                       Stock::PUT_ON_PATH));
813     _act_grp->add(Gtk::Action::create("RemoveFromPath",
814                                       Stock::REMOVE_FROM_PATH));
816     _act_grp->add(Gtk::Action::create("RemoveManualKerns",
817                                       Stock::REMOVE_MANUAL_KERNS));
819         // Whiteboard menu
820 #ifdef WITH_INKBOARD
821     _act_grp->add(Gtk::Action::create("DialogWhiteboardConnect",
822                                       Gtk::Stock::CLEAR, Glib::ustring(),
823                                       _("PLACEHOLDER, do not translate")),
824                   sigc::mem_fun(*this, &EditWidget::onDialogWhiteboardConnect));
826     _act_grp->add(Gtk::Action::create("DialogWhiteboardShareWithUser",
827                                       Gtk::Stock::CLEAR, Glib::ustring(),
828                                       _("PLACEHOLDER, do not translate")),
829                   sigc::mem_fun(*this, &EditWidget::onDialogWhiteboardShareWithUser));
831     _act_grp->add(Gtk::Action::create("DialogWhiteboardShareWithChat",
832                                       Gtk::Stock::CLEAR, Glib::ustring(),
833                                       _("PLACEHOLDER, do not translate")),
834                   sigc::mem_fun(*this, &EditWidget::onDialogWhiteboardShareWithChat));
836     _act_grp->add(Gtk::Action::create("WhiteboardOpenSessionFile",
837                                       Gtk::Stock::CLEAR, Glib::ustring(),
838                                       _("PLACEHOLDER, do not translate")),
839                   sigc::mem_fun(*this, &EditWidget::onDialogOpenSessionFile));
841     _act_grp->add(Gtk::Action::create("WhiteboardDumpXMLTracker",
842                                       Gtk::Stock::CLEAR, Glib::ustring(),
843                                       _("PLACEHOLDER, do not translate")),
844                   sigc::mem_fun(*this, &EditWidget::onDumpXMLTracker));
845 #endif
847     // About menu
848     _act_grp->add(Gtk::Action::create("KeysAndMouse",
849                                       Stock::KEYS_MOUSE));
851     _act_grp->add(Gtk::Action::create("Tutorials",
852                                       Stock::TUTORIALS));
854     _act_grp->add(Gtk::Action::create("About",
855                                       Stock::ABOUT),
856                   sigc::mem_fun(*this, &EditWidget::onDialogAbout));
859 void
860 EditWidget::initToolbarActions()
862     // Tools bar
863     Gtk::RadioAction::Group tools;
865     _act_grp->add(Gtk::RadioAction::create(tools, "ToolSelect",
866                                            Stock::TOOL_SELECT, Glib::ustring(),
867                                            _("PLACEHOLDER, do not translate")),
868                   sigc::mem_fun(*this, &EditWidget::onSelectTool));
870     _act_grp->add(Gtk::RadioAction::create(tools, "ToolNode",
871                                            Stock::TOOL_NODE, Glib::ustring(),
872                                            _("PLACEHOLDER, do not translate")),
873                   sigc::mem_fun(*this, &EditWidget::onNodeTool));
875     _act_grp->add(Gtk::RadioAction::create(tools, "ToolZoom",
876                                            Stock::TOOL_ZOOM, Glib::ustring(),
877                                            _("PLACEHOLDER, do not translate")));
879     _act_grp->add(Gtk::RadioAction::create(tools, "ToolRect",
880                                            Stock::TOOL_RECT, Glib::ustring(),
881                                            _("PLACEHOLDER, do not translate")));
883     _act_grp->add(Gtk::RadioAction::create(tools, "ToolArc",
884                                            Stock::TOOL_ARC, Glib::ustring(),
885                                            _("PLACEHOLDER, do not translate")));
887     _act_grp->add(Gtk::RadioAction::create(tools, "ToolStar",
888                                            Stock::TOOL_STAR, Glib::ustring(),
889                                            _("PLACEHOLDER, do not translate")));
891     _act_grp->add(Gtk::RadioAction::create(tools, "ToolSpiral",
892                                            Stock::TOOL_SPIRAL, Glib::ustring(),
893                                            _("PLACEHOLDER, do not translate")));
895     _act_grp->add(Gtk::RadioAction::create(tools, "ToolFreehand",
896                                            Stock::TOOL_FREEHAND, Glib::ustring(),
897                                            _("PLACEHOLDER, do not translate")));
899     _act_grp->add(Gtk::RadioAction::create(tools, "ToolPen",
900                                            Stock::TOOL_PEN, Glib::ustring(),
901                                            _("PLACEHOLDER, do not translate")));
903     _act_grp->add(Gtk::RadioAction::create(tools, "ToolDynaDraw",
904                                            Stock::TOOL_DYNADRAW, Glib::ustring(),
905                                            _("PLACEHOLDER, do not translate")));
907     _act_grp->add(Gtk::RadioAction::create(tools, "ToolText",
908                                            Stock::TOOL_TEXT, Glib::ustring(),
909                                            _("PLACEHOLDER, do not translate")));
911     _act_grp->add(Gtk::RadioAction::create(tools, "ToolDropper",
912                                            Stock::TOOL_DROPPER, Glib::ustring(),
913                                            _("PLACEHOLDER, do not translate")));
915     // Select Controls bar
916     _act_grp->add(Gtk::ToggleAction::create("TransformStroke",
917                                             Stock::TRANSFORM_STROKE, Glib::ustring(),
918                                             _("PLACEHOLDER, do not translate")));
920     _act_grp->add(Gtk::ToggleAction::create("TransformCorners",
921                                             Stock::TRANSFORM_CORNERS, Glib::ustring(),
922                                             _("PLACEHOLDER, do not translate")));
924     _act_grp->add(Gtk::ToggleAction::create("TransformGradient",
925                                             Stock::TRANSFORM_GRADIENT, Glib::ustring(),
926                                             _("PLACEHOLDER, do not translate")));
928     _act_grp->add(Gtk::ToggleAction::create("TransformPattern",
929                                             Stock::TRANSFORM_PATTERN, Glib::ustring(),
930                                             _("PLACEHOLDER, do not translate")));
932     // Node Controls bar
933     _act_grp->add(Gtk::Action::create("NodeInsert",
934                                       Gtk::Stock::ADD, Glib::ustring(),
935                                       _("PLACEHOLDER, do not translate")));
937     _act_grp->add(Gtk::Action::create("NodeDelete",
938                                       Gtk::Stock::REMOVE, Glib::ustring(),
939                                       _("PLACEHOLDER, do not translate")));
941     _act_grp->add(Gtk::Action::create("NodeJoin",
942                                       Stock::NODE_JOIN, Glib::ustring(),
943                                       _("PLACEHOLDER, do not translate")));
945     _act_grp->add(Gtk::Action::create("NodeJoinSegment",
946                                       Stock::NODE_JOIN_SEGMENT, Glib::ustring(),
947                                       _("PLACEHOLDER, do not translate")));
949     _act_grp->add(Gtk::Action::create("NodeDeleteSegment",
950                                       Stock::NODE_DELETE_SEGMENT, Glib::ustring(),
951                                       _("PLACEHOLDER, do not translate")));
953     _act_grp->add(Gtk::Action::create("NodeBreak",
954                                       Stock::NODE_BREAK, Glib::ustring(),
955                                       _("PLACEHOLDER, do not translate")));
957     _act_grp->add(Gtk::Action::create("NodeCorner",
958                                       Stock::NODE_CORNER, Glib::ustring(),
959                                       _("PLACEHOLDER, do not translate")));
961     _act_grp->add(Gtk::Action::create("NodeSmooth",
962                                       Stock::NODE_SMOOTH, Glib::ustring(),
963                                       _("PLACEHOLDER, do not translate")));
965     _act_grp->add(Gtk::Action::create("NodeSymmetric",
966                                       Stock::NODE_SYMMETRIC, Glib::ustring(),
967                                       _("PLACEHOLDER, do not translate")));
969     _act_grp->add(Gtk::Action::create("NodeLine",
970                                       Stock::NODE_LINE, Glib::ustring(),
971                                       _("PLACEHOLDER, do not translate")));
973     _act_grp->add(Gtk::Action::create("NodeCurve",
974                                       Stock::NODE_CURVE, Glib::ustring(),
975                                       _("PLACEHOLDER, do not translate")));
978 void
979 EditWidget::initAccelMap()
981     gchar *filename = g_build_filename(INKSCAPE_UIDIR, "keybindings.rc", NULL);
982     Gtk::AccelMap::load(filename);
983     g_free(filename);
985     // One problem is that the keys 1-6 are zoom accelerators which get
986     // caught as accelerator _before_ any Entry input handler receives them,
987     // for example the zoom status. At the moment, the best way seems to
988     // disable them as accelerators when the Entry gets focus, and enable
989     // them when focus goes elsewhere. The code for this belongs here,
990     // and not in zoom-status.cpp .
992     _zoom_status.signal_focus_in_event().connect (sigc::mem_fun (*this, &EditWidget::onEntryFocusIn));
993     _zoom_status.signal_focus_out_event().connect (sigc::mem_fun (*this, &EditWidget::onEntryFocusOut));
996 bool
997 EditWidget::onEntryFocusIn (GdkEventFocus* ev)
999     Gdk::ModifierType m = static_cast<Gdk::ModifierType>(0);
1000     Gtk::AccelMap::change_entry ("<Actions>//Zoom100", 0, m, false);
1001     Gtk::AccelMap::change_entry ("<Actions>//Zoom50", 0, m, false);
1002     Gtk::AccelMap::change_entry ("<Actions>//ZoomSelection", 0, m, false);
1003     Gtk::AccelMap::change_entry ("<Actions>//ZoomDrawing", 0, m, false);
1004     Gtk::AccelMap::change_entry ("<Actions>//ZoomPage", 0, m, false);
1005     Gtk::AccelMap::change_entry ("<Actions>//ZoomWidth", 0, m, false);
1006     return false;
1009 bool
1010 EditWidget::onEntryFocusOut (GdkEventFocus* ev)
1012     Gdk::ModifierType m = static_cast<Gdk::ModifierType>(0);
1013     Gtk::AccelMap::change_entry ("<Actions>//Zoom100", '1', m, false);
1014     Gtk::AccelMap::change_entry ("<Actions>//Zoom50", '2', m, false);
1015     Gtk::AccelMap::change_entry ("<Actions>//ZoomSelection", '3', m, false);
1016     Gtk::AccelMap::change_entry ("<Actions>//ZoomDrawing", '4', m, false);
1017     Gtk::AccelMap::change_entry ("<Actions>//ZoomPage", '5', m, false);
1018     Gtk::AccelMap::change_entry ("<Actions>//ZoomWidth", '6', m, false);
1019     return false;
1022 void
1023 EditWidget::initMenuBar()
1025     g_assert(_ui_mgr);
1026     Gtk::MenuBar *menu = static_cast<Gtk::MenuBar*>(_ui_mgr->get_widget("/MenuBar"));
1027     g_assert(menu != NULL);
1028     _main_window_table.attach(*Gtk::manage(menu), 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1031 void
1032 EditWidget::initCommandsBar()
1034     g_assert(_ui_mgr);
1035     Toolbox *bar = new Toolbox(static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/CommandsBar")),
1036                                Gtk::TOOLBAR_ICONS);
1037     g_assert(bar != NULL);
1038     _toolbars_vbox.pack_start(*Gtk::manage(bar), Gtk::PACK_SHRINK);
1041 void
1042 EditWidget::initToolControlsBar()
1044     // TODO: Do UIManager controlled widgets need to be deleted?
1045     _select_ctrl = static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/SelectControlsBar"));
1046     _node_ctrl = static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/NodeControlsBar"));
1048     _tool_ctrl = new Toolbox(_select_ctrl, Gtk::TOOLBAR_ICONS);
1050     _toolbars_vbox.pack_start(*Gtk::manage(_tool_ctrl), Gtk::PACK_SHRINK);
1053 void
1054 EditWidget::initUriBar()
1056     /// \todo  Create an Inkscape::UI::Widget::UriBar class (?)
1058     _uri_ctrl = new Gtk::Toolbar();
1060     _uri_label.set_label(_("PLACEHOLDER, DO NOT TRANSLATE"));
1061     _uri_ctrl->add(_uri_label);
1062     _uri_ctrl->add(_uri_entry);
1064     _uri_entry.signal_activate()
1065         .connect_notify(sigc::mem_fun(*this, &EditWidget::onUriChanged));
1067     _toolbars_vbox.pack_start(*Gtk::manage(_uri_ctrl), Gtk::PACK_SHRINK);
1070 void
1071 EditWidget::initToolsBar()
1073     Toolbox *bar = new Toolbox(static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/ToolsBar")),
1074                                Gtk::TOOLBAR_ICONS,
1075                                Gtk::ORIENTATION_VERTICAL);
1076     g_assert(bar != NULL);
1077     _sub_window_hbox.pack_start(*Gtk::manage(bar), Gtk::PACK_SHRINK);
1080 void
1081 EditWidget::initTopRuler()
1083     _viewport_table.attach(_top_ruler,  1, 2, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1084     
1085     _tooltips.set_tip (_top_ruler, _top_ruler.get_tip());
1088 void
1089 EditWidget::initLeftRuler()
1091     _viewport_table.attach(_left_ruler, 0, 1, 1, 2, Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
1092     
1093     _tooltips.set_tip (_left_ruler, _left_ruler.get_tip());
1096 void
1097 EditWidget::initBottomScrollbar()
1099     _viewport_table.attach(_bottom_scrollbar, 1, 2, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1100     _bottom_scrollbar.signal_value_changed().connect (sigc::mem_fun (*this, &EditWidget::onAdjValueChanged));
1101     _bottom_scrollbar.property_adjustment() = new Gtk::Adjustment (0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0);
1104 void
1105 EditWidget::initRightScrollbar()
1107     _viewport_table.attach(_right_scrollbar, 2, 3, 1, 2, Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
1109     _right_scrollbar.signal_value_changed().connect (sigc::mem_fun (*this, &EditWidget::onAdjValueChanged));
1110     _right_scrollbar.property_adjustment() = new Gtk::Adjustment (0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0);
1113 void 
1114 EditWidget::initStickyZoom()
1116     _viewport_table.attach(_sticky_zoom, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
1118     _sticky_zoom.set_active (prefs_get_int_attribute ("options.stickyzoom", "value", 0) != 0);
1119     _tooltips.set_tip (_sticky_zoom, _("Zoom drawing if window size changes"));
1120     
1121     /// \todo icon not implemented
1124 void
1125 EditWidget::initStatusbar()
1127     _statusbar.pack_start (_selected_style_status, false, false, 1);
1128     _statusbar.pack_start (*new Gtk::VSeparator(), false, false, 0);
1130     _tooltips.set_tip (_zoom_status, _("Zoom"));
1132     _layer_selector.reference();
1133     _statusbar.pack_start (_layer_selector, false, false, 1);
1135     _coord_status.property_n_rows() = 2;    
1136     _coord_status.property_n_columns() = 5;    
1137     _coord_status.property_row_spacing() = 0;
1138     _coord_status.property_column_spacing() = 2;
1139     _coord_eventbox.add (_coord_status);
1140     _tooltips.set_tip (_coord_eventbox, _("Cursor coordinates"));
1141     _coord_status.attach (*new Gtk::VSeparator(), 0,1, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1142     _coord_status.attach (*new Gtk::Label("X:", 0.0, 0.5), 1,2, 0,1, Gtk::FILL,Gtk::FILL, 0,0);
1143     _coord_status.attach (*new Gtk::Label("Y:", 0.0, 0.5), 1,2, 1,2, Gtk::FILL,Gtk::FILL, 0,0);
1144     _coord_status_x.set_text ("0.0");
1145     _coord_status_x.set_alignment (0.0, 0.5);
1146     _coord_status_y.set_text ("0.0");
1147     _coord_status_y.set_alignment (0.0, 0.5);
1148     _coord_status.attach (_coord_status_x, 2,3, 0,1, Gtk::FILL,Gtk::FILL, 0,0);
1149     _coord_status.attach (_coord_status_y, 2,3, 1,2, Gtk::FILL,Gtk::FILL, 0,0);
1150     _coord_status.attach (*new Gtk::Label("Z:", 0.0, 0.5), 3,4, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1151     _coord_status.attach (_zoom_status, 4,5, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1152     sp_set_font_size_smaller (static_cast<GtkWidget*>((void*)_coord_status.gobj()));
1153     _statusbar.pack_end (_coord_eventbox, false, false, 1);
1155     _select_status.property_xalign() = 0.0;
1156     _select_status.property_yalign() = 0.5;
1157     _select_status.set_markup (_("<b>Welcome to Inkscape!</b> Use shape or freehand tools to create objects; use selector (arrow) to move or transform them."));
1158     // include this again with Gtk+-2.6
1159     //_select_status.property_ellipsize() = Pango::ELLIPSIZE_END;
1160     _select_status.set_size_request (1, -1);
1161     _statusbar.pack_start (_select_status, true, true, 0);
1162     
1163     _main_window_table.attach(_statusbar, 0, 1, 3, 4, Gtk::FILL, Gtk::SHRINK);
1166 //========================================
1167 //----------implements EditWidgetInterface
1169 void *
1170 EditWidget::getWindow() 
1171
1172     return this; 
1175 void 
1176 EditWidget::setTitle (gchar const* new_title) 
1178     set_title (new_title);    
1181 void 
1182 EditWidget::layout() 
1184    show_all_children();
1187 void 
1188 EditWidget::present() 
1190     this->Gtk::Window::present();
1193 void 
1194 EditWidget::getGeometry (gint &x, gint &y, gint &w, gint &h) 
1196     get_position (x, y);
1197     get_size (w, h);
1200 void 
1201 EditWidget::setSize (gint w, gint h) 
1203     resize (w, h);
1206 void 
1207 EditWidget::setPosition (NR::Point p) 
1209     move (int(p[NR::X]), int(p[NR::Y]));
1212 /// \param p is already gobj()!
1213 void 
1214 EditWidget::setTransient (void* p, int i) 
1216 #ifndef WIN32
1217     gtk_window_set_transient_for (static_cast<GtkWindow*>(p), this->gobj());
1218     if (i==2)
1219         this->Gtk::Window::present();
1220 #endif
1223 NR::Point 
1224 EditWidget::getPointer() 
1225
1226     int x, y;
1227     get_pointer (x, y);
1228     return NR::Point (x, y); 
1231 void 
1232 EditWidget::setFullscreen() 
1234     fullscreen();
1237 /**
1238  *  Shuts down the desktop object for the view being closed.  It checks
1239  *  to see if the document has been edited, and if so prompts the user
1240  *  to save, discard, or cancel.  Returns TRUE if the shutdown operation
1241  *  is cancelled or if the save is cancelled or fails, FALSE otherwise.
1242  */
1243 bool 
1244 EditWidget::shutdown() 
1246     g_assert (_desktop != NULL);
1247     if (Inkscape::NSApplication::Editor::isDuplicatedView (_desktop))
1248         return false;
1250     SPDocument *doc = _desktop->doc();
1251     if (sp_document_repr_root(doc)->attribute("sodipodi:modified") != NULL) 
1252     {
1253         gchar *markup;
1254         /// \todo FIXME !!! obviously this will have problems if the document 
1255         /// name contains markup characters
1256         markup = g_strdup_printf(
1257                 _("<span weight=\"bold\" size=\"larger\">Save changes to document \"%s\" before closing?</span>\n\n"
1258                   "If you close without saving, your changes will be discarded."),
1259                 SP_DOCUMENT_NAME(doc));
1260         
1261         Gtk::MessageDialog dlg (*this, 
1262                        markup,
1263                        true,
1264                        Gtk::MESSAGE_WARNING,
1265                        Gtk::BUTTONS_NONE,
1266                        true);
1267         g_free(markup);
1268         Gtk::Button close_button (_("Close _without saving"), true);
1269         dlg.add_action_widget (close_button, Gtk::RESPONSE_NO);
1270         close_button.show();
1271         dlg.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1272         dlg.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_YES);
1273         dlg.set_default_response (Gtk::RESPONSE_YES);
1275         int response = dlg.run();
1276         switch (response) 
1277         {
1278             case Gtk::RESPONSE_YES:
1279                 sp_document_ref(doc);
1280                 if (sp_file_save_document(doc)) {
1281                     sp_document_unref(doc);
1282                 } else { // save dialog cancelled or save failed
1283                     sp_document_unref(doc);
1284                     return TRUE;
1285                 }
1286                 break;
1287             case Gtk::RESPONSE_NO:
1288                 break;
1289             default: // cancel pressed, or dialog was closed
1290                 return TRUE;
1291                 break;
1292         }
1293     }
1295     /* Code to check data loss */
1296     bool allow_data_loss = FALSE;
1297     while (sp_document_repr_root(doc)->attribute("inkscape:dataloss") != NULL && allow_data_loss == FALSE) 
1298     {
1299         gchar *markup;
1300         /// \todo FIXME !!! obviously this will have problems if the document 
1301         /// name contains markup characters
1302         markup = g_strdup_printf(
1303                 _("<span weight=\"bold\" size=\"larger\">The file \"%s\" was saved with a format (%s) that may cause data loss!</span>\n\n"
1304                   "Do you want to save this file in another format?"),
1305                 SP_DOCUMENT_NAME(doc),
1306                 Inkscape::Extension::db.get(sp_document_repr_root(doc)->attribute("inkscape:output_extension"))->get_name());
1307         
1308         Gtk::MessageDialog dlg (*this, 
1309                        markup,
1310                        true,
1311                        Gtk::MESSAGE_WARNING,
1312                        Gtk::BUTTONS_NONE,
1313                        true);
1314         g_free(markup);
1315         Gtk::Button close_button (_("Close _without saving"), true);
1316         dlg.add_action_widget (close_button, Gtk::RESPONSE_NO);
1317         close_button.show();
1318         dlg.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1319         dlg.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_YES);
1320         dlg.set_default_response (Gtk::RESPONSE_YES);
1322         int response = dlg.run();
1323         
1324         switch (response) 
1325         {
1326             case Gtk::RESPONSE_YES:
1327                 sp_document_ref(doc);
1328                 if (sp_file_save_document(doc)) {
1329                     sp_document_unref(doc);
1330                 } else { // save dialog cancelled or save failed
1331                     sp_document_unref(doc);
1332                     return TRUE;
1333                 }
1334                 break;
1335             case Gtk::RESPONSE_NO:
1336                 allow_data_loss = TRUE;
1337                 break;
1338             default: // cancel pressed, or dialog was closed
1339                 return TRUE;
1340                 break;
1341         }
1342     }
1343     
1344     return false;
1348 void 
1349 EditWidget::destroy() 
1350
1351     delete this; 
1354 void 
1355 EditWidget::requestCanvasUpdate() 
1357     _svg_canvas.widget().queue_draw();
1360 void 
1361 EditWidget::activateDesktop() 
1363     /// \todo active_desktop_indicator not implemented 
1366 void 
1367 EditWidget::deactivateDesktop() 
1369     /// \todo active_desktop_indicator not implemented
1372 void 
1373 EditWidget::viewSetPosition (NR::Point p) 
1375     p -= _namedview->gridorigin;
1376     double lo, up, pos, max;
1377     _top_ruler.get_range (lo, up, pos, max);
1378     _top_ruler.set_range (lo, up, p[NR::X], max);
1379     _left_ruler.get_range (lo, up, pos, max);
1380     _left_ruler.set_range (lo, up, p[NR::Y], max);
1383 void 
1384 EditWidget::updateRulers() 
1385 {    
1386     NR::Point origin = _namedview->gridorigin;
1388     NR::Rect const viewbox = _svg_canvas.spobj()->getViewbox();
1389     double lo, up, pos, max;
1390     double const scale = _desktop->current_zoom();
1391     double s = viewbox.min()[NR::X] / scale - origin[NR::X];
1392     double e = viewbox.max()[NR::X] / scale - origin[NR::X];
1393     _top_ruler.get_range(lo, up, pos, max);
1394     _top_ruler.set_range(s, e, pos, e);
1395     s = viewbox.min()[NR::Y] / -scale - origin[NR::Y];
1396     e = viewbox.max()[NR::Y] / -scale - origin[NR::Y];
1397     _left_ruler.set_range(s, e, origin[NR::Y], e);
1398     /// \todo is that correct?
1401 void 
1402 EditWidget::updateScrollbars (double scale) 
1404     // do not call this function before canvas has its size allocated
1405     if (!is_realized() || _update_s_f) {
1406         return;
1407     }
1409     _update_s_f = true;
1411     /* The desktop region we always show unconditionally */
1412     SPDocument *doc = _desktop->doc();
1413     NR::Rect const r = sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc)));
1414     NR::Rect darea(NR::Point(MIN(r.min()[NR::X], -sp_document_width(doc)),
1415                              MIN(r.min()[NR::Y], -sp_document_height(doc))),
1416                    NR::Point(MAX(r.max()[NR::X], 2 * sp_document_width(doc)),
1417                              MAX(r.max()[NR::Y], 2 * sp_document_height(doc))));
1419     /* Canvas region we always show unconditionally */
1420     NR::Rect carea(NR::Point(darea.min()[NR::X] * scale - 64,
1421                              darea.max()[NR::Y] * -scale - 64),
1422                    NR::Point(darea.max()[NR::X] * scale + 64,
1423                              darea.min()[NR::Y] * -scale + 64));
1425     NR::Rect const viewbox = _svg_canvas.spobj()->getViewbox();
1427     /* Viewbox is always included into scrollable region */
1428     carea = NR::Rect::union_bounds(carea, viewbox);
1430     Gtk::Adjustment *adj = _bottom_scrollbar.get_adjustment();
1431     adj->set_value(viewbox.min()[NR::X]);
1432     adj->set_lower(carea.min()[NR::X]);
1433     adj->set_upper(carea.max()[NR::X]);
1434     adj->set_page_increment(viewbox.dimensions()[NR::X]);
1435     adj->set_step_increment(0.1 * (viewbox.dimensions()[NR::X]));
1436     adj->set_page_size(viewbox.dimensions()[NR::X]);
1438     adj = _right_scrollbar.get_adjustment();
1439     adj->set_value(viewbox.min()[NR::Y]);
1440     adj->set_lower(carea.min()[NR::Y]);
1441     adj->set_upper(carea.max()[NR::Y]);
1442     adj->set_page_increment(viewbox.dimensions()[NR::Y]);
1443     adj->set_step_increment(0.1 * viewbox.dimensions()[NR::Y]);
1444     adj->set_page_size(viewbox.dimensions()[NR::Y]);
1446     _update_s_f = false;
1449 void
1450 EditWidget::toggleRulers() 
1452     if (_top_ruler.is_visible())
1453     {
1454         _top_ruler.hide_all();
1455         _left_ruler.hide_all();
1456         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 0);
1457     } else {
1458         _top_ruler.show_all();
1459         _left_ruler.show_all();
1460         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 1);
1461     }
1464 void 
1465 EditWidget::toggleScrollbars() 
1467     if (_bottom_scrollbar.is_visible())
1468     {
1469         _bottom_scrollbar.hide_all();
1470         _right_scrollbar.hide_all();
1471         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 0);
1472     } else {
1473         _bottom_scrollbar.show_all();
1474         _right_scrollbar.show_all();
1475         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 1);
1476     }
1479 void 
1480 EditWidget::updateZoom() 
1482     _zoom_status.update();
1485 void 
1486 EditWidget::letZoomGrabFocus() 
1488     _zoom_status.grab_focus();
1491 void 
1492 EditWidget::setToolboxFocusTo (const gchar *)
1494     /// \todo not implemented
1497 void 
1498 EditWidget::setToolboxAdjustmentValue (const gchar *, double)
1500     /// \todo not implemented
1503 bool 
1504 EditWidget::isToolboxButtonActive (gchar const*)
1506     /// \todo not implemented
1507     return true;
1510 void 
1511 EditWidget::setCoordinateStatus (NR::Point p) 
1513     gchar *cstr = g_strdup_printf ("%6.2f", _dt2r * p[NR::X]);
1514     _coord_status_x.property_label() = cstr;
1515     g_free (cstr);
1516     cstr = g_strdup_printf ("%6.2f", _dt2r * p[NR::Y]);
1517     _coord_status_y.property_label() = cstr;
1518     g_free (cstr);
1521 void 
1522 EditWidget::setMessage (Inkscape::MessageType type, gchar const* msg) 
1524     _select_status.set_markup (msg? msg : "");
1527 bool 
1528 EditWidget::warnDialog (gchar* msg)
1530     Gtk::MessageDialog dlg (*this, 
1531                        msg,
1532                        true,
1533                        Gtk::MESSAGE_WARNING,
1534                        Gtk::BUTTONS_YES_NO,
1535                        true);
1536     int r = dlg.run();
1537     return r == Gtk::RESPONSE_YES;
1541 void 
1542 EditWidget::initEdit (SPDocument *doc)
1544     _desktop = new SPDesktop();
1545     _desktop->registerEditWidget (this);
1547     _namedview = sp_document_namedview (doc, 0);
1548     _svg_canvas.init (_desktop);
1549     _desktop->init (_namedview, _svg_canvas.spobj());
1550     sp_namedview_window_from_document (_desktop);
1551     _dt2r = 1.0 / _namedview->doc_units->unittobase;
1553     /// \todo convert to sigc++ when SPObject hierarchy gets converted
1554     /* Listen on namedview modification */
1555     g_signal_connect (G_OBJECT (_desktop->namedview), "modified", G_CALLBACK (_namedview_modified), this);
1556     _layer_selector.setDesktop (_desktop);
1557     _selected_style_status.setDesktop (_desktop);
1558  
1559     Inkscape::NSApplication::Editor::addDesktop (_desktop);
1561     _zoom_status.init (_desktop);
1562     _top_ruler.init (_desktop, _svg_canvas.widget());
1563     _left_ruler.init (_desktop, _svg_canvas.widget());
1564     updateRulers();
1567 void 
1568 EditWidget::destroyEdit()
1570     if (_desktop) {
1571         _layer_selector.unreference();
1572         Inkscape::NSApplication::Editor::removeDesktop (_desktop); // clears selection too
1573         sp_signal_disconnect_by_data (G_OBJECT (_desktop->namedview), this);
1574         _desktop->destroy();
1575         Inkscape::GC::release (_desktop);
1576         _desktop = 0;
1577     }
1580 //----------end of EditWidgetInterface implementation
1582 //----------start of other callbacks
1584 bool 
1585 EditWidget::on_key_press_event (GdkEventKey* event)
1587     // this is the original code from helper/window.cpp
1589     unsigned int shortcut;
1590     shortcut = get_group0_keyval (event) |
1591                    ( event->state & GDK_SHIFT_MASK ?
1592                      SP_SHORTCUT_SHIFT_MASK : 0 ) |
1593                    ( event->state & GDK_CONTROL_MASK ?
1594                      SP_SHORTCUT_CONTROL_MASK : 0 ) |
1595                    ( event->state & GDK_MOD1_MASK ?
1596                      SP_SHORTCUT_ALT_MASK : 0 );
1597     return sp_shortcut_invoke (shortcut, 
1598                              Inkscape::NSApplication::Editor::getActiveDesktop());
1601 bool 
1602 EditWidget::on_delete_event (GdkEventAny*)
1604     return shutdown();
1607 bool 
1608 EditWidget::on_focus_in_event (GdkEventFocus*)
1610     Inkscape::NSApplication::Editor::activateDesktop (_desktop);
1611     _svg_canvas.widget().grab_focus();
1613     return false;
1616 void
1617 EditWidget::onWindowSizeAllocate (Gtk::Allocation &newall)
1619     if (!is_realized()) return;
1620     
1621     const Gtk::Allocation& all = get_allocation();
1622     if ((newall.get_x() == all.get_x()) &&
1623         (newall.get_y() == all.get_y()) &&
1624         (newall.get_width() == all.get_width()) &&
1625         (newall.get_height() == all.get_height())) {
1626         return;
1627     }
1629     NR::Rect const area = _desktop->get_display_area();
1630     double zoom = _desktop->current_zoom();
1632     if (_sticky_zoom.get_active()) {
1633         /* Calculate zoom per pixel */
1634         double const zpsp = zoom / hypot(area.dimensions()[NR::X], area.dimensions()[NR::Y]);
1635         /* Find new visible area */
1636         NR::Rect const newarea = _desktop->get_display_area();
1637         /* Calculate adjusted zoom */
1638         zoom = zpsp * hypot(newarea.dimensions()[NR::X], newarea.dimensions()[NR::Y]);
1639     }
1641     _desktop->zoom_absolute(area.midpoint()[NR::X], area.midpoint()[NR::Y], zoom);
1644 void
1645 EditWidget::onWindowRealize()
1647     NR::Rect d(NR::Point(0, 0),
1648                NR::Point(sp_document_width(_desktop->doc()), sp_document_height(_desktop->doc())));
1650     if (fabs(d.dimensions()[NR::X]) < 1.0 || fabs(d.dimensions()[NR::Y]) < 1.0) {
1651         return;
1652     }
1654     _desktop->set_display_area(d.min()[NR::X], d.min()[NR::Y], d.max()[NR::X], d.max()[NR::Y], 10);
1655     _namedview_modified(_desktop->namedview, SP_OBJECT_MODIFIED_FLAG, this);
1656     setTitle (SP_DOCUMENT_NAME(_desktop->doc()));
1659 void
1660 EditWidget::onAdjValueChanged()
1662     if (_update_a_f) return;
1663     _update_a_f = true;
1664     
1665     sp_canvas_scroll_to (_svg_canvas.spobj(), 
1666                          _bottom_scrollbar.get_value(), 
1667                          _right_scrollbar.get_value(), 
1668                          false);
1669     updateRulers();
1670     
1671     _update_a_f = false;
1674 /// \todo make this a member function when the signal is a sigc++ signal
1675 void _namedview_modified (SPNamedView* nv, guint flags, EditWidget* ew)
1677     if (flags & SP_OBJECT_MODIFIED_FLAG)
1678     {
1679         ew->_dt2r = 1.0 / nv->doc_units->unittobase;
1680         ew->_top_ruler.update_metric();
1681         ew->_left_ruler.update_metric();
1682         ew->_tooltips.set_tip (ew->_top_ruler, ew->_top_ruler.get_tip());
1683         ew->_tooltips.set_tip (ew->_left_ruler, ew->_left_ruler.get_tip());
1684         ew->updateRulers();
1685     }
1688 } // namespace View
1689 } // namespace UI
1690 } // namespace Inkscape
1692 /*
1693   Local Variables:
1694   mode:c++
1695   c-file-style:"stroustrup"
1696   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1697   indent-tabs-mode:nil
1698   fill-column:99
1699   End:
1700 */
1701 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :