Code

c42f447493cd1e39d03e44d08acc0de74c786103
[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 <gtk/gtkversion.h>
32 #include <gtk/gtklabel.h>
33 #include <gtkmm/radioaction.h>
34 #include <gtkmm/menubar.h>
35 #include <gtkmm/messagedialog.h>
36 #include <gtkmm/stock.h>
37 #include <gtkmm/accelmap.h>
38 #include <gtkmm/separator.h>
39 #include <gtkmm/base.h>
41 #include "macros.h"
42 #include "path-prefix.h"
43 #include "prefs-utils.h"
44 #include "file.h"
45 #include "application/editor.h"
46 #include "edit-widget.h"
47 #include "ui/stock.h"
48 #include "ui/stock-items.h"
49 #include "ui/icons.h"
51 #include "display/sodipodi-ctrlrect.h"
52 #include "helper/units.h"
53 #include "shortcuts.h"
54 #include "widgets/spw-utilities.h"
55 #include "event-context.h"
56 #include "document.h"
57 #include "sp-namedview.h"
58 #include "sp-item.h"
59 #include "interface.h"
60 #include "extension/db.h"
62 #ifdef WITH_INKBOARD
63 #include "ui/dialog/whiteboard-connect.h"
64 #include "ui/dialog/whiteboard-sharewithuser.h"
65 #include "ui/dialog/whiteboard-sharewithchat.h"
66 #endif
68 using namespace Inkscape::UI;
69 using namespace Inkscape::UI::Widget;
71 namespace Inkscape {
72 namespace UI {
73 namespace View {
75 EditWidget::EditWidget (SPDocument *doc)
76     : _main_window_table(4),
77       _viewport_table(3,3),
78       _act_grp(Gtk::ActionGroup::create()),
79       _ui_mgr(Gtk::UIManager::create()),
80       _update_s_f(false),
81       _update_a_f(false)
82 {
83     g_warning("Creating new EditWidget");
85     _desktop = 0;
86     Icons::init();
87     Stock::init();
88     initActions();
89     initAccelMap();
90     initUIManager();
91     initLayout();
92     initEdit (doc);
93     g_warning("Done creating new EditWidget");
94 }
96 EditWidget::~EditWidget()
97 {
98     destroyEdit();
99 }
101 void
102 EditWidget::initActions()
104     initMenuActions();
105     initToolbarActions();
108 void
109 EditWidget::initUIManager()
111     _ui_mgr->insert_action_group(_act_grp);
112     add_accel_group(_ui_mgr->get_accel_group());
114     gchar *filename_utf8 = g_build_filename(INKSCAPE_UIDIR, "menus-bars.xml", NULL);
115     if (_ui_mgr->add_ui_from_file(filename_utf8) == 0) {
116         g_warning("Error merging ui from file '%s'", filename_utf8);
117         // fixme-charset: What charset should we pass to g_warning?
118     }
119     g_free(filename_utf8);
122 void
123 EditWidget::initLayout()
125     set_title("New document 1 - Inkscape");
126     set_resizable();
127     set_default_size(640, 480);
129     // top level window into which all other portions of the UI get inserted
130     add(_main_window_table);
131     // attach box for horizontal toolbars
132     _main_window_table.attach(_toolbars_vbox, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
133     // attach sub-window for viewport and vertical toolbars
134     _main_window_table.attach(_sub_window_hbox, 0, 1, 2, 3);
135     // viewport table with 3 rows by 3 columns
136     _sub_window_hbox.pack_end(_viewport_table);
138     // Menus and Bars
139     initMenuBar();
140     initCommandsBar();
141     initToolControlsBar();
142     initUriBar();
143     initToolsBar();
145     // Canvas Viewport
146     initLeftRuler();
147     initTopRuler();
148     initStickyZoom();
149     initBottomScrollbar();
150     initRightScrollbar();
151     _viewport_table.attach(_svg_canvas.widget(), 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
152     _svg_canvas.widget().show_all();
155     // The statusbar comes last and appears at the bottom of _main_window_table
156     initStatusbar();
158     signal_size_allocate().connect (sigc::mem_fun (*this, &EditWidget::onWindowSizeAllocate), false);
159     signal_realize().connect (sigc::mem_fun (*this, &EditWidget::onWindowRealize));
160     show_all_children();
163 void
164 EditWidget::onMenuItem()
166     g_warning("onMenuItem called");
169 void
170 EditWidget::onActionFileNew()
172 //    g_warning("onActionFileNew called");
173     sp_file_new_default();
176 void
177 EditWidget::onActionFileOpen()
179 //    g_warning("onActionFileOpen called");
180     sp_file_open_dialog (NULL, NULL);
183 void
184 EditWidget::onActionFileQuit()
186     g_warning("onActionFileQuit");
187     sp_ui_close_all();
190 void
191 EditWidget::onActionFilePrint()
193     g_warning("onActionFilePrint");
196 void
197 EditWidget::onToolbarItem()
199     g_warning("onToolbarItem called");
202 void
203 EditWidget::onSelectTool()
205     _tool_ctrl->remove();
206     _tool_ctrl->add(*_select_ctrl);
209 void
210 EditWidget::onNodeTool()
212     _tool_ctrl->remove();
213     _tool_ctrl->add(*_node_ctrl);
216 void
217 EditWidget::onDialogInkscapePreferences()
219     _dlg_mgr.showDialog("InkscapePreferences");
222 void
223 EditWidget::onDialogAbout()
227 void
228 EditWidget::onDialogAlignAndDistribute()
230     _dlg_mgr.showDialog("AlignAndDistribute");
233 void
234 EditWidget::onDialogDocumentProperties()
236 //    manage (Inkscape::UI::Dialog::DocumentPreferences::create());
237     _dlg_mgr.showDialog("DocumentPreferences");
240 void
241 EditWidget::onDialogExport()
243     _dlg_mgr.showDialog("Export");
246 void
247 EditWidget::onDialogExtensionEditor()
249     _dlg_mgr.showDialog("ExtensionEditor");
252 void
253 EditWidget::onDialogFillAndStroke()
255     _dlg_mgr.showDialog("FillAndStroke");
258 void
259 EditWidget::onDialogFind()
261     _dlg_mgr.showDialog("Find");
264 void
265 EditWidget::onDialogLayerEditor()
267     _dlg_mgr.showDialog("LayerEditor");
270 void
271 EditWidget::onDialogMessages()
273     _dlg_mgr.showDialog("Messages");
276 void
277 EditWidget::onDialogObjectProperties()
279     _dlg_mgr.showDialog("ObjectProperties");
282 void
283 EditWidget::onDialogTextProperties()
285     _dlg_mgr.showDialog("TextProperties");
288 void
289 EditWidget::onDialogTrace()
293 void
294 EditWidget::onDialogTransformation()
296     _dlg_mgr.showDialog("Transformation");
299 void
300 EditWidget::onDialogXmlEditor()
302     _dlg_mgr.showDialog("XmlEditor");
305 #ifdef WITH_INKBOARD
306 void
307 EditWidget::onDialogWhiteboardConnect()
309         Dialog::WhiteboardConnectDialogImpl* dlg = dynamic_cast< Dialog::WhiteboardConnectDialogImpl* >(_dlg_mgr.getDialog("WhiteboardConnect"));
310         dlg->setSessionManager();
311         _dlg_mgr.showDialog("WhiteboardConnect");
314 void
315 EditWidget::onDialogWhiteboardShareWithUser()
317                 Dialog::WhiteboardShareWithUserDialogImpl* dlg = dynamic_cast< Dialog::WhiteboardShareWithUserDialogImpl* >(_dlg_mgr.getDialog("WhiteboardShareWithUser"));
318                 dlg->setSessionManager();
319                 _dlg_mgr.showDialog("WhiteboardShareWithUser");
322 void
323 EditWidget::onDialogWhiteboardShareWithChat()
325         Dialog::WhiteboardShareWithChatroomDialogImpl* dlg = dynamic_cast< Dialog::WhiteboardShareWithChatroomDialogImpl* >(_dlg_mgr.getDialog("WhiteboardShareWithChat"));
326         dlg->setSessionManager();
327         _dlg_mgr.showDialog("WhiteboardShareWithChat");
330 void
331 EditWidget::onDialogOpenSessionFile()
333         g_log(NULL, G_LOG_LEVEL_DEBUG, "not reimplemented yet");
336 void
337 EditWidget::onDumpXMLTracker()
339         g_log(NULL, G_LOG_LEVEL_DEBUG, "not reimplemented yet");
342 #endif
344 void
345 EditWidget::onUriChanged()
347     g_message("onUriChanged called");
351 // FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled
352 // See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details
354 void
355 EditWidget::initMenuActions()
357 //    _act_grp->add(Gtk::Action::create("MenuFile",   _("PLACEHOLDER, do not translate")));
358 //    _act_grp->add(Gtk::Action::create("MenuEdit",   _("PLACEHOLDER, do not translate")));
359 //    _act_grp->add(Gtk::Action::create("MenuView",   _("PLACEHOLDER, do not translate")));
360 //    _act_grp->add(Gtk::Action::create("MenuLayer",  _("PLACEHOLDER, do not translate")));
361 //    _act_grp->add(Gtk::Action::create("MenuObject", _("PLACEHOLDER, do not translate")));
362 //    _act_grp->add(Gtk::Action::create("MenuPath",   _("PLACEHOLDER, do not translate")));
363 //    _act_grp->add(Gtk::Action::create("MenuText",   _("PLACEHOLDER, do not translate")));
364 #ifdef WITH_INKBOARD
365 //    _act_grp->add(Gtk::Action::create("MenuWhiteboard",   _("PLACEHOLDER, do not translate")));
366 #endif
367 //    _act_grp->add(Gtk::Action::create("MenuHelp",   _("PLACEHOLDER, do not translate")));
368 // temporarily replaced with non-gettext version to have a well-sized menu
369 // for testing:
371     _act_grp->add(Gtk::Action::create("MenuFile",   "File"));
372     _act_grp->add(Gtk::Action::create("MenuEdit",   "Edit"));
373     _act_grp->add(Gtk::Action::create("MenuView",   "View"));
374     _act_grp->add(Gtk::Action::create("MenuLayer",  "Layer"));
375     _act_grp->add(Gtk::Action::create("MenuObject", "Object"));
376     _act_grp->add(Gtk::Action::create("MenuPath",   "Path"));
377     _act_grp->add(Gtk::Action::create("MenuText",   "Text"));
378 #ifdef WITH_INKBOARD
379     _act_grp->add(Gtk::Action::create("MenuWhiteboard",   "Whiteboard"));
380 #endif
381     _act_grp->add(Gtk::Action::create("MenuHelp",   "Help"));
383     // File menu
384     _act_grp->add(Gtk::Action::create("New",
385                                       Gtk::Stock::NEW, Glib::ustring(),
386                                       _("PLACEHOLDER, do not translate")),
387                   sigc::mem_fun(*this, &EditWidget::onActionFileNew));
389     _act_grp->add(Gtk::Action::create("Open",
390                                       Gtk::Stock::OPEN, Glib::ustring(),
391                                       _("PLACEHOLDER, do not translate")),
392                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
394     _act_grp->add(Gtk::Action::create("OpenRecent",
395                                       Stock::OPEN_RECENT));
397     _act_grp->add(Gtk::Action::create("Revert",
398                                       Gtk::Stock::REVERT_TO_SAVED, Glib::ustring(),
399                                       _("PLACEHOLDER, do not translate")),
400                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
402     _act_grp->add(Gtk::Action::create("Save",
403                                       Gtk::Stock::SAVE, Glib::ustring(),
404                                       _("PLACEHOLDER, do not translate")),
405                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
407     _act_grp->add(Gtk::Action::create("SaveAs",
408                                       Gtk::Stock::SAVE_AS, Glib::ustring(),
409                                       _("PLACEHOLDER, do not translate")),
410                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
412     _act_grp->add(Gtk::Action::create("Import",
413                                       Stock::IMPORT, Glib::ustring(),
414                                       _("PLACEHOLDER, do not translate")),
415                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
417     _act_grp->add(Gtk::Action::create("Export",
418                                       Stock::EXPORT, Glib::ustring(),
419                                       _("PLACEHOLDER, do not translate")),
420                   sigc::mem_fun(*this, &EditWidget::onDialogExport));
422     _act_grp->add(Gtk::Action::create("Print",
423                                       Gtk::Stock::PRINT, Glib::ustring(),
424                                       _("PLACEHOLDER, do not translate")),
425                   sigc::mem_fun(*this, &EditWidget::onActionFilePrint));
427     _act_grp->add(Gtk::Action::create("PrintPreview",
428                                       Gtk::Stock::PRINT_PREVIEW),
429                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
431     _act_grp->add(Gtk::Action::create("VacuumDefs",
432                                       Stock::VACUUM_DEFS),
433                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
435     _act_grp->add(Gtk::Action::create("DocumentProperties",
436                                       Gtk::Stock::PROPERTIES, Glib::ustring(),
437                                       _("PLACEHOLDER, do not translate")),
438                   sigc::mem_fun(*this, &EditWidget::onDialogDocumentProperties));
440     _act_grp->add(Gtk::Action::create("InkscapePreferences",
441                                       Gtk::Stock::PREFERENCES, Glib::ustring(),
442                                       _("PLACEHOLDER, do not translate")),
443                   sigc::mem_fun(*this, &EditWidget::onDialogInkscapePreferences));
445     _act_grp->add(Gtk::Action::create("Close",
446                                       Gtk::Stock::CLOSE),
447                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
449     _act_grp->add(Gtk::Action::create("Quit",
450                                       Gtk::Stock::QUIT),
451                   sigc::mem_fun(*this, &EditWidget::onActionFileQuit));
453     // EditWidget menu
454     _act_grp->add(Gtk::Action::create("Undo",
455                                       Gtk::Stock::UNDO, Glib::ustring(),
456                                       _("PLACEHOLDER, do not translate")));
458     _act_grp->add(Gtk::Action::create("Redo",
459                                       Gtk::Stock::REDO, Glib::ustring(),
460                                       _("PLACEHOLDER, do not translate")));
462     _act_grp->add(Gtk::Action::create("Cut",
463                                       Gtk::Stock::CUT, Glib::ustring(),
464                                       _("PLACEHOLDER, do not translate")));
466     _act_grp->add(Gtk::Action::create("Copy",
467                                       Gtk::Stock::COPY, Glib::ustring(),
468                                       _("PLACEHOLDER, do not translate")));
470     _act_grp->add(Gtk::Action::create("Paste",
471                                       Gtk::Stock::PASTE, Glib::ustring(),
472                                       _("PLACEHOLDER, do not translate")));
474     _act_grp->add(Gtk::Action::create("PasteInPlace",
475                                       Stock::PASTE_IN_PLACE));
477     _act_grp->add(Gtk::Action::create("PasteStyle",
478                                       Stock::PASTE_STYLE));
480     _act_grp->add(Gtk::Action::create("Find",
481                                       Gtk::Stock::FIND),
482                   sigc::mem_fun(*this, &EditWidget::onDialogFind));
484     _act_grp->add(Gtk::Action::create("Duplicate",
485                                       Stock::DUPLICATE, Glib::ustring(),
486                                       _("PLACEHOLDER, do not translate")));
488     _act_grp->add(Gtk::Action::create("Clone",
489                                       Stock::CLONE, Glib::ustring(),
490                                       _("PLACEHOLDER, do not translate")));
492     _act_grp->add(Gtk::Action::create("CloneUnlink",
493                                       Stock::CLONE_UNLINK, Glib::ustring(),
494                                       _("PLACEHOLDER, do not translate")));
496     _act_grp->add(Gtk::Action::create("CloneSelectOrig",
497                                       Stock::CLONE_SELECT_ORIG));
499     _act_grp->add(Gtk::Action::create("MakeBitmap",
500                                       Stock::MAKE_BITMAP));
502     _act_grp->add(Gtk::Action::create("Tile",
503                                      Stock::TILE));
505     _act_grp->add(Gtk::Action::create("Untile",
506                                       Stock::UNTILE));
508     _act_grp->add(Gtk::Action::create("Delete",
509                                       Gtk::Stock::DELETE));
511     _act_grp->add(Gtk::Action::create("SelectAll",
512                                       Stock::SELECT_ALL));
514     _act_grp->add(Gtk::Action::create("SelectAllInAllLayers",
515                                       Stock::SELECT_ALL_IN_ALL_LAYERS));
517     _act_grp->add(Gtk::Action::create("SelectInvert",
518                                       Stock::SELECT_INVERT));
520     _act_grp->add(Gtk::Action::create("SelectNone",
521                                       Stock::SELECT_NONE));
523     _act_grp->add(Gtk::Action::create("XmlEditor",
524                                       Stock::XML_EDITOR, Glib::ustring(),
525                                       _("PLACEHOLDER, do not translate")),
526                   sigc::mem_fun(*this, &EditWidget::onDialogXmlEditor));
528     // View menu
529     _act_grp->add(Gtk::Action::create("Zoom",
530                                       Stock::ZOOM));
532     _act_grp->add(Gtk::Action::create("ZoomIn",
533                                       Stock::ZOOM_IN, Glib::ustring(),
534                                       _("PLACEHOLDER, do not translate")));
536     _act_grp->add(Gtk::Action::create("ZoomOut",
537                                       Stock::ZOOM_OUT, Glib::ustring(),
538                                       _("PLACEHOLDER, do not translate")));
540     _act_grp->add(Gtk::Action::create("Zoom100",
541                                       Stock::ZOOM_100, Glib::ustring(),
542                                       _("PLACEHOLDER, do not translate")));
544     _act_grp->add(Gtk::Action::create("Zoom50",
545                                       Stock::ZOOM_50, Glib::ustring(),
546                                       _("PLACEHOLDER, do not translate")));
548     _act_grp->add(Gtk::Action::create("Zoom200",
549                                       Stock::ZOOM_200, Glib::ustring(),
550                                       _("PLACEHOLDER, do not translate")));
552     _act_grp->add(Gtk::Action::create("ZoomSelection",
553                                       Stock::ZOOM_SELECTION, Glib::ustring(),
554                                       _("PLACEHOLDER, do not translate")));
556     _act_grp->add(Gtk::Action::create("ZoomDrawing",
557                                       Stock::ZOOM_DRAWING, Glib::ustring(),
558                                       _("PLACEHOLDER, do not translate")));
560     _act_grp->add(Gtk::Action::create("ZoomPage",
561                                       Stock::ZOOM_PAGE, Glib::ustring(),
562                                       _("PLACEHOLDER, do not translate")));
564     _act_grp->add(Gtk::Action::create("ZoomWidth",
565                                       Stock::ZOOM_WIDTH, Glib::ustring(),
566                                       _("PLACEHOLDER, do not translate")));
568     _act_grp->add(Gtk::Action::create("ZoomPrev",
569                                       Stock::ZOOM_PREV, Glib::ustring(),
570                                       _("PLACEHOLDER, do not translate")));
572     _act_grp->add(Gtk::Action::create("ZoomNext",
573                                       Stock::ZOOM_NEXT, Glib::ustring(),
574                                       _("PLACEHOLDER, do not translate")));
576     _act_grp->add(Gtk::Action::create("ShowHide",
577                                       Stock::SHOW_HIDE));
579     _act_grp->add(Gtk::ToggleAction::create("ShowHideCommandsBar",
580                                             Stock::SHOW_HIDE_COMMANDS_BAR));
582     _act_grp->add(Gtk::ToggleAction::create("ShowHideToolControlsBar",
583                                             Stock::SHOW_HIDE_TOOL_CONTROLS_BAR));
585     _act_grp->add(Gtk::ToggleAction::create("ShowHideToolsBar",
586                                             Stock::SHOW_HIDE_TOOLS_BAR));
588     _act_grp->add(Gtk::ToggleAction::create("ShowHideRulers",
589                                             Stock::SHOW_HIDE_RULERS));
591     _act_grp->add(Gtk::ToggleAction::create("ShowHideScrollbars",
592                                             Stock::SHOW_HIDE_SCROLLBARS));
594     _act_grp->add(Gtk::ToggleAction::create("ShowHideStatusbar",
595                                             Stock::SHOW_HIDE_STATUSBAR));
597     _act_grp->add(Gtk::Action::create("ShowHideDialogs",
598                                       Stock::SHOW_HIDE_DIALOGS));
600     _act_grp->add(Gtk::Action::create("Grid",
601                                       Stock::GRID));
603     _act_grp->add(Gtk::Action::create("Guides",
604                                       Stock::GUIDES));
606     _act_grp->add(Gtk::Action::create("Fullscreen",
607                                       Stock::FULLSCREEN));
609     _act_grp->add(Gtk::Action::create("Messages",
610                                       Stock::MESSAGES),
611                   sigc::mem_fun(*this, &EditWidget::onDialogMessages));
613     _act_grp->add(Gtk::Action::create("Scripts",
614                                       Stock::SCRIPTS));
616     _act_grp->add(Gtk::Action::create("WindowPrev",
617                                       Stock::WINDOW_PREV));
619     _act_grp->add(Gtk::Action::create("WindowNext",
620                                       Stock::WINDOW_NEXT));
622     _act_grp->add(Gtk::Action::create("WindowDuplicate",
623                                       Stock::WINDOW_DUPLICATE));
625     // Layer menu
626     _act_grp->add(Gtk::Action::create("LayerNew",
627                                       Stock::LAYER_NEW));
629     _act_grp->add(Gtk::Action::create("LayerRename",
630                                       Stock::LAYER_RENAME));
632     _act_grp->add(Gtk::Action::create("LayerDuplicate",
633                                       Stock::LAYER_DUPLICATE));
635     _act_grp->add(Gtk::Action::create("LayerAnchor",
636                                       Stock::LAYER_ANCHOR));
638     _act_grp->add(Gtk::Action::create("LayerMergeDown",
639                                       Stock::LAYER_MERGE_DOWN));
641     _act_grp->add(Gtk::Action::create("LayerDelete",
642                                       Stock::LAYER_DELETE));
644     _act_grp->add(Gtk::Action::create("LayerSelectNext",
645                                       Stock::LAYER_SELECT_NEXT));
647     _act_grp->add(Gtk::Action::create("LayerSelectPrev",
648                                       Stock::LAYER_SELECT_PREV));
650     _act_grp->add(Gtk::Action::create("LayerSelectTop",
651                                       Stock::LAYER_SELECT_TOP));
653     _act_grp->add(Gtk::Action::create("LayerSelectBottom",
654                                       Stock::LAYER_SELECT_BOTTOM));
656     _act_grp->add(Gtk::Action::create("LayerRaise",
657                                       Stock::LAYER_RAISE));
659     _act_grp->add(Gtk::Action::create("LayerLower",
660                                       Stock::LAYER_LOWER));
662     _act_grp->add(Gtk::Action::create("LayerToTop",
663                                       Stock::LAYER_TO_TOP));
665     _act_grp->add(Gtk::Action::create("LayerToBottom",
666                                       Stock::LAYER_TO_BOTTOM));
668     // Object menu
669     _act_grp->add(Gtk::Action::create("FillAndStroke",
670                                       Stock::FILL_STROKE, Glib::ustring(),
671                                       _("PLACEHOLDER, do not translate")),
672                   sigc::mem_fun(*this, &EditWidget::onDialogFillAndStroke));
674     _act_grp->add(Gtk::Action::create("ObjectProperties",
675                                       Stock::OBJECT_PROPERTIES),
676                   sigc::mem_fun(*this, &EditWidget::onDialogObjectProperties));
678     _act_grp->add(Gtk::Action::create("Group",
679                                       Stock::GROUP, Glib::ustring(),
680                                       _("PLACEHOLDER, do not translate")));
682     _act_grp->add(Gtk::Action::create("Ungroup",
683                                       Stock::UNGROUP, Glib::ustring(),
684                                       _("PLACEHOLDER, do not translate")));
686     _act_grp->add(Gtk::Action::create("Raise",
687                                       Stock::RAISE, Glib::ustring(),
688                                       _("PLACEHOLDER, do not translate")));
690     _act_grp->add(Gtk::Action::create("Lower",
691                                       Stock::LOWER, Glib::ustring(),
692                                       _("PLACEHOLDER, do not translate")));
694     _act_grp->add(Gtk::Action::create("RaiseToTop",
695                                       Stock::RAISE_TO_TOP, Glib::ustring(),
696                                       _("PLACEHOLDER, do not translate")));
698     _act_grp->add(Gtk::Action::create("LowerToBottom",
699                                       Stock::LOWER_TO_BOTTOM, Glib::ustring(),
700                                       _("PLACEHOLDER, do not translate")));
702     _act_grp->add(Gtk::Action::create("MoveToNewLayer",
703                                       Stock::MOVE_TO_NEW_LAYER, Glib::ustring(),
704                                       _("PLACEHOLDER, do not translate")));
706     _act_grp->add(Gtk::Action::create("MoveToNextLayer",
707                                       Stock::MOVE_TO_NEXT_LAYER, Glib::ustring(),
708                                       _("PLACEHOLDER, do not translate")));
710     _act_grp->add(Gtk::Action::create("MoveToPrevLayer",
711                                       Stock::MOVE_TO_PREV_LAYER, Glib::ustring(),
712                                       _("PLACEHOLDER, do not translate")));
714     _act_grp->add(Gtk::Action::create("MoveToTopLayer",
715                                       Stock::MOVE_TO_TOP_LAYER, Glib::ustring(),
716                                       _("PLACEHOLDER, do not translate")));
718     _act_grp->add(Gtk::Action::create("MoveToBottomLayer",
719                                       Stock::MOVE_TO_BOTTOM_LAYER, Glib::ustring(),
720                                       _("PLACEHOLDER, do not translate")));
722     _act_grp->add(Gtk::Action::create("Rotate90CW",
723                                       Stock::ROTATE_90_CW, Glib::ustring(),
724                                       _("PLACEHOLDER, do not translate")));
726     _act_grp->add(Gtk::Action::create("Rotate90CCW",
727                                       Stock::ROTATE_90_CCW, Glib::ustring(),
728                                       _("PLACEHOLDER, do not translate")));
730     _act_grp->add(Gtk::Action::create("FlipHoriz",
731                                       Stock::FLIP_HORIZ, Glib::ustring(),
732                                       _("PLACEHOLDER, do not translate")));
734     _act_grp->add(Gtk::Action::create("FlipVert",
735                                       Stock::FLIP_VERT, Glib::ustring(),
736                                       _("PLACEHOLDER, do not translate")));
738     _act_grp->add(Gtk::Action::create("Transformation",
739                                       Stock::TRANSFORMATION, Glib::ustring(),
740                                       _("PLACEHOLDER, do not translate")),
741                   sigc::mem_fun(*this, &EditWidget::onDialogTransformation));
743     _act_grp->add(Gtk::Action::create("AlignAndDistribute",
744                                       Stock::ALIGN_DISTRIBUTE, Glib::ustring(),
745                                       _("PLACEHOLDER, do not translate")),
746                   sigc::mem_fun(*this, &EditWidget::onDialogAlignAndDistribute));
748     // Path menu
749     _act_grp->add(Gtk::Action::create("ObjectToPath",
750                                       Stock::OBJECT_TO_PATH, Glib::ustring(),
751                                       _("PLACEHOLDER, do not translate")));
753     _act_grp->add(Gtk::Action::create("StrokeToPath",
754                                       Stock::STROKE_TO_PATH, Glib::ustring(),
755                                       _("PLACEHOLDER, do not translate")));
757     _act_grp->add(Gtk::Action::create("Trace",
758                                       Stock::TRACE),
759                   sigc::mem_fun(*this, &EditWidget::onDialogTrace));
761     _act_grp->add(Gtk::Action::create("Union",
762                                       Stock::UNION));
764     _act_grp->add(Gtk::Action::create("Difference",
765                                       Stock::DIFFERENCE));
767     _act_grp->add(Gtk::Action::create("Intersection",
768                                       Stock::INTERSECTION));
770     _act_grp->add(Gtk::Action::create("Exclusion",
771                                       Stock::EXCLUSION));
773     _act_grp->add(Gtk::Action::create("Division",
774                                       Stock::DIVISION));
776     _act_grp->add(Gtk::Action::create("CutPath",
777                                       Stock::CUT_PATH));
779     _act_grp->add(Gtk::Action::create("Combine",
780                                       Stock::COMBINE));
782     _act_grp->add(Gtk::Action::create("BreakApart",
783                                       Stock::BREAK_APART));
785     _act_grp->add(Gtk::Action::create("Inset",
786                                       Stock::INSET));
788     _act_grp->add(Gtk::Action::create("Outset",
789                                       Stock::OUTSET));
791     _act_grp->add(Gtk::Action::create("OffsetDynamic",
792                                       Stock::OFFSET_DYNAMIC));
794     _act_grp->add(Gtk::Action::create("OffsetLinked",
795                                       Stock::OFFSET_LINKED));
797     _act_grp->add(Gtk::Action::create("Simplify",
798                                       Stock::SIMPLIFY));
800     _act_grp->add(Gtk::Action::create("Reverse",
801                                       Stock::REVERSE));
803     _act_grp->add(Gtk::Action::create("Cleanup",
804                                       Gtk::Stock::CLEAR,
805                                       _("PLACEHOLDER, do not translate")));
807     // Text menu
808     _act_grp->add(Gtk::Action::create("TextProperties",
809                                       Gtk::Stock::SELECT_FONT, Glib::ustring(),
810                                       _("PLACEHOLDER, do not translate")),
811                   sigc::mem_fun(*this, &EditWidget::onDialogTextProperties));
813     _act_grp->add(Gtk::Action::create("PutOnPath",
814                                       Stock::PUT_ON_PATH));
816     _act_grp->add(Gtk::Action::create("RemoveFromPath",
817                                       Stock::REMOVE_FROM_PATH));
819     _act_grp->add(Gtk::Action::create("RemoveManualKerns",
820                                       Stock::REMOVE_MANUAL_KERNS));
822         // Whiteboard menu
823 #ifdef WITH_INKBOARD
824     _act_grp->add(Gtk::Action::create("DialogWhiteboardConnect",
825                                       Gtk::Stock::CLEAR, Glib::ustring(),
826                                       _("PLACEHOLDER, do not translate")),
827                   sigc::mem_fun(*this, &EditWidget::onDialogWhiteboardConnect));
829     _act_grp->add(Gtk::Action::create("DialogWhiteboardShareWithUser",
830                                       Gtk::Stock::CLEAR, Glib::ustring(),
831                                       _("PLACEHOLDER, do not translate")),
832                   sigc::mem_fun(*this, &EditWidget::onDialogWhiteboardShareWithUser));
834     _act_grp->add(Gtk::Action::create("DialogWhiteboardShareWithChat",
835                                       Gtk::Stock::CLEAR, Glib::ustring(),
836                                       _("PLACEHOLDER, do not translate")),
837                   sigc::mem_fun(*this, &EditWidget::onDialogWhiteboardShareWithChat));
839     _act_grp->add(Gtk::Action::create("WhiteboardOpenSessionFile",
840                                       Gtk::Stock::CLEAR, Glib::ustring(),
841                                       _("PLACEHOLDER, do not translate")),
842                   sigc::mem_fun(*this, &EditWidget::onDialogOpenSessionFile));
844     _act_grp->add(Gtk::Action::create("WhiteboardDumpXMLTracker",
845                                       Gtk::Stock::CLEAR, Glib::ustring(),
846                                       _("PLACEHOLDER, do not translate")),
847                   sigc::mem_fun(*this, &EditWidget::onDumpXMLTracker));
848 #endif
850     // About menu
851     _act_grp->add(Gtk::Action::create("KeysAndMouse",
852                                       Stock::KEYS_MOUSE));
854     _act_grp->add(Gtk::Action::create("Tutorials",
855                                       Stock::TUTORIALS));
857     _act_grp->add(Gtk::Action::create("About",
858                                       Stock::ABOUT),
859                   sigc::mem_fun(*this, &EditWidget::onDialogAbout));
862 void
863 EditWidget::initToolbarActions()
865     // Tools bar
866     Gtk::RadioAction::Group tools;
868     _act_grp->add(Gtk::RadioAction::create(tools, "ToolSelect",
869                                            Stock::TOOL_SELECT, Glib::ustring(),
870                                            _("PLACEHOLDER, do not translate")),
871                   sigc::mem_fun(*this, &EditWidget::onSelectTool));
873     _act_grp->add(Gtk::RadioAction::create(tools, "ToolNode",
874                                            Stock::TOOL_NODE, Glib::ustring(),
875                                            _("PLACEHOLDER, do not translate")),
876                   sigc::mem_fun(*this, &EditWidget::onNodeTool));
878     _act_grp->add(Gtk::RadioAction::create(tools, "ToolZoom",
879                                            Stock::TOOL_ZOOM, Glib::ustring(),
880                                            _("PLACEHOLDER, do not translate")));
882     _act_grp->add(Gtk::RadioAction::create(tools, "ToolRect",
883                                            Stock::TOOL_RECT, Glib::ustring(),
884                                            _("PLACEHOLDER, do not translate")));
886     _act_grp->add(Gtk::RadioAction::create(tools, "ToolArc",
887                                            Stock::TOOL_ARC, Glib::ustring(),
888                                            _("PLACEHOLDER, do not translate")));
890     _act_grp->add(Gtk::RadioAction::create(tools, "ToolStar",
891                                            Stock::TOOL_STAR, Glib::ustring(),
892                                            _("PLACEHOLDER, do not translate")));
894     _act_grp->add(Gtk::RadioAction::create(tools, "ToolSpiral",
895                                            Stock::TOOL_SPIRAL, Glib::ustring(),
896                                            _("PLACEHOLDER, do not translate")));
898     _act_grp->add(Gtk::RadioAction::create(tools, "ToolFreehand",
899                                            Stock::TOOL_FREEHAND, Glib::ustring(),
900                                            _("PLACEHOLDER, do not translate")));
902     _act_grp->add(Gtk::RadioAction::create(tools, "ToolPen",
903                                            Stock::TOOL_PEN, Glib::ustring(),
904                                            _("PLACEHOLDER, do not translate")));
906     _act_grp->add(Gtk::RadioAction::create(tools, "ToolDynaDraw",
907                                            Stock::TOOL_DYNADRAW, Glib::ustring(),
908                                            _("PLACEHOLDER, do not translate")));
910     _act_grp->add(Gtk::RadioAction::create(tools, "ToolText",
911                                            Stock::TOOL_TEXT, Glib::ustring(),
912                                            _("PLACEHOLDER, do not translate")));
914     _act_grp->add(Gtk::RadioAction::create(tools, "ToolDropper",
915                                            Stock::TOOL_DROPPER, Glib::ustring(),
916                                            _("PLACEHOLDER, do not translate")));
918     // Select Controls bar
919     _act_grp->add(Gtk::ToggleAction::create("TransformStroke",
920                                             Stock::TRANSFORM_STROKE, Glib::ustring(),
921                                             _("PLACEHOLDER, do not translate")));
923     _act_grp->add(Gtk::ToggleAction::create("TransformCorners",
924                                             Stock::TRANSFORM_CORNERS, Glib::ustring(),
925                                             _("PLACEHOLDER, do not translate")));
927     _act_grp->add(Gtk::ToggleAction::create("TransformGradient",
928                                             Stock::TRANSFORM_GRADIENT, Glib::ustring(),
929                                             _("PLACEHOLDER, do not translate")));
931     _act_grp->add(Gtk::ToggleAction::create("TransformPattern",
932                                             Stock::TRANSFORM_PATTERN, Glib::ustring(),
933                                             _("PLACEHOLDER, do not translate")));
935     // Node Controls bar
936     _act_grp->add(Gtk::Action::create("NodeInsert",
937                                       Gtk::Stock::ADD, Glib::ustring(),
938                                       _("PLACEHOLDER, do not translate")));
940     _act_grp->add(Gtk::Action::create("NodeDelete",
941                                       Gtk::Stock::REMOVE, Glib::ustring(),
942                                       _("PLACEHOLDER, do not translate")));
944     _act_grp->add(Gtk::Action::create("NodeJoin",
945                                       Stock::NODE_JOIN, Glib::ustring(),
946                                       _("PLACEHOLDER, do not translate")));
948     _act_grp->add(Gtk::Action::create("NodeJoinSegment",
949                                       Stock::NODE_JOIN_SEGMENT, Glib::ustring(),
950                                       _("PLACEHOLDER, do not translate")));
952     _act_grp->add(Gtk::Action::create("NodeDeleteSegment",
953                                       Stock::NODE_DELETE_SEGMENT, Glib::ustring(),
954                                       _("PLACEHOLDER, do not translate")));
956     _act_grp->add(Gtk::Action::create("NodeBreak",
957                                       Stock::NODE_BREAK, Glib::ustring(),
958                                       _("PLACEHOLDER, do not translate")));
960     _act_grp->add(Gtk::Action::create("NodeCorner",
961                                       Stock::NODE_CORNER, Glib::ustring(),
962                                       _("PLACEHOLDER, do not translate")));
964     _act_grp->add(Gtk::Action::create("NodeSmooth",
965                                       Stock::NODE_SMOOTH, Glib::ustring(),
966                                       _("PLACEHOLDER, do not translate")));
968     _act_grp->add(Gtk::Action::create("NodeSymmetric",
969                                       Stock::NODE_SYMMETRIC, Glib::ustring(),
970                                       _("PLACEHOLDER, do not translate")));
972     _act_grp->add(Gtk::Action::create("NodeLine",
973                                       Stock::NODE_LINE, Glib::ustring(),
974                                       _("PLACEHOLDER, do not translate")));
976     _act_grp->add(Gtk::Action::create("NodeCurve",
977                                       Stock::NODE_CURVE, Glib::ustring(),
978                                       _("PLACEHOLDER, do not translate")));
981 void
982 EditWidget::initAccelMap()
984     gchar *filename = g_build_filename(INKSCAPE_UIDIR, "keybindings.rc", NULL);
985     Gtk::AccelMap::load(filename);
986     g_free(filename);
988     // One problem is that the keys 1-6 are zoom accelerators which get
989     // caught as accelerator _before_ any Entry input handler receives them,
990     // for example the zoom status. At the moment, the best way seems to
991     // disable them as accelerators when the Entry gets focus, and enable
992     // them when focus goes elsewhere. The code for this belongs here,
993     // and not in zoom-status.cpp .
995     _zoom_status.signal_focus_in_event().connect (sigc::mem_fun (*this, &EditWidget::onEntryFocusIn));
996     _zoom_status.signal_focus_out_event().connect (sigc::mem_fun (*this, &EditWidget::onEntryFocusOut));
999 bool
1000 EditWidget::onEntryFocusIn (GdkEventFocus* ev)
1002     Gdk::ModifierType m = static_cast<Gdk::ModifierType>(0);
1003     Gtk::AccelMap::change_entry ("<Actions>//Zoom100", 0, m, false);
1004     Gtk::AccelMap::change_entry ("<Actions>//Zoom50", 0, m, false);
1005     Gtk::AccelMap::change_entry ("<Actions>//ZoomSelection", 0, m, false);
1006     Gtk::AccelMap::change_entry ("<Actions>//ZoomDrawing", 0, m, false);
1007     Gtk::AccelMap::change_entry ("<Actions>//ZoomPage", 0, m, false);
1008     Gtk::AccelMap::change_entry ("<Actions>//ZoomWidth", 0, m, false);
1009     return false;
1012 bool
1013 EditWidget::onEntryFocusOut (GdkEventFocus* ev)
1015     Gdk::ModifierType m = static_cast<Gdk::ModifierType>(0);
1016     Gtk::AccelMap::change_entry ("<Actions>//Zoom100", '1', m, false);
1017     Gtk::AccelMap::change_entry ("<Actions>//Zoom50", '2', m, false);
1018     Gtk::AccelMap::change_entry ("<Actions>//ZoomSelection", '3', m, false);
1019     Gtk::AccelMap::change_entry ("<Actions>//ZoomDrawing", '4', m, false);
1020     Gtk::AccelMap::change_entry ("<Actions>//ZoomPage", '5', m, false);
1021     Gtk::AccelMap::change_entry ("<Actions>//ZoomWidth", '6', m, false);
1022     return false;
1025 void
1026 EditWidget::initMenuBar()
1028     g_assert(_ui_mgr);
1029     Gtk::MenuBar *menu = static_cast<Gtk::MenuBar*>(_ui_mgr->get_widget("/MenuBar"));
1030     g_assert(menu != NULL);
1031     _main_window_table.attach(*Gtk::manage(menu), 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1034 void
1035 EditWidget::initCommandsBar()
1037     g_assert(_ui_mgr);
1038     Toolbox *bar = new Toolbox(static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/CommandsBar")),
1039                                Gtk::TOOLBAR_ICONS);
1040     g_assert(bar != NULL);
1041     _toolbars_vbox.pack_start(*Gtk::manage(bar), Gtk::PACK_SHRINK);
1044 void
1045 EditWidget::initToolControlsBar()
1047     // TODO: Do UIManager controlled widgets need to be deleted?
1048     _select_ctrl = static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/SelectControlsBar"));
1049     _node_ctrl = static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/NodeControlsBar"));
1051     _tool_ctrl = new Toolbox(_select_ctrl, Gtk::TOOLBAR_ICONS);
1053     _toolbars_vbox.pack_start(*Gtk::manage(_tool_ctrl), Gtk::PACK_SHRINK);
1056 void
1057 EditWidget::initUriBar()
1059     /// \todo  Create an Inkscape::UI::Widget::UriBar class (?)
1061     _uri_ctrl = new Gtk::Toolbar();
1063     _uri_label.set_label(_("PLACEHOLDER, DO NOT TRANSLATE"));
1064     _uri_ctrl->add(_uri_label);
1065     _uri_ctrl->add(_uri_entry);
1067     _uri_entry.signal_activate()
1068         .connect_notify(sigc::mem_fun(*this, &EditWidget::onUriChanged));
1070     _toolbars_vbox.pack_start(*Gtk::manage(_uri_ctrl), Gtk::PACK_SHRINK);
1073 void
1074 EditWidget::initToolsBar()
1076     Toolbox *bar = new Toolbox(static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/ToolsBar")),
1077                                Gtk::TOOLBAR_ICONS,
1078                                Gtk::ORIENTATION_VERTICAL);
1079     g_assert(bar != NULL);
1080     _sub_window_hbox.pack_start(*Gtk::manage(bar), Gtk::PACK_SHRINK);
1083 void
1084 EditWidget::initTopRuler()
1086     _viewport_table.attach(_top_ruler,  1, 2, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1088     _tooltips.set_tip (_top_ruler, _top_ruler.get_tip());
1091 void
1092 EditWidget::initLeftRuler()
1094     _viewport_table.attach(_left_ruler, 0, 1, 1, 2, Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
1096     _tooltips.set_tip (_left_ruler, _left_ruler.get_tip());
1099 void
1100 EditWidget::initBottomScrollbar()
1102     _viewport_table.attach(_bottom_scrollbar, 1, 2, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1103     _bottom_scrollbar.signal_value_changed().connect (sigc::mem_fun (*this, &EditWidget::onAdjValueChanged));
1104     _bottom_scrollbar.property_adjustment() = new Gtk::Adjustment (0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0);
1107 void
1108 EditWidget::initRightScrollbar()
1110     _viewport_table.attach(_right_scrollbar, 2, 3, 1, 2, Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
1112     _right_scrollbar.signal_value_changed().connect (sigc::mem_fun (*this, &EditWidget::onAdjValueChanged));
1113     _right_scrollbar.property_adjustment() = new Gtk::Adjustment (0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0);
1116 void
1117 EditWidget::initStickyZoom()
1119     _viewport_table.attach(_sticky_zoom, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
1121     _sticky_zoom.set_active (prefs_get_int_attribute ("options.stickyzoom", "value", 0) != 0);
1122     _tooltips.set_tip (_sticky_zoom, _("Zoom drawing if window size changes"));
1124     /// \todo icon not implemented
1127 void
1128 EditWidget::initStatusbar()
1130     _statusbar.pack_start (_selected_style_status, false, false, 1);
1131     _statusbar.pack_start (*new Gtk::VSeparator(), false, false, 0);
1133     _tooltips.set_tip (_zoom_status, _("Zoom"));
1135     _layer_selector.reference();
1136     _statusbar.pack_start (_layer_selector, false, false, 1);
1138     _coord_status.property_n_rows() = 2;
1139     _coord_status.property_n_columns() = 5;
1140     _coord_status.property_row_spacing() = 0;
1141     _coord_status.property_column_spacing() = 2;
1142     _coord_eventbox.add (_coord_status);
1143     _tooltips.set_tip (_coord_eventbox, _("Cursor coordinates"));
1144     _coord_status.attach (*new Gtk::VSeparator(), 0,1, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1145     _coord_status.attach (*new Gtk::Label("X:", 0.0, 0.5), 1,2, 0,1, Gtk::FILL,Gtk::FILL, 0,0);
1146     _coord_status.attach (*new Gtk::Label("Y:", 0.0, 0.5), 1,2, 1,2, Gtk::FILL,Gtk::FILL, 0,0);
1147     _coord_status_x.set_text ("0.0");
1148     _coord_status_x.set_alignment (0.0, 0.5);
1149     _coord_status_y.set_text ("0.0");
1150     _coord_status_y.set_alignment (0.0, 0.5);
1151     _coord_status.attach (_coord_status_x, 2,3, 0,1, Gtk::FILL,Gtk::FILL, 0,0);
1152     _coord_status.attach (_coord_status_y, 2,3, 1,2, Gtk::FILL,Gtk::FILL, 0,0);
1153     _coord_status.attach (*new Gtk::Label("Z:", 0.0, 0.5), 3,4, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1154     _coord_status.attach (_zoom_status, 4,5, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1155     sp_set_font_size_smaller (static_cast<GtkWidget*>((void*)_coord_status.gobj()));
1156     _statusbar.pack_end (_coord_eventbox, false, false, 1);
1158     _select_status.property_xalign() = 0.0;
1159     _select_status.property_yalign() = 0.5;
1160     _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."));
1161     // include this again with Gtk+-2.6
1162 #if GTK_VERSION_GE(2,6)
1163      gtk_label_set_ellipsize (GTK_LABEL(_select_status.gobj()), PANGO_ELLIPSIZE_END);
1164 #endif
1165     _select_status.set_size_request (1, -1);
1166     _statusbar.pack_start (_select_status, true, true, 0);
1168     _main_window_table.attach(_statusbar, 0, 1, 3, 4, Gtk::FILL, Gtk::SHRINK);
1171 //========================================
1172 //----------implements EditWidgetInterface
1174 void *
1175 EditWidget::getWindow()
1177     return this;
1180 void
1181 EditWidget::setTitle (gchar const* new_title)
1183     set_title (new_title);
1186 void
1187 EditWidget::layout()
1189    show_all_children();
1192 void
1193 EditWidget::present()
1195     this->Gtk::Window::present();
1198 void
1199 EditWidget::getGeometry (gint &x, gint &y, gint &w, gint &h)
1201     get_position (x, y);
1202     get_size (w, h);
1205 void
1206 EditWidget::setSize (gint w, gint h)
1208     resize (w, h);
1211 void
1212 EditWidget::setPosition (NR::Point p)
1214     move (int(p[NR::X]), int(p[NR::Y]));
1217 /// \param p is already gobj()!
1218 void
1219 EditWidget::setTransient (void* p, int i)
1221 #ifndef WIN32
1222     gtk_window_set_transient_for (static_cast<GtkWindow*>(p), this->gobj());
1223     if (i==2)
1224         this->Gtk::Window::present();
1225 #endif
1228 NR::Point
1229 EditWidget::getPointer()
1231     int x, y;
1232     get_pointer (x, y);
1233     return NR::Point (x, y);
1236 void
1237 EditWidget::setFullscreen()
1239     fullscreen();
1242 /**
1243  *  Shuts down the desktop object for the view being closed.  It checks
1244  *  to see if the document has been edited, and if so prompts the user
1245  *  to save, discard, or cancel.  Returns TRUE if the shutdown operation
1246  *  is cancelled or if the save is cancelled or fails, FALSE otherwise.
1247  */
1248 bool
1249 EditWidget::shutdown()
1251     g_assert (_desktop != NULL);
1252     if (Inkscape::NSApplication::Editor::isDuplicatedView (_desktop))
1253         return false;
1255     SPDocument *doc = _desktop->doc();
1256     if (sp_document_repr_root(doc)->attribute("sodipodi:modified") != NULL)
1257     {
1258         gchar *markup;
1259         /// \todo FIXME !!! obviously this will have problems if the document
1260         /// name contains markup characters
1261         markup = g_strdup_printf(
1262                 _("<span weight=\"bold\" size=\"larger\">Save changes to document \"%s\" before closing?</span>\n\n"
1263                   "If you close without saving, your changes will be discarded."),
1264                 SP_DOCUMENT_NAME(doc));
1266         Gtk::MessageDialog dlg (*this,
1267                        markup,
1268                        true,
1269                        Gtk::MESSAGE_WARNING,
1270                        Gtk::BUTTONS_NONE,
1271                        true);
1272         g_free(markup);
1273         Gtk::Button close_button (_("Close _without saving"), true);
1274         dlg.add_action_widget (close_button, Gtk::RESPONSE_NO);
1275         close_button.show();
1276         dlg.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1277         dlg.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_YES);
1278         dlg.set_default_response (Gtk::RESPONSE_YES);
1280         int response = dlg.run();
1281         switch (response)
1282         {
1283             case Gtk::RESPONSE_YES:
1284                 sp_document_ref(doc);
1285                 if (sp_file_save_document(doc)) {
1286                     sp_document_unref(doc);
1287                 } else { // save dialog cancelled or save failed
1288                     sp_document_unref(doc);
1289                     return TRUE;
1290                 }
1291                 break;
1292             case Gtk::RESPONSE_NO:
1293                 break;
1294             default: // cancel pressed, or dialog was closed
1295                 return TRUE;
1296                 break;
1297         }
1298     }
1300     /* Code to check data loss */
1301     bool allow_data_loss = FALSE;
1302     while (sp_document_repr_root(doc)->attribute("inkscape:dataloss") != NULL && allow_data_loss == FALSE)
1303     {
1304         gchar *markup;
1305         /// \todo FIXME !!! obviously this will have problems if the document
1306         /// name contains markup characters
1307         markup = g_strdup_printf(
1308                 _("<span weight=\"bold\" size=\"larger\">The file \"%s\" was saved with a format (%s) that may cause data loss!</span>\n\n"
1309                   "Do you want to save this file in another format?"),
1310                 SP_DOCUMENT_NAME(doc),
1311                 Inkscape::Extension::db.get(sp_document_repr_root(doc)->attribute("inkscape:output_extension"))->get_name());
1313         Gtk::MessageDialog dlg (*this,
1314                        markup,
1315                        true,
1316                        Gtk::MESSAGE_WARNING,
1317                        Gtk::BUTTONS_NONE,
1318                        true);
1319         g_free(markup);
1320         Gtk::Button close_button (_("Close _without saving"), true);
1321         dlg.add_action_widget (close_button, Gtk::RESPONSE_NO);
1322         close_button.show();
1323         dlg.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1324         dlg.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_YES);
1325         dlg.set_default_response (Gtk::RESPONSE_YES);
1327         int response = dlg.run();
1329         switch (response)
1330         {
1331             case Gtk::RESPONSE_YES:
1332                 sp_document_ref(doc);
1333                 if (sp_file_save_document(doc)) {
1334                     sp_document_unref(doc);
1335                 } else { // save dialog cancelled or save failed
1336                     sp_document_unref(doc);
1337                     return TRUE;
1338                 }
1339                 break;
1340             case Gtk::RESPONSE_NO:
1341                 allow_data_loss = TRUE;
1342                 break;
1343             default: // cancel pressed, or dialog was closed
1344                 return TRUE;
1345                 break;
1346         }
1347     }
1349     return false;
1353 void
1354 EditWidget::destroy()
1356     delete this;
1359 void
1360 EditWidget::requestCanvasUpdate()
1362     _svg_canvas.widget().queue_draw();
1365 void
1366 EditWidget::activateDesktop()
1368     /// \todo active_desktop_indicator not implemented
1371 void
1372 EditWidget::deactivateDesktop()
1374     /// \todo active_desktop_indicator not implemented
1377 void
1378 EditWidget::viewSetPosition (NR::Point p)
1380     p -= _namedview->gridorigin;
1381     double lo, up, pos, max;
1382     _top_ruler.get_range (lo, up, pos, max);
1383     _top_ruler.set_range (lo, up, p[NR::X], max);
1384     _left_ruler.get_range (lo, up, pos, max);
1385     _left_ruler.set_range (lo, up, p[NR::Y], max);
1388 void
1389 EditWidget::updateRulers()
1391     NR::Point origin = _namedview->gridorigin;
1393     NR::Rect const viewbox = _svg_canvas.spobj()->getViewbox();
1394     double lo, up, pos, max;
1395     double const scale = _desktop->current_zoom();
1396     double s = viewbox.min()[NR::X] / scale - origin[NR::X];
1397     double e = viewbox.max()[NR::X] / scale - origin[NR::X];
1398     _top_ruler.get_range(lo, up, pos, max);
1399     _top_ruler.set_range(s, e, pos, e);
1400     s = viewbox.min()[NR::Y] / -scale - origin[NR::Y];
1401     e = viewbox.max()[NR::Y] / -scale - origin[NR::Y];
1402     _left_ruler.set_range(s, e, origin[NR::Y], e);
1403     /// \todo is that correct?
1406 void
1407 EditWidget::updateScrollbars (double scale)
1409     // do not call this function before canvas has its size allocated
1410     if (!is_realized() || _update_s_f) {
1411         return;
1412     }
1414     _update_s_f = true;
1416     /* The desktop region we always show unconditionally */
1417     SPDocument *doc = _desktop->doc();
1418     NR::Rect const r = sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc)));
1419     NR::Rect darea(NR::Point(MIN(r.min()[NR::X], -sp_document_width(doc)),
1420                              MIN(r.min()[NR::Y], -sp_document_height(doc))),
1421                    NR::Point(MAX(r.max()[NR::X], 2 * sp_document_width(doc)),
1422                              MAX(r.max()[NR::Y], 2 * sp_document_height(doc))));
1424     /* Canvas region we always show unconditionally */
1425     NR::Rect carea(NR::Point(darea.min()[NR::X] * scale - 64,
1426                              darea.max()[NR::Y] * -scale - 64),
1427                    NR::Point(darea.max()[NR::X] * scale + 64,
1428                              darea.min()[NR::Y] * -scale + 64));
1430     NR::Rect const viewbox = _svg_canvas.spobj()->getViewbox();
1432     /* Viewbox is always included into scrollable region */
1433     carea = NR::Rect::union_bounds(carea, viewbox);
1435     Gtk::Adjustment *adj = _bottom_scrollbar.get_adjustment();
1436     adj->set_value(viewbox.min()[NR::X]);
1437     adj->set_lower(carea.min()[NR::X]);
1438     adj->set_upper(carea.max()[NR::X]);
1439     adj->set_page_increment(viewbox.dimensions()[NR::X]);
1440     adj->set_step_increment(0.1 * (viewbox.dimensions()[NR::X]));
1441     adj->set_page_size(viewbox.dimensions()[NR::X]);
1443     adj = _right_scrollbar.get_adjustment();
1444     adj->set_value(viewbox.min()[NR::Y]);
1445     adj->set_lower(carea.min()[NR::Y]);
1446     adj->set_upper(carea.max()[NR::Y]);
1447     adj->set_page_increment(viewbox.dimensions()[NR::Y]);
1448     adj->set_step_increment(0.1 * viewbox.dimensions()[NR::Y]);
1449     adj->set_page_size(viewbox.dimensions()[NR::Y]);
1451     _update_s_f = false;
1454 void
1455 EditWidget::toggleRulers()
1457     if (_top_ruler.is_visible())
1458     {
1459         _top_ruler.hide_all();
1460         _left_ruler.hide_all();
1461         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 0);
1462     } else {
1463         _top_ruler.show_all();
1464         _left_ruler.show_all();
1465         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 1);
1466     }
1469 void
1470 EditWidget::toggleScrollbars()
1472     if (_bottom_scrollbar.is_visible())
1473     {
1474         _bottom_scrollbar.hide_all();
1475         _right_scrollbar.hide_all();
1476         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 0);
1477     } else {
1478         _bottom_scrollbar.show_all();
1479         _right_scrollbar.show_all();
1480         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 1);
1481     }
1484 void
1485 EditWidget::updateZoom()
1487     _zoom_status.update();
1490 void
1491 EditWidget::letZoomGrabFocus()
1493     _zoom_status.grab_focus();
1496 void
1497 EditWidget::setToolboxFocusTo (const gchar *)
1499     /// \todo not implemented
1502 void
1503 EditWidget::setToolboxAdjustmentValue (const gchar *, double)
1505     /// \todo not implemented
1508 bool
1509 EditWidget::isToolboxButtonActive (gchar const*)
1511     /// \todo not implemented
1512     return true;
1515 void
1516 EditWidget::setCoordinateStatus (NR::Point p)
1518     gchar *cstr = g_strdup_printf ("%6.2f", _dt2r * p[NR::X]);
1519     _coord_status_x.property_label() = cstr;
1520     g_free (cstr);
1521     cstr = g_strdup_printf ("%6.2f", _dt2r * p[NR::Y]);
1522     _coord_status_y.property_label() = cstr;
1523     g_free (cstr);
1526 void
1527 EditWidget::setMessage (Inkscape::MessageType type, gchar const* msg)
1529     _select_status.set_markup (msg? msg : "");
1532 bool
1533 EditWidget::warnDialog (gchar* msg)
1535     Gtk::MessageDialog dlg (*this,
1536                        msg,
1537                        true,
1538                        Gtk::MESSAGE_WARNING,
1539                        Gtk::BUTTONS_YES_NO,
1540                        true);
1541     int r = dlg.run();
1542     return r == Gtk::RESPONSE_YES;
1546 /// \todo make this a member function when the signal is a sigc++ signal
1547 void _namedview_modified (SPNamedView* nv, guint flags, EditWidget* ew)
1549     if (flags & SP_OBJECT_MODIFIED_FLAG)
1550     {
1551         ew->_dt2r = 1.0 / nv->doc_units->unittobase;
1552         ew->_top_ruler.update_metric();
1553         ew->_left_ruler.update_metric();
1554         ew->_tooltips.set_tip (ew->_top_ruler, ew->_top_ruler.get_tip());
1555         ew->_tooltips.set_tip (ew->_left_ruler, ew->_left_ruler.get_tip());
1556         ew->updateRulers();
1557     }
1560 void
1561 EditWidget::initEdit (SPDocument *doc)
1563     _desktop = new SPDesktop();
1564     _desktop->registerEditWidget (this);
1566     _namedview = sp_document_namedview (doc, 0);
1567     _svg_canvas.init (_desktop);
1568     _desktop->init (_namedview, _svg_canvas.spobj());
1569     sp_namedview_window_from_document (_desktop);
1570     _dt2r = 1.0 / _namedview->doc_units->unittobase;
1572     /// \todo convert to sigc++ when SPObject hierarchy gets converted
1573     /* Listen on namedview modification */
1574     g_signal_connect (G_OBJECT (_desktop->namedview), "modified",
1575         G_CALLBACK (_namedview_modified), this);
1576     _layer_selector.setDesktop (_desktop);
1577     _selected_style_status.setDesktop (_desktop);
1579     Inkscape::NSApplication::Editor::addDesktop (_desktop);
1581     _zoom_status.init (_desktop);
1582     _top_ruler.init (_desktop, _svg_canvas.widget());
1583     _left_ruler.init (_desktop, _svg_canvas.widget());
1584     updateRulers();
1587 void
1588 EditWidget::destroyEdit()
1590     if (_desktop) {
1591         _layer_selector.unreference();
1592         Inkscape::NSApplication::Editor::removeDesktop (_desktop); // clears selection too
1593         sp_signal_disconnect_by_data (G_OBJECT (_desktop->namedview), this);
1594         _desktop->destroy();
1595         Inkscape::GC::release (_desktop);
1596         _desktop = 0;
1597     }
1600 //----------end of EditWidgetInterface implementation
1602 //----------start of other callbacks
1604 bool
1605 EditWidget::on_key_press_event (GdkEventKey* event)
1607     // this is the original code from helper/window.cpp
1609     unsigned int shortcut;
1610     shortcut = get_group0_keyval (event) |
1611                    ( event->state & GDK_SHIFT_MASK ?
1612                      SP_SHORTCUT_SHIFT_MASK : 0 ) |
1613                    ( event->state & GDK_CONTROL_MASK ?
1614                      SP_SHORTCUT_CONTROL_MASK : 0 ) |
1615                    ( event->state & GDK_MOD1_MASK ?
1616                      SP_SHORTCUT_ALT_MASK : 0 );
1617     return sp_shortcut_invoke (shortcut,
1618                              Inkscape::NSApplication::Editor::getActiveDesktop());
1621 bool
1622 EditWidget::on_delete_event (GdkEventAny*)
1624     return shutdown();
1627 bool
1628 EditWidget::on_focus_in_event (GdkEventFocus*)
1630     Inkscape::NSApplication::Editor::activateDesktop (_desktop);
1631     _svg_canvas.widget().grab_focus();
1633     return false;
1636 void
1637 EditWidget::onWindowSizeAllocate (Gtk::Allocation &newall)
1639     if (!is_realized()) return;
1641     const Gtk::Allocation& all = get_allocation();
1642     if ((newall.get_x() == all.get_x()) &&
1643         (newall.get_y() == all.get_y()) &&
1644         (newall.get_width() == all.get_width()) &&
1645         (newall.get_height() == all.get_height())) {
1646         return;
1647     }
1649     NR::Rect const area = _desktop->get_display_area();
1650     double zoom = _desktop->current_zoom();
1652     if (_sticky_zoom.get_active()) {
1653         /* Calculate zoom per pixel */
1654         double const zpsp = zoom / hypot(area.dimensions()[NR::X], area.dimensions()[NR::Y]);
1655         /* Find new visible area */
1656         NR::Rect const newarea = _desktop->get_display_area();
1657         /* Calculate adjusted zoom */
1658         zoom = zpsp * hypot(newarea.dimensions()[NR::X], newarea.dimensions()[NR::Y]);
1659     }
1661     _desktop->zoom_absolute(area.midpoint()[NR::X], area.midpoint()[NR::Y], zoom);
1664 void
1665 EditWidget::onWindowRealize()
1667     NR::Rect d(NR::Point(0, 0),
1668                NR::Point(sp_document_width(_desktop->doc()), sp_document_height(_desktop->doc())));
1670     if (fabs(d.dimensions()[NR::X]) < 1.0 || fabs(d.dimensions()[NR::Y]) < 1.0) {
1671         return;
1672     }
1674     _desktop->set_display_area(d.min()[NR::X], d.min()[NR::Y], d.max()[NR::X], d.max()[NR::Y], 10);
1675     _namedview_modified(_desktop->namedview, SP_OBJECT_MODIFIED_FLAG, this);
1676     setTitle (SP_DOCUMENT_NAME(_desktop->doc()));
1679 void
1680 EditWidget::onAdjValueChanged()
1682     if (_update_a_f) return;
1683     _update_a_f = true;
1685     sp_canvas_scroll_to (_svg_canvas.spobj(),
1686                          _bottom_scrollbar.get_value(),
1687                          _right_scrollbar.get_value(),
1688                          false);
1689     updateRulers();
1691     _update_a_f = false;
1695 } // namespace View
1696 } // namespace UI
1697 } // namespace Inkscape
1699 /*
1700   Local Variables:
1701   mode:c++
1702   c-file-style:"stroustrup"
1703   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1704   indent-tabs-mode:nil
1705   fill-column:99
1706   End:
1707 */
1708 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :