Code

Fix for bug LP #400985 (3 strings in UI are not translatable)
[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  *   John Bintz <jcoswell@coswellproductions.org>
20  *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
21  *
22  * Copyright (C) 2007 Johan Engelen
23  * Copyright (C) 2006 John Bintz
24  * Copyright (C) 1999-2005 Authors
25  * Copyright (C) 2000-2001 Ximian, Inc.
26  *
27  * Released under GNU GPL.  Read the file 'COPYING' for more information.
28  */
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
34 #include <gtk/gtkwindow.h>
35 #include <gtk/gtkversion.h>
36 #include <gtk/gtklabel.h>
37 #include <gtkmm/radioaction.h>
38 #include <gtkmm/menubar.h>
39 #include <gtkmm/messagedialog.h>
40 #include <gtkmm/stock.h>
41 #include <gtkmm/accelmap.h>
42 #include <gtkmm/separator.h>
43 #include <gtkmm/base.h>
45 #include <sigc++/functors/mem_fun.h>
47 #include "macros.h"
48 #include "path-prefix.h"
49 #include "preferences.h"
50 #include "file.h"
51 #include "application/editor.h"
52 #include "edit-widget.h"
54 #include "display/sodipodi-ctrlrect.h"
55 #include "helper/units.h"
56 #include "shortcuts.h"
57 #include "widgets/spw-utilities.h"
58 #include "event-context.h"
59 #include "document.h"
60 #include "sp-namedview.h"
61 #include "sp-item.h"
62 #include "interface.h"
63 #include "extension/db.h"
65 #include "ui/dialog/dialog-manager.h"
67 using namespace Inkscape::UI;
68 using namespace Inkscape::UI::Widget;
70 namespace Inkscape {
71 namespace UI {
72 namespace View {
74 EditWidget::EditWidget (SPDocument *doc)
75     : _main_window_table(4),
76       _viewport_table(3,3),
77       _act_grp(Gtk::ActionGroup::create()),
78       _ui_mgr(Gtk::UIManager::create()),
79       _update_s_f(false),
80       _update_a_f(false),
81       _interaction_disabled_counter(0)
82 {
83     g_warning("Creating new EditWidget");
85     _desktop = 0;
86     initActions();
87     initAccelMap();
88     initUIManager();
89     initLayout();
90     initEdit (doc);
91     g_warning("Done creating new EditWidget");
92 }
94 EditWidget::~EditWidget()
95 {
96     destroyEdit();
97 }
99 void
100 EditWidget::initActions()
102     initMenuActions();
103     initToolbarActions();
106 void
107 EditWidget::initUIManager()
109     _ui_mgr->insert_action_group(_act_grp);
110     add_accel_group(_ui_mgr->get_accel_group());
112     gchar *filename_utf8 = g_build_filename(INKSCAPE_UIDIR, "menus-bars.xml", NULL);
113     if (_ui_mgr->add_ui_from_file(filename_utf8) == 0) {
114         g_warning("Error merging ui from file '%s'", filename_utf8);
115         // fixme-charset: What charset should we pass to g_warning?
116     }
117     g_free(filename_utf8);
120 void
121 EditWidget::initLayout()
123     set_title("New document 1 - Inkscape");
124     set_resizable();
125     set_default_size(640, 480);
127     // top level window into which all other portions of the UI get inserted
128     add(_main_window_table);
129     // attach box for horizontal toolbars
130     _main_window_table.attach(_toolbars_vbox, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
131     // attach sub-window for viewport and vertical toolbars
132     _main_window_table.attach(_sub_window_hbox, 0, 1, 2, 3);
133     // viewport table with 3 rows by 3 columns
134     _sub_window_hbox.pack_end(_viewport_table);
136     // Menus and Bars
137     initMenuBar();
138     initCommandsBar();
139     initToolControlsBar();
140     initUriBar();
141     initToolsBar();
143     // Canvas Viewport
144     initLeftRuler();
145     initTopRuler();
146     initStickyZoom();
147     initBottomScrollbar();
148     initRightScrollbar();
149     _viewport_table.attach(_svg_canvas.widget(), 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
150     _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 (*this, 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 void
303 EditWidget::onUriChanged()
305     g_message("onUriChanged called");
309 // FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled
310 // See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details
312 void
313 EditWidget::initMenuActions()
315 // This has no chance of working right now.
316 // Has to be converted to Gtk::Action::create_with_icon_name.
318     _act_grp->add(Gtk::Action::create("MenuFile",   "File"));
319     _act_grp->add(Gtk::Action::create("MenuEdit",   "Edit"));
320     _act_grp->add(Gtk::Action::create("MenuView",   "View"));
321     _act_grp->add(Gtk::Action::create("MenuLayer",  "Layer"));
322     _act_grp->add(Gtk::Action::create("MenuObject", "Object"));
323     _act_grp->add(Gtk::Action::create("MenuPath",   "Path"));
324     _act_grp->add(Gtk::Action::create("MenuText",   "Text"));
325     _act_grp->add(Gtk::Action::create("MenuHelp",   "Help"));
327     // File menu
328     _act_grp->add(Gtk::Action::create("New",
329                                       Gtk::Stock::NEW, Glib::ustring(),
330                                       _("PLACEHOLDER, do not translate")),
331                   sigc::mem_fun(*this, &EditWidget::onActionFileNew));
333     _act_grp->add(Gtk::Action::create("Open",
334                                       Gtk::Stock::OPEN, Glib::ustring(),
335                                       _("PLACEHOLDER, do not translate")),
336                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
337 /*
338     _act_grp->add(Gtk::Action::create("OpenRecent",
339                                       Stock::OPEN_RECENT));*/
341     _act_grp->add(Gtk::Action::create("Revert",
342                                       Gtk::Stock::REVERT_TO_SAVED, Glib::ustring(),
343                                       _("PLACEHOLDER, do not translate")),
344                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
346     _act_grp->add(Gtk::Action::create("Save",
347                                       Gtk::Stock::SAVE, Glib::ustring(),
348                                       _("PLACEHOLDER, do not translate")),
349                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
351     _act_grp->add(Gtk::Action::create("SaveAs",
352                                       Gtk::Stock::SAVE_AS, Glib::ustring(),
353                                       _("PLACEHOLDER, do not translate")),
354                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
355 /*
356     _act_grp->add(Gtk::Action::create("Import",
357                                       Stock::IMPORT, Glib::ustring(),
358                                       _("PLACEHOLDER, do not translate")),
359                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
361     _act_grp->add(Gtk::Action::create("Export",
362                                       Stock::EXPORT, Glib::ustring(),
363                                       _("PLACEHOLDER, do not translate")),
364                   sigc::mem_fun(*this, &EditWidget::onDialogExport));*/
366     _act_grp->add(Gtk::Action::create("Print",
367                                       Gtk::Stock::PRINT, Glib::ustring(),
368                                       _("PLACEHOLDER, do not translate")),
369                   sigc::mem_fun(*this, &EditWidget::onActionFilePrint));
371     _act_grp->add(Gtk::Action::create("PrintPreview",
372                                       Gtk::Stock::PRINT_PREVIEW),
373                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
374 /*
375     _act_grp->add(Gtk::Action::create("VacuumDefs",
376                                       Stock::VACUUM_DEFS),
377                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));*/
379     _act_grp->add(Gtk::Action::create("DocumentProperties",
380                                       Gtk::Stock::PROPERTIES, Glib::ustring(),
381                                       _("PLACEHOLDER, do not translate")),
382                   sigc::mem_fun(*this, &EditWidget::onDialogDocumentProperties));
384     _act_grp->add(Gtk::Action::create("InkscapePreferences",
385                                       Gtk::Stock::PREFERENCES, Glib::ustring(),
386                                       _("PLACEHOLDER, do not translate")),
387                   sigc::mem_fun(*this, &EditWidget::onDialogInkscapePreferences));
389     _act_grp->add(Gtk::Action::create("Close",
390                                       Gtk::Stock::CLOSE),
391                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
393     _act_grp->add(Gtk::Action::create("Quit",
394                                       Gtk::Stock::QUIT),
395                   sigc::mem_fun(*this, &EditWidget::onActionFileQuit));
397     // EditWidget menu
398     _act_grp->add(Gtk::Action::create("Undo",
399                                       Gtk::Stock::UNDO, Glib::ustring(),
400                                       _("PLACEHOLDER, do not translate")));
402     _act_grp->add(Gtk::Action::create("Redo",
403                                       Gtk::Stock::REDO, Glib::ustring(),
404                                       _("PLACEHOLDER, do not translate")));
405 /*
406     _act_grp->add(Gtk::Action::create("UndoHistory",
407                                       Stock::UNDO_HISTORY, Glib::ustring(),
408                                       _("PLACEHOLDER, do not translate")));*/
410     _act_grp->add(Gtk::Action::create("Cut",
411                                       Gtk::Stock::CUT, Glib::ustring(),
412                                       _("PLACEHOLDER, do not translate")));
414     _act_grp->add(Gtk::Action::create("Copy",
415                                       Gtk::Stock::COPY, Glib::ustring(),
416                                       _("PLACEHOLDER, do not translate")));
418     _act_grp->add(Gtk::Action::create("Paste",
419                                       Gtk::Stock::PASTE, Glib::ustring(),
420                                       _("PLACEHOLDER, do not translate")));
421 /*
422     _act_grp->add(Gtk::Action::create("PasteInPlace",
423                                       Stock::PASTE_IN_PLACE));
425     _act_grp->add(Gtk::Action::create("PasteStyle",
426                                       Stock::PASTE_STYLE));*/
428     _act_grp->add(Gtk::Action::create("Find",
429                                       Gtk::Stock::FIND),
430                   sigc::mem_fun(*this, &EditWidget::onDialogFind));
431 /*
432     _act_grp->add(Gtk::Action::create("Duplicate",
433                                       Stock::DUPLICATE, Glib::ustring(),
434                                       _("PLACEHOLDER, do not translate")));
436     _act_grp->add(Gtk::Action::create("Clone",
437                                       Stock::CLONE, Glib::ustring(),
438                                       _("PLACEHOLDER, do not translate")));
440     _act_grp->add(Gtk::Action::create("CloneUnlink",
441                                       Stock::CLONE_UNLINK, Glib::ustring(),
442                                       _("PLACEHOLDER, do not translate")));
444     _act_grp->add(Gtk::Action::create("CloneSelectOrig",
445                                       Stock::CLONE_SELECT_ORIG));
447     _act_grp->add(Gtk::Action::create("MakeBitmap",
448                                       Stock::MAKE_BITMAP));
450     _act_grp->add(Gtk::Action::create("Tile",
451                                      Stock::TILE));
453     _act_grp->add(Gtk::Action::create("Untile",
454                                       Stock::UNTILE));
456     _act_grp->add(Gtk::Action::create("Delete",
457                                       Gtk::Stock::DELETE));
459     _act_grp->add(Gtk::Action::create("SelectAll",
460                                       Stock::SELECT_ALL));
462     _act_grp->add(Gtk::Action::create("SelectAllInAllLayers",
463                                       Stock::SELECT_ALL_IN_ALL_LAYERS));
465     _act_grp->add(Gtk::Action::create("SelectInvert",
466                                       Stock::SELECT_INVERT));
468     _act_grp->add(Gtk::Action::create("SelectNone",
469                                       Stock::SELECT_NONE));
471     _act_grp->add(Gtk::Action::create("XmlEditor",
472                                       Stock::XML_EDITOR, Glib::ustring(),
473                                       _("PLACEHOLDER, do not translate")),
474                   sigc::mem_fun(*this, &EditWidget::onDialogXmlEditor));
476     // View menu
477     _act_grp->add(Gtk::Action::create("Zoom",
478                                       Stock::ZOOM));
480     _act_grp->add(Gtk::Action::create("ZoomIn",
481                                       Stock::ZOOM_IN, Glib::ustring(),
482                                       _("PLACEHOLDER, do not translate")));
484     _act_grp->add(Gtk::Action::create("ZoomOut",
485                                       Stock::ZOOM_OUT, Glib::ustring(),
486                                       _("PLACEHOLDER, do not translate")));
488     _act_grp->add(Gtk::Action::create("Zoom100",
489                                       Stock::ZOOM_100, Glib::ustring(),
490                                       _("PLACEHOLDER, do not translate")));
492     _act_grp->add(Gtk::Action::create("Zoom50",
493                                       Stock::ZOOM_50, Glib::ustring(),
494                                       _("PLACEHOLDER, do not translate")));
496     _act_grp->add(Gtk::Action::create("Zoom200",
497                                       Stock::ZOOM_200, Glib::ustring(),
498                                       _("PLACEHOLDER, do not translate")));
500     _act_grp->add(Gtk::Action::create("ZoomSelection",
501                                       Stock::ZOOM_SELECTION, Glib::ustring(),
502                                       _("PLACEHOLDER, do not translate")));
504     _act_grp->add(Gtk::Action::create("ZoomDrawing",
505                                       Stock::ZOOM_DRAWING, Glib::ustring(),
506                                       _("PLACEHOLDER, do not translate")));
508     _act_grp->add(Gtk::Action::create("ZoomPage",
509                                       Stock::ZOOM_PAGE, Glib::ustring(),
510                                       _("PLACEHOLDER, do not translate")));
512     _act_grp->add(Gtk::Action::create("ZoomWidth",
513                                       Stock::ZOOM_WIDTH, Glib::ustring(),
514                                       _("PLACEHOLDER, do not translate")));
516     _act_grp->add(Gtk::Action::create("ZoomPrev",
517                                       Stock::ZOOM_PREV, Glib::ustring(),
518                                       _("PLACEHOLDER, do not translate")));
520     _act_grp->add(Gtk::Action::create("ZoomNext",
521                                       Stock::ZOOM_NEXT, Glib::ustring(),
522                                       _("PLACEHOLDER, do not translate")));
524     _act_grp->add(Gtk::Action::create("ShowHide",
525                                       Stock::SHOW_HIDE));
527     _act_grp->add(Gtk::ToggleAction::create("ShowHideCommandsBar",
528                                             Stock::SHOW_HIDE_COMMANDS_BAR));
530     _act_grp->add(Gtk::ToggleAction::create("ShowHideToolControlsBar",
531                                             Stock::SHOW_HIDE_TOOL_CONTROLS_BAR));
533     _act_grp->add(Gtk::ToggleAction::create("ShowHideToolsBar",
534                                             Stock::SHOW_HIDE_TOOLS_BAR));
536     _act_grp->add(Gtk::ToggleAction::create("ShowHideRulers",
537                                             Stock::SHOW_HIDE_RULERS));
539     _act_grp->add(Gtk::ToggleAction::create("ShowHideScrollbars",
540                                             Stock::SHOW_HIDE_SCROLLBARS));
542     _act_grp->add(Gtk::ToggleAction::create("ShowHideStatusbar",
543                                             Stock::SHOW_HIDE_STATUSBAR));
545     _act_grp->add(Gtk::Action::create("ShowHideDialogs",
546                                       Stock::SHOW_HIDE_DIALOGS));
548     _act_grp->add(Gtk::Action::create("Grid",
549                                       Stock::GRID));
551     _act_grp->add(Gtk::Action::create("Guides",
552                                       Stock::GUIDES));
554     _act_grp->add(Gtk::Action::create("Fullscreen",
555                                       Stock::FULLSCREEN));
557     _act_grp->add(Gtk::Action::create("Messages",
558                                       Stock::MESSAGES),
559                   sigc::mem_fun(*this, &EditWidget::onDialogMessages));
561     _act_grp->add(Gtk::Action::create("Scripts",
562                                       Stock::SCRIPTS));
564     _act_grp->add(Gtk::Action::create("WindowPrev",
565                                       Stock::WINDOW_PREV));
567     _act_grp->add(Gtk::Action::create("WindowNext",
568                                       Stock::WINDOW_NEXT));
570     _act_grp->add(Gtk::Action::create("WindowDuplicate",
571                                       Stock::WINDOW_DUPLICATE));
573     // Layer menu
574     _act_grp->add(Gtk::Action::create("LayerNew",
575                                       Stock::LAYER_NEW));
577     _act_grp->add(Gtk::Action::create("LayerRename",
578                                       Stock::LAYER_RENAME));
580     _act_grp->add(Gtk::Action::create("LayerDuplicate",
581                                       Stock::LAYER_DUPLICATE));
583     _act_grp->add(Gtk::Action::create("LayerAnchor",
584                                       Stock::LAYER_ANCHOR));
586     _act_grp->add(Gtk::Action::create("LayerMergeDown",
587                                       Stock::LAYER_MERGE_DOWN));
589     _act_grp->add(Gtk::Action::create("LayerDelete",
590                                       Stock::LAYER_DELETE));
592     _act_grp->add(Gtk::Action::create("LayerSelectNext",
593                                       Stock::LAYER_SELECT_NEXT));
595     _act_grp->add(Gtk::Action::create("LayerSelectPrev",
596                                       Stock::LAYER_SELECT_PREV));
598     _act_grp->add(Gtk::Action::create("LayerSelectTop",
599                                       Stock::LAYER_SELECT_TOP));
601     _act_grp->add(Gtk::Action::create("LayerSelectBottom",
602                                       Stock::LAYER_SELECT_BOTTOM));
604     _act_grp->add(Gtk::Action::create("LayerRaise",
605                                       Stock::LAYER_RAISE));
607     _act_grp->add(Gtk::Action::create("LayerLower",
608                                       Stock::LAYER_LOWER));
610     _act_grp->add(Gtk::Action::create("LayerToTop",
611                                       Stock::LAYER_TO_TOP));
613     _act_grp->add(Gtk::Action::create("LayerToBottom",
614                                       Stock::LAYER_TO_BOTTOM));
616     // Object menu
617     _act_grp->add(Gtk::Action::create("FillAndStroke",
618                                       Stock::FILL_STROKE, Glib::ustring(),
619                                       _("PLACEHOLDER, do not translate")),
620                   sigc::mem_fun(*this, &EditWidget::onDialogFillAndStroke));
622     _act_grp->add(Gtk::Action::create("ObjectProperties",
623                                       Stock::OBJECT_PROPERTIES),
624                   sigc::mem_fun(*this, &EditWidget::onDialogObjectProperties));
626     _act_grp->add(Gtk::Action::create("FilterEffects",
627                                       Stock::FILTER_EFFECTS));
629     _act_grp->add(Gtk::Action::create("Group",
630                                       Stock::GROUP, Glib::ustring(),
631                                       _("PLACEHOLDER, do not translate")));
633     _act_grp->add(Gtk::Action::create("Ungroup",
634                                       Stock::UNGROUP, Glib::ustring(),
635                                       _("PLACEHOLDER, do not translate")));
637     _act_grp->add(Gtk::Action::create("Raise",
638                                       Stock::RAISE, Glib::ustring(),
639                                       _("PLACEHOLDER, do not translate")));
641     _act_grp->add(Gtk::Action::create("Lower",
642                                       Stock::LOWER, Glib::ustring(),
643                                       _("PLACEHOLDER, do not translate")));
645     _act_grp->add(Gtk::Action::create("RaiseToTop",
646                                       Stock::RAISE_TO_TOP, Glib::ustring(),
647                                       _("PLACEHOLDER, do not translate")));
649     _act_grp->add(Gtk::Action::create("LowerToBottom",
650                                       Stock::LOWER_TO_BOTTOM, Glib::ustring(),
651                                       _("PLACEHOLDER, do not translate")));
653     _act_grp->add(Gtk::Action::create("MoveToNewLayer",
654                                       Stock::MOVE_TO_NEW_LAYER, Glib::ustring(),
655                                       _("PLACEHOLDER, do not translate")));
657     _act_grp->add(Gtk::Action::create("MoveToNextLayer",
658                                       Stock::MOVE_TO_NEXT_LAYER, Glib::ustring(),
659                                       _("PLACEHOLDER, do not translate")));
661     _act_grp->add(Gtk::Action::create("MoveToPrevLayer",
662                                       Stock::MOVE_TO_PREV_LAYER, Glib::ustring(),
663                                       _("PLACEHOLDER, do not translate")));
665     _act_grp->add(Gtk::Action::create("MoveToTopLayer",
666                                       Stock::MOVE_TO_TOP_LAYER, Glib::ustring(),
667                                       _("PLACEHOLDER, do not translate")));
669     _act_grp->add(Gtk::Action::create("MoveToBottomLayer",
670                                       Stock::MOVE_TO_BOTTOM_LAYER, Glib::ustring(),
671                                       _("PLACEHOLDER, do not translate")));
673     _act_grp->add(Gtk::Action::create("Rotate90CW",
674                                       Stock::ROTATE_90_CW, Glib::ustring(),
675                                       _("PLACEHOLDER, do not translate")));
677     _act_grp->add(Gtk::Action::create("Rotate90CCW",
678                                       Stock::ROTATE_90_CCW, Glib::ustring(),
679                                       _("PLACEHOLDER, do not translate")));
681     _act_grp->add(Gtk::Action::create("FlipHoriz",
682                                       Stock::FLIP_HORIZ, Glib::ustring(),
683                                       _("PLACEHOLDER, do not translate")));
685     _act_grp->add(Gtk::Action::create("FlipVert",
686                                       Stock::FLIP_VERT, Glib::ustring(),
687                                       _("PLACEHOLDER, do not translate")));
689     _act_grp->add(Gtk::Action::create("Transformation",
690                                       Stock::TRANSFORMATION, Glib::ustring(),
691                                       _("PLACEHOLDER, do not translate")),
692                   sigc::mem_fun(*this, &EditWidget::onDialogTransformation));
694     _act_grp->add(Gtk::Action::create("AlignAndDistribute",
695                                       Stock::ALIGN_DISTRIBUTE, Glib::ustring(),
696                                       _("PLACEHOLDER, do not translate")),
697                   sigc::mem_fun(*this, &EditWidget::onDialogAlignAndDistribute));
699     // Path menu
700     _act_grp->add(Gtk::Action::create("ObjectToPath",
701                                       Stock::OBJECT_TO_PATH, Glib::ustring(),
702                                       _("PLACEHOLDER, do not translate")));
704     _act_grp->add(Gtk::Action::create("StrokeToPath",
705                                       Stock::STROKE_TO_PATH, Glib::ustring(),
706                                       _("PLACEHOLDER, do not translate")));
708     _act_grp->add(Gtk::Action::create("Trace",
709                                       Stock::TRACE),
710                   sigc::mem_fun(*this, &EditWidget::onDialogTrace));
712     _act_grp->add(Gtk::Action::create("Union",
713                                       Stock::UNION));
715     _act_grp->add(Gtk::Action::create("Difference",
716                                       Stock::DIFFERENCE));
718     _act_grp->add(Gtk::Action::create("Intersection",
719                                       Stock::INTERSECTION));
721     _act_grp->add(Gtk::Action::create("Exclusion",
722                                       Stock::EXCLUSION));
724     _act_grp->add(Gtk::Action::create("Division",
725                                       Stock::DIVISION));
727     _act_grp->add(Gtk::Action::create("CutPath",
728                                       Stock::CUT_PATH));
730     _act_grp->add(Gtk::Action::create("Combine",
731                                       Stock::COMBINE));
733     _act_grp->add(Gtk::Action::create("BreakApart",
734                                       Stock::BREAK_APART));
736     _act_grp->add(Gtk::Action::create("Inset",
737                                       Stock::INSET));
739     _act_grp->add(Gtk::Action::create("Outset",
740                                       Stock::OUTSET));
742     _act_grp->add(Gtk::Action::create("OffsetDynamic",
743                                       Stock::OFFSET_DYNAMIC));
745     _act_grp->add(Gtk::Action::create("OffsetLinked",
746                                       Stock::OFFSET_LINKED));
748     _act_grp->add(Gtk::Action::create("Simplify",
749                                       Stock::SIMPLIFY));
751     _act_grp->add(Gtk::Action::create("Reverse",
752                                       Stock::REVERSE));*/
754     _act_grp->add(Gtk::Action::create("Cleanup",
755                                       Gtk::Stock::CLEAR,
756                                       _("PLACEHOLDER, do not translate")));
758     // Text menu
759     _act_grp->add(Gtk::Action::create("TextProperties",
760                                       Gtk::Stock::SELECT_FONT, Glib::ustring(),
761                                       _("PLACEHOLDER, do not translate")),
762                   sigc::mem_fun(*this, &EditWidget::onDialogTextProperties));
763 /*
764     _act_grp->add(Gtk::Action::create("PutOnPath",
765                                       Stock::PUT_ON_PATH));
767     _act_grp->add(Gtk::Action::create("RemoveFromPath",
768                                       Stock::REMOVE_FROM_PATH));
770     _act_grp->add(Gtk::Action::create("RemoveManualKerns",
771                                       Stock::REMOVE_MANUAL_KERNS));*/
773         // Whiteboard menu
774 #ifdef WITH_INKBOARD
775 #endif
777     // About menu
778 /*
779     _act_grp->add(Gtk::Action::create("KeysAndMouse",
780                                       Stock::KEYS_MOUSE));
782     _act_grp->add(Gtk::Action::create("Tutorials",
783                                       Stock::TUTORIALS));
785     _act_grp->add(Gtk::Action::create("About",
786                                       Stock::ABOUT),
787                   sigc::mem_fun(*this, &EditWidget::onDialogAbout));*/
790 void
791 EditWidget::initToolbarActions()
793     // Tools bar
794     // This has zero chance to work, and has to be converted to create_with_icon_name
795     Gtk::RadioAction::Group tools;
796 /*
797     _act_grp->add(Gtk::RadioAction::create(tools, "ToolSelect",
798                                            Stock::TOOL_SELECT, Glib::ustring(),
799                                            _("PLACEHOLDER, do not translate")),
800                   sigc::mem_fun(*this, &EditWidget::onSelectTool));
802     _act_grp->add(Gtk::RadioAction::create(tools, "ToolNode",
803                                            Stock::TOOL_NODE, Glib::ustring(),
804                                            _("PLACEHOLDER, do not translate")),
805                   sigc::mem_fun(*this, &EditWidget::onNodeTool));
807     _act_grp->add(Gtk::RadioAction::create(tools, "ToolZoom",
808                                            Stock::TOOL_ZOOM, Glib::ustring(),
809                                            _("PLACEHOLDER, do not translate")));
811     _act_grp->add(Gtk::RadioAction::create(tools, "ToolRect",
812                                            Stock::TOOL_RECT, Glib::ustring(),
813                                            _("PLACEHOLDER, do not translate")));
815     _act_grp->add(Gtk::RadioAction::create(tools, "ToolArc",
816                                            Stock::TOOL_ARC, Glib::ustring(),
817                                            _("PLACEHOLDER, do not translate")));
819     _act_grp->add(Gtk::RadioAction::create(tools, "ToolStar",
820                                            Stock::TOOL_STAR, Glib::ustring(),
821                                            _("PLACEHOLDER, do not translate")));
823     _act_grp->add(Gtk::RadioAction::create(tools, "ToolSpiral",
824                                            Stock::TOOL_SPIRAL, Glib::ustring(),
825                                            _("PLACEHOLDER, do not translate")));
827     _act_grp->add(Gtk::RadioAction::create(tools, "ToolFreehand",
828                                            Stock::TOOL_FREEHAND, Glib::ustring(),
829                                            _("PLACEHOLDER, do not translate")));
831     _act_grp->add(Gtk::RadioAction::create(tools, "ToolPen",
832                                            Stock::TOOL_PEN, Glib::ustring(),
833                                            _("PLACEHOLDER, do not translate")));
835     _act_grp->add(Gtk::RadioAction::create(tools, "ToolDynaDraw",
836                                            Stock::TOOL_DYNADRAW, Glib::ustring(),
837                                            _("PLACEHOLDER, do not translate")));
839     _act_grp->add(Gtk::RadioAction::create(tools, "ToolText",
840                                            Stock::TOOL_TEXT, Glib::ustring(),
841                                            _("PLACEHOLDER, do not translate")));
843     _act_grp->add(Gtk::RadioAction::create(tools, "ToolDropper",
844                                            Stock::TOOL_DROPPER, Glib::ustring(),
845                                            _("PLACEHOLDER, do not translate")));
847     // Select Controls bar
848     _act_grp->add(Gtk::ToggleAction::create("TransformStroke",
849                                             Stock::TRANSFORM_STROKE, Glib::ustring(),
850                                             _("PLACEHOLDER, do not translate")));
852     _act_grp->add(Gtk::ToggleAction::create("TransformCorners",
853                                             Stock::TRANSFORM_CORNERS, Glib::ustring(),
854                                             _("PLACEHOLDER, do not translate")));
856     _act_grp->add(Gtk::ToggleAction::create("TransformGradient",
857                                             Stock::TRANSFORM_GRADIENT, Glib::ustring(),
858                                             _("PLACEHOLDER, do not translate")));
860     _act_grp->add(Gtk::ToggleAction::create("TransformPattern",
861                                             Stock::TRANSFORM_PATTERN, Glib::ustring(),
862                                             _("PLACEHOLDER, do not translate")));*/
864     // Node Controls bar
865     _act_grp->add(Gtk::Action::create("NodeInsert",
866                                       Gtk::Stock::ADD, Glib::ustring(),
867                                       _("PLACEHOLDER, do not translate")));
869     _act_grp->add(Gtk::Action::create("NodeDelete",
870                                       Gtk::Stock::REMOVE, Glib::ustring(),
871                                       _("PLACEHOLDER, do not translate")));
872 /*
873     _act_grp->add(Gtk::Action::create("NodeJoin",
874                                       Stock::NODE_JOIN, Glib::ustring(),
875                                       _("PLACEHOLDER, do not translate")));
877     _act_grp->add(Gtk::Action::create("NodeJoinSegment",
878                                       Stock::NODE_JOIN_SEGMENT, Glib::ustring(),
879                                       _("PLACEHOLDER, do not translate")));
881     _act_grp->add(Gtk::Action::create("NodeDeleteSegment",
882                                       Stock::NODE_DELETE_SEGMENT, Glib::ustring(),
883                                       _("PLACEHOLDER, do not translate")));
885     _act_grp->add(Gtk::Action::create("NodeBreak",
886                                       Stock::NODE_BREAK, Glib::ustring(),
887                                       _("PLACEHOLDER, do not translate")));
889     _act_grp->add(Gtk::Action::create("NodeCorner",
890                                       Stock::NODE_CORNER, Glib::ustring(),
891                                       _("PLACEHOLDER, do not translate")));
893     _act_grp->add(Gtk::Action::create("NodeSmooth",
894                                       Stock::NODE_SMOOTH, Glib::ustring(),
895                                       _("PLACEHOLDER, do not translate")));
897     _act_grp->add(Gtk::Action::create("NodeSymmetric",
898                                       Stock::NODE_SYMMETRIC, Glib::ustring(),
899                                       _("PLACEHOLDER, do not translate")));
901     _act_grp->add(Gtk::Action::create("NodeLine",
902                                       Stock::NODE_LINE, Glib::ustring(),
903                                       _("PLACEHOLDER, do not translate")));
905     _act_grp->add(Gtk::Action::create("NodeCurve",
906                                       Stock::NODE_CURVE, Glib::ustring(),
907                                       _("PLACEHOLDER, do not translate")));*/
910 void
911 EditWidget::initAccelMap()
913     gchar *filename = g_build_filename(INKSCAPE_UIDIR, "keybindings.rc", NULL);
914     Gtk::AccelMap::load(filename);
915     g_free(filename);
917     // One problem is that the keys 1-6 are zoom accelerators which get
918     // caught as accelerator _before_ any Entry input handler receives them,
919     // for example the zoom status. At the moment, the best way seems to
920     // disable them as accelerators when the Entry gets focus, and enable
921     // them when focus goes elsewhere. The code for this belongs here,
922     // and not in zoom-status.cpp .
924     _zoom_status.signal_focus_in_event().connect (sigc::mem_fun (*this, &EditWidget::onEntryFocusIn));
925     _zoom_status.signal_focus_out_event().connect (sigc::mem_fun (*this, &EditWidget::onEntryFocusOut));
928 bool
929 EditWidget::onEntryFocusIn (GdkEventFocus* /*ev*/)
931     Gdk::ModifierType m = static_cast<Gdk::ModifierType>(0);
932     Gtk::AccelMap::change_entry ("<Actions>//Zoom100", 0, m, false);
933     Gtk::AccelMap::change_entry ("<Actions>//Zoom50", 0, m, false);
934     Gtk::AccelMap::change_entry ("<Actions>//ZoomSelection", 0, m, false);
935     Gtk::AccelMap::change_entry ("<Actions>//ZoomDrawing", 0, m, false);
936     Gtk::AccelMap::change_entry ("<Actions>//ZoomPage", 0, m, false);
937     Gtk::AccelMap::change_entry ("<Actions>//ZoomWidth", 0, m, false);
938     return false;
941 bool
942 EditWidget::onEntryFocusOut (GdkEventFocus* /*ev*/)
944     Gdk::ModifierType m = static_cast<Gdk::ModifierType>(0);
945     Gtk::AccelMap::change_entry ("<Actions>//Zoom100", '1', m, false);
946     Gtk::AccelMap::change_entry ("<Actions>//Zoom50", '2', m, false);
947     Gtk::AccelMap::change_entry ("<Actions>//ZoomSelection", '3', m, false);
948     Gtk::AccelMap::change_entry ("<Actions>//ZoomDrawing", '4', m, false);
949     Gtk::AccelMap::change_entry ("<Actions>//ZoomPage", '5', m, false);
950     Gtk::AccelMap::change_entry ("<Actions>//ZoomWidth", '6', m, false);
951     return false;
954 void
955 EditWidget::initMenuBar()
957     g_assert(_ui_mgr);
958     Gtk::MenuBar *menu = static_cast<Gtk::MenuBar*>(_ui_mgr->get_widget("/MenuBar"));
959     g_assert(menu != NULL);
960     _main_window_table.attach(*Gtk::manage(menu), 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
963 void
964 EditWidget::initCommandsBar()
966     g_assert(_ui_mgr);
967     Toolbox *bar = new Toolbox(static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/CommandsBar")),
968                                Gtk::TOOLBAR_ICONS);
969     g_assert(bar != NULL);
970     _toolbars_vbox.pack_start(*Gtk::manage(bar), Gtk::PACK_SHRINK);
973 void
974 EditWidget::initToolControlsBar()
976     // TODO: Do UIManager controlled widgets need to be deleted?
977     _select_ctrl = static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/SelectControlsBar"));
978     _node_ctrl = static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/NodeControlsBar"));
980     _tool_ctrl = new Toolbox(_select_ctrl, Gtk::TOOLBAR_ICONS);
982     _toolbars_vbox.pack_start(*Gtk::manage(_tool_ctrl), Gtk::PACK_SHRINK);
985 void
986 EditWidget::initUriBar()
988     /// \todo  Create an Inkscape::UI::Widget::UriBar class (?)
990     _uri_ctrl = new Gtk::Toolbar();
992     _uri_label.set_label(_("PLACEHOLDER, do not translate"));
993     _uri_ctrl->add(_uri_label);
994     _uri_ctrl->add(_uri_entry);
996     _uri_entry.signal_activate()
997         .connect_notify(sigc::mem_fun(*this, &EditWidget::onUriChanged));
999     _toolbars_vbox.pack_start(*Gtk::manage(_uri_ctrl), Gtk::PACK_SHRINK);
1002 void
1003 EditWidget::initToolsBar()
1005     Toolbox *bar = new Toolbox(static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/ToolsBar")),
1006                                Gtk::TOOLBAR_ICONS,
1007                                Gtk::ORIENTATION_VERTICAL);
1008     g_assert(bar != NULL);
1009     _sub_window_hbox.pack_start(*Gtk::manage(bar), Gtk::PACK_SHRINK);
1012 void
1013 EditWidget::initTopRuler()
1015     _viewport_table.attach(_top_ruler,  1, 2, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1017     _tooltips.set_tip (_top_ruler, _top_ruler.get_tip());
1020 void
1021 EditWidget::initLeftRuler()
1023     _viewport_table.attach(_left_ruler, 0, 1, 1, 2, Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
1025     _tooltips.set_tip (_left_ruler, _left_ruler.get_tip());
1028 void
1029 EditWidget::initBottomScrollbar()
1031     _viewport_table.attach(_bottom_scrollbar, 1, 2, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1032     _bottom_scrollbar.signal_value_changed().connect (sigc::mem_fun (*this, &EditWidget::onAdjValueChanged));
1033     _bottom_scrollbar.property_adjustment() = new Gtk::Adjustment (0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0);
1036 void
1037 EditWidget::initRightScrollbar()
1039     _viewport_table.attach(_right_scrollbar, 2, 3, 1, 2, Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
1041     _right_scrollbar.signal_value_changed().connect (sigc::mem_fun (*this, &EditWidget::onAdjValueChanged));
1042     _right_scrollbar.property_adjustment() = new Gtk::Adjustment (0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0);
1045 void
1046 EditWidget::initStickyZoom()
1048     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1049     _viewport_table.attach(_sticky_zoom, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
1050     _sticky_zoom.set_active (prefs->getBool("/options/stickyzoom/value"));
1051     _tooltips.set_tip (_sticky_zoom, _("Zoom drawing if window size changes"));
1053     /// \todo icon not implemented
1056 void
1057 EditWidget::initStatusbar()
1059     _statusbar.pack_start (_selected_style_status, false, false, 1);
1060     _statusbar.pack_start (*new Gtk::VSeparator(), false, false, 0);
1062     _tooltips.set_tip (_zoom_status, _("Zoom"));
1064     _layer_selector.reference();
1065     _statusbar.pack_start (_layer_selector, false, false, 1);
1067     _coord_status.property_n_rows() = 2;
1068     _coord_status.property_n_columns() = 5;
1069     _coord_status.property_row_spacing() = 0;
1070     _coord_status.property_column_spacing() = 2;
1071     _coord_eventbox.add (_coord_status);
1072     _tooltips.set_tip (_coord_eventbox, _("Cursor coordinates"));
1073     _coord_status.attach (*new Gtk::VSeparator(), 0,1, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1074     _coord_status.attach (*new Gtk::Label(_("X:"), 0.0, 0.5), 1,2, 0,1, Gtk::FILL,Gtk::FILL, 0,0);
1075     _coord_status.attach (*new Gtk::Label(_("Y:"), 0.0, 0.5), 1,2, 1,2, Gtk::FILL,Gtk::FILL, 0,0);
1076     _coord_status_x.set_text ("0.0");
1077     _coord_status_x.set_alignment (0.0, 0.5);
1078     _coord_status_y.set_text ("0.0");
1079     _coord_status_y.set_alignment (0.0, 0.5);
1080     _coord_status.attach (_coord_status_x, 2,3, 0,1, Gtk::FILL,Gtk::FILL, 0,0);
1081     _coord_status.attach (_coord_status_y, 2,3, 1,2, Gtk::FILL,Gtk::FILL, 0,0);
1082     _coord_status.attach (*new Gtk::Label(_("Z:"), 0.0, 0.5), 3,4, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1083     _coord_status.attach (_zoom_status, 4,5, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1084     sp_set_font_size_smaller (static_cast<GtkWidget*>((void*)_coord_status.gobj()));
1085     _statusbar.pack_end (_coord_eventbox, false, false, 1);
1087     _select_status.property_xalign() = 0.0;
1088     _select_status.property_yalign() = 0.5;
1089     _select_status.set_markup (_("<b>Welcome to Inkscape!</b> Use shape or drawing tools to create objects; use selector (arrow) to move or transform them."));
1090     // include this again with Gtk+-2.6
1091 #if GTK_VERSION_GE(2,6)
1092      gtk_label_set_ellipsize (GTK_LABEL(_select_status.gobj()), PANGO_ELLIPSIZE_END);
1093 #endif
1094     _select_status.set_size_request (1, -1);
1095     _statusbar.pack_start (_select_status, true, true, 0);
1097     _main_window_table.attach(_statusbar, 0, 1, 3, 4, Gtk::FILL, Gtk::SHRINK);
1100 //========================================
1101 //----------implements EditWidgetInterface
1103 Gtk::Window *
1104 EditWidget::getWindow()
1106     return this;
1109 void
1110 EditWidget::setTitle (gchar const* new_title)
1112     set_title (new_title);
1115 void
1116 EditWidget::layout()
1118    show_all_children();
1121 void
1122 EditWidget::present()
1124     this->Gtk::Window::present();
1127 void
1128 EditWidget::getGeometry (gint &x, gint &y, gint &w, gint &h)
1130     get_position (x, y);
1131     get_size (w, h);
1134 void
1135 EditWidget::setSize (gint w, gint h)
1137     resize (w, h);
1140 void
1141 EditWidget::setPosition (Geom::Point p)
1143     move (int(p[Geom::X]), int(p[Geom::Y]));
1146 /// \param p is already gobj()!
1147 void
1148 EditWidget::setTransient (void* p, int i)
1150     gtk_window_set_transient_for (static_cast<GtkWindow*>(p), this->gobj());
1151     if (i==2)
1152         this->Gtk::Window::present();
1155 Geom::Point
1156 EditWidget::getPointer()
1158     int x, y;
1159     get_pointer (x, y);
1160     return Geom::Point (x, y);
1163 void
1164 EditWidget::setIconified()
1166     iconify();
1169 void
1170 EditWidget::setMaximized()
1172     maximize();
1175 void
1176 EditWidget::setFullscreen()
1178     fullscreen();
1181 /**
1182  *  Shuts down the desktop object for the view being closed.  It checks
1183  *  to see if the document has been edited, and if so prompts the user
1184  *  to save, discard, or cancel.  Returns TRUE if the shutdown operation
1185  *  is cancelled or if the save is cancelled or fails, FALSE otherwise.
1186  */
1187 bool
1188 EditWidget::shutdown()
1190     g_assert (_desktop != NULL);
1191     if (Inkscape::NSApplication::Editor::isDuplicatedView (_desktop))
1192         return false;
1194     SPDocument *doc = _desktop->doc();
1195     if (doc->isModifiedSinceSave()) {
1196         gchar *markup;
1197         /// \todo FIXME !!! obviously this will have problems if the document
1198         /// name contains markup characters
1199         markup = g_strdup_printf(
1200                 _("<span weight=\"bold\" size=\"larger\">Save changes to document \"%s\" before closing?</span>\n\n"
1201                   "If you close without saving, your changes will be discarded."),
1202                 SP_DOCUMENT_NAME(doc));
1204         Gtk::MessageDialog dlg (*this,
1205                        markup,
1206                        true,
1207                        Gtk::MESSAGE_WARNING,
1208                        Gtk::BUTTONS_NONE,
1209                        true);
1210         g_free(markup);
1211         Gtk::Button close_button (_("Close _without saving"), true);
1212         dlg.add_action_widget (close_button, Gtk::RESPONSE_NO);
1213         close_button.show();
1214         dlg.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1215         dlg.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_YES);
1216         dlg.set_default_response (Gtk::RESPONSE_YES);
1218         int response = dlg.run();
1219         switch (response)
1220         {
1221             case Gtk::RESPONSE_YES:
1222                 sp_document_ref(doc);
1223                 sp_namedview_document_from_window(_desktop);
1224                 if (sp_file_save_document(*this, doc)) {
1225                     sp_document_unref(doc);
1226                 } else { // save dialog cancelled or save failed
1227                     sp_document_unref(doc);
1228                     return TRUE;
1229                 }
1230                 break;
1231             case Gtk::RESPONSE_NO:
1232                 break;
1233             default: // cancel pressed, or dialog was closed
1234                 return TRUE;
1235                 break;
1236         }
1237     }
1239     /* Code to check data loss */
1240     bool allow_data_loss = FALSE;
1241     while (sp_document_repr_root(doc)->attribute("inkscape:dataloss") != NULL && allow_data_loss == FALSE)
1242     {
1243         gchar *markup;
1244         /// \todo FIXME !!! obviously this will have problems if the document
1245         /// name contains markup characters
1246         markup = g_strdup_printf(
1247                 _("<span weight=\"bold\" size=\"larger\">The file \"%s\" was saved with a format (%s) that may cause data loss!</span>\n\n"
1248                   "Do you want to save this file as an Inkscape SVG?"),
1249                 SP_DOCUMENT_NAME(doc),
1250                 Inkscape::Extension::db.get(sp_document_repr_root(doc)->attribute("inkscape:output_extension"))->get_name());
1252         Gtk::MessageDialog dlg (*this,
1253                        markup,
1254                        true,
1255                        Gtk::MESSAGE_WARNING,
1256                        Gtk::BUTTONS_NONE,
1257                        true);
1258         g_free(markup);
1259         Gtk::Button close_button (_("Close _without saving"), true);
1260         dlg.add_action_widget (close_button, Gtk::RESPONSE_NO);
1261         close_button.show();
1262         Gtk::Button save_button (_("_Save as SVG"), true);
1263         dlg.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1264         dlg.add_action_widget (save_button, Gtk::RESPONSE_YES);
1265         save_button.show();
1266         dlg.set_default_response (Gtk::RESPONSE_YES);
1268         int response = dlg.run();
1270         switch (response)
1271         {
1272             case Gtk::RESPONSE_YES:
1273                 sp_document_ref(doc);
1274                 if (sp_file_save_document(*this, doc)) {
1275                     sp_document_unref(doc);
1276                 } else { // save dialog cancelled or save failed
1277                     sp_document_unref(doc);
1278                     return TRUE;
1279                 }
1280                 break;
1281             case Gtk::RESPONSE_NO:
1282                 allow_data_loss = TRUE;
1283                 break;
1284             default: // cancel pressed, or dialog was closed
1285                 return TRUE;
1286                 break;
1287         }
1288     }
1290     return false;
1294 void
1295 EditWidget::destroy()
1297     delete this;
1300 void
1301 EditWidget::requestCanvasUpdate()
1303     _svg_canvas.widget().queue_draw();
1306 void
1307 EditWidget::requestCanvasUpdateAndWait()
1309     requestCanvasUpdate();
1311     while (gtk_events_pending())
1312       gtk_main_iteration_do(FALSE);
1315 void
1316 EditWidget::enableInteraction()
1318   g_return_if_fail(_interaction_disabled_counter > 0);
1320   _interaction_disabled_counter--;
1322   if (_interaction_disabled_counter == 0) {
1323     this->set_sensitive(true);
1324   }
1327 void
1328 EditWidget::disableInteraction()
1330   if (_interaction_disabled_counter == 0) {
1331     this->set_sensitive(false);
1332   }
1334   _interaction_disabled_counter++;
1337 void
1338 EditWidget::activateDesktop()
1340     /// \todo active_desktop_indicator not implemented
1343 void
1344 EditWidget::deactivateDesktop()
1346     /// \todo active_desktop_indicator not implemented
1349 void
1350 EditWidget::viewSetPosition (Geom::Point p)
1352     // p -= _namedview->gridorigin;
1353     /// \todo Why was the origin corrected for the grid origin? (johan)
1355     double lo, up, pos, max;
1356     _top_ruler.get_range (lo, up, pos, max);
1357     _top_ruler.set_range (lo, up, p[Geom::X], max);
1358     _left_ruler.get_range (lo, up, pos, max);
1359     _left_ruler.set_range (lo, up, p[Geom::Y], max);
1362 void
1363 EditWidget::updateRulers()
1365     //Geom::Point gridorigin = _namedview->gridorigin;
1366     /// \todo Why was the origin corrected for the grid origin? (johan)
1368     Geom::Rect const viewbox = _svg_canvas.spobj()->getViewbox();
1369     double lo, up, pos, max;
1370     double const scale = _desktop->current_zoom();
1371     double s = viewbox.min()[Geom::X] / scale; //- gridorigin[Geom::X];
1372     double e = viewbox.max()[Geom::X] / scale; //- gridorigin[Geom::X];
1373     _top_ruler.get_range(lo, up, pos, max);
1374     _top_ruler.set_range(s, e, pos, e);
1375     s = viewbox.min()[Geom::Y] / -scale; //- gridorigin[Geom::Y];
1376     e = viewbox.max()[Geom::Y] / -scale; //- gridorigin[Geom::Y];
1377     _left_ruler.set_range(s, e, 0 /*gridorigin[Geom::Y]*/, e);
1378     /// \todo is that correct?
1381 void
1382 EditWidget::updateScrollbars (double scale)
1384     // do not call this function before canvas has its size allocated
1385     if (!is_realized() || _update_s_f) {
1386         return;
1387     }
1389     _update_s_f = true;
1391     /* The desktop region we always show unconditionally */
1392     SPDocument *doc = _desktop->doc();
1393     Geom::Rect darea ( Geom::Point(-sp_document_width(doc), -sp_document_height(doc)),
1394                      Geom::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc))  );
1395     SPObject* root = doc->root;
1396     SPItem* item = SP_ITEM(root);
1397     Geom::OptRect deskarea = Geom::unify(darea, sp_item_bbox_desktop(item));
1399     /* Canvas region we always show unconditionally */
1400     Geom::Rect carea( Geom::Point(deskarea->min()[Geom::X] * scale - 64, deskarea->max()[Geom::Y] * -scale - 64),
1401                     Geom::Point(deskarea->max()[Geom::X] * scale + 64, deskarea->min()[Geom::Y] * -scale + 64)  );
1403     Geom::Rect const viewbox = _svg_canvas.spobj()->getViewbox();
1405     /* Viewbox is always included into scrollable region */
1406     carea = Geom::unify(carea, viewbox);
1408     Gtk::Adjustment *adj = _bottom_scrollbar.get_adjustment();
1409     adj->set_value(viewbox.min()[Geom::X]);
1410     adj->set_lower(carea.min()[Geom::X]);
1411     adj->set_upper(carea.max()[Geom::X]);
1412     adj->set_page_increment(viewbox.dimensions()[Geom::X]);
1413     adj->set_step_increment(0.1 * (viewbox.dimensions()[Geom::X]));
1414     adj->set_page_size(viewbox.dimensions()[Geom::X]);
1416     adj = _right_scrollbar.get_adjustment();
1417     adj->set_value(viewbox.min()[Geom::Y]);
1418     adj->set_lower(carea.min()[Geom::Y]);
1419     adj->set_upper(carea.max()[Geom::Y]);
1420     adj->set_page_increment(viewbox.dimensions()[Geom::Y]);
1421     adj->set_step_increment(0.1 * viewbox.dimensions()[Geom::Y]);
1422     adj->set_page_size(viewbox.dimensions()[Geom::Y]);
1424     _update_s_f = false;
1427 void
1428 EditWidget::toggleRulers()
1430     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1431     if (_top_ruler.is_visible())
1432     {
1433         _top_ruler.hide_all();
1434         _left_ruler.hide_all();
1435         prefs->setBool(_desktop->is_fullscreen() ? "/fullscreen/rulers/state" : "/window/rulers/state", false);
1436     } else {
1437         _top_ruler.show_all();
1438         _left_ruler.show_all();
1439         prefs->setBool(_desktop->is_fullscreen() ? "/fullscreen/rulers/state" : "/window/rulers/state", true);
1440     }
1443 void
1444 EditWidget::toggleScrollbars()
1446     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1447     if (_bottom_scrollbar.is_visible())
1448     {
1449         _bottom_scrollbar.hide_all();
1450         _right_scrollbar.hide_all();
1451         prefs->setBool(_desktop->is_fullscreen() ? "/fullscreen/scrollbars/state" : "/window/scrollbars/state", false);
1452     } else {
1453         _bottom_scrollbar.show_all();
1454         _right_scrollbar.show_all();
1455         prefs->setBool(_desktop->is_fullscreen() ? "/fullscreen/scrollbars/state" : "/window/scrollbars/state", true);
1456     }
1459 void EditWidget::toggleColorProfAdjust()
1461     // TODO implement
1464 void
1465 EditWidget::updateZoom()
1467     _zoom_status.update();
1470 void
1471 EditWidget::letZoomGrabFocus()
1473     _zoom_status.grab_focus();
1476 void
1477 EditWidget::setToolboxFocusTo (const gchar *)
1479     /// \todo not implemented
1482 void
1483 EditWidget::setToolboxAdjustmentValue (const gchar *, double)
1485     /// \todo not implemented
1488 void
1489 EditWidget::setToolboxSelectOneValue (const gchar *, gint)
1491     /// \todo not implemented
1494 bool
1495 EditWidget::isToolboxButtonActive (gchar const*)
1497     /// \todo not implemented
1498     return true;
1501 void
1502 EditWidget::setCoordinateStatus (Geom::Point p)
1504     gchar *cstr = g_strdup_printf ("%6.2f", _dt2r * p[Geom::X]);
1505     _coord_status_x.property_label() = cstr;
1506     g_free (cstr);
1507     cstr = g_strdup_printf ("%6.2f", _dt2r * p[Geom::Y]);
1508     _coord_status_y.property_label() = cstr;
1509     g_free (cstr);
1512 void
1513 EditWidget::setMessage (Inkscape::MessageType /*type*/, gchar const* msg)
1515     _select_status.set_markup (msg? msg : "");
1518 bool
1519 EditWidget::warnDialog (gchar* msg)
1521     Gtk::MessageDialog dlg (*this,
1522                        msg,
1523                        true,
1524                        Gtk::MESSAGE_WARNING,
1525                        Gtk::BUTTONS_YES_NO,
1526                        true);
1527     int r = dlg.run();
1528     return r == Gtk::RESPONSE_YES;
1532 Inkscape::UI::Widget::Dock*
1533 EditWidget::getDock ()
1535     return &_dock;
1538 void EditWidget::_namedview_modified (SPObject *obj, guint flags) {
1539     SPNamedView *nv = static_cast<SPNamedView *>(obj);
1540     if (flags & SP_OBJECT_MODIFIED_FLAG) {
1541         this->_dt2r = 1.0 / nv->doc_units->unittobase;
1542         this->_top_ruler.update_metric();
1543         this->_left_ruler.update_metric();
1544         this->_tooltips.set_tip(this->_top_ruler, this->_top_ruler.get_tip());
1545         this->_tooltips.set_tip(this->_left_ruler, this->_left_ruler.get_tip());
1546         this->updateRulers();
1547     }
1550 void
1551 EditWidget::initEdit (SPDocument *doc)
1553     _desktop = new SPDesktop();
1554     _desktop->registerEditWidget (this);
1556     _namedview = sp_document_namedview (doc, 0);
1557     _svg_canvas.init (_desktop);
1558     _desktop->init (_namedview, _svg_canvas.spobj());
1559     sp_namedview_window_from_document (_desktop);
1560     sp_namedview_update_layers_from_document (_desktop);
1561     _dt2r = 1.0 / _namedview->doc_units->unittobase;
1563     /// \todo convert to sigc++ when SPObject hierarchy gets converted
1564     /* Listen on namedview modification */
1565     _namedview_modified_connection = _desktop->namedview->connectModified(sigc::mem_fun(*this, &EditWidget::_namedview_modified));
1566     _layer_selector.setDesktop (_desktop);
1567     _selected_style_status.setDesktop (_desktop);
1569     Inkscape::NSApplication::Editor::addDesktop (_desktop);
1571     _zoom_status.init (_desktop);
1572     _top_ruler.init (_desktop, _svg_canvas.widget());
1573     _left_ruler.init (_desktop, _svg_canvas.widget());
1574     updateRulers();
1577 void
1578 EditWidget::destroyEdit()
1580     if (_desktop) {
1581         _layer_selector.unreference();
1582         Inkscape::NSApplication::Editor::removeDesktop (_desktop); // clears selection too
1583         _namedview_modified_connection.disconnect();
1584         _desktop->destroy();
1585         Inkscape::GC::release (_desktop);
1586         _desktop = 0;
1587     }
1590 //----------end of EditWidgetInterface implementation
1592 //----------start of other callbacks
1594 bool
1595 EditWidget::on_key_press_event (GdkEventKey* event)
1597     // this is the original code from helper/window.cpp
1599     unsigned int shortcut;
1600     shortcut = get_group0_keyval (event) |
1601                    ( event->state & GDK_SHIFT_MASK ?
1602                      SP_SHORTCUT_SHIFT_MASK : 0 ) |
1603                    ( event->state & GDK_CONTROL_MASK ?
1604                      SP_SHORTCUT_CONTROL_MASK : 0 ) |
1605                    ( event->state & GDK_MOD1_MASK ?
1606                      SP_SHORTCUT_ALT_MASK : 0 );
1607     return sp_shortcut_invoke (shortcut,
1608                              Inkscape::NSApplication::Editor::getActiveDesktop());
1611 bool
1612 EditWidget::on_delete_event (GdkEventAny*)
1614     return shutdown();
1617 bool
1618 EditWidget::on_focus_in_event (GdkEventFocus*)
1620     Inkscape::NSApplication::Editor::activateDesktop (_desktop);
1621     _svg_canvas.widget().grab_focus();
1623     return false;
1626 void
1627 EditWidget::onWindowSizeAllocate (Gtk::Allocation &newall)
1629     if (!is_realized()) return;
1631     const Gtk::Allocation& all = get_allocation();
1632     if ((newall.get_x() == all.get_x()) &&
1633         (newall.get_y() == all.get_y()) &&
1634         (newall.get_width() == all.get_width()) &&
1635         (newall.get_height() == all.get_height())) {
1636         return;
1637     }
1639     Geom::Rect const area = _desktop->get_display_area();
1640     double zoom = _desktop->current_zoom();
1642     if (_sticky_zoom.get_active()) {
1643         /* Calculate zoom per pixel */
1644         double const zpsp = zoom / hypot(area.dimensions()[Geom::X], area.dimensions()[Geom::Y]);
1645         /* Find new visible area */
1646         Geom::Rect const newarea = _desktop->get_display_area();
1647         /* Calculate adjusted zoom */
1648         zoom = zpsp * hypot(newarea.dimensions()[Geom::X], newarea.dimensions()[Geom::Y]);
1649     }
1651     _desktop->zoom_absolute(area.midpoint()[Geom::X], area.midpoint()[Geom::Y], zoom);
1654 void
1655 EditWidget::onWindowRealize()
1658     if ( (sp_document_width(_desktop->doc()) < 1.0) || (sp_document_height(_desktop->doc()) < 1.0) ) {
1659         return;
1660     }
1662     Geom::Rect d( Geom::Point(0, 0),
1663                   Geom::Point(sp_document_width(_desktop->doc()), sp_document_height(_desktop->doc())) );
1665     _desktop->set_display_area(d.min()[Geom::X], d.min()[Geom::Y], d.max()[Geom::X], d.max()[Geom::Y], 10);
1666     _namedview_modified(_desktop->namedview, SP_OBJECT_MODIFIED_FLAG);
1667     setTitle (SP_DOCUMENT_NAME(_desktop->doc()));
1670 void
1671 EditWidget::onAdjValueChanged()
1673     if (_update_a_f) return;
1674     _update_a_f = true;
1676     sp_canvas_scroll_to (_svg_canvas.spobj(),
1677                          _bottom_scrollbar.get_value(),
1678                          _right_scrollbar.get_value(),
1679                          false);
1680     updateRulers();
1682     _update_a_f = false;
1686 } // namespace View
1687 } // namespace UI
1688 } // namespace Inkscape
1690 /*
1691   Local Variables:
1692   mode:c++
1693   c-file-style:"stroustrup"
1694   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1695   indent-tabs-mode:nil
1696   fill-column:99
1697   End:
1698 */
1699 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :