Code

b86a5d3f9f79261b6ca8bd6284ecff58f4f56c8c
[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 <gtkmm/radioaction.h>
33 #include <gtkmm/menubar.h>
34 #include <gtkmm/messagedialog.h>
35 #include <gtkmm/stock.h>
36 #include <gtkmm/accelmap.h>
37 #include <gtkmm/separator.h>
39 #include "macros.h"
40 #include "path-prefix.h"
41 #include "prefs-utils.h"
42 #include "file.h"
43 #include "application/editor.h"
44 #include "edit-widget.h"
45 #include "ui/stock.h"
46 #include "ui/stock-items.h"
47 #include "ui/icons.h"
49 #include "display/sodipodi-ctrlrect.h"
50 #include "helper/units.h"
51 #include "shortcuts.h"
52 #include "widgets/spw-utilities.h"
53 #include "event-context.h"
54 #include "document.h"
55 #include "sp-namedview.h"
56 #include "sp-item.h"
57 #include "interface.h"
58 #include "extension/db.h"
60 #ifdef WITH_INKBOARD
61 #include "ui/dialog/whiteboard-connect.h"
62 #include "ui/dialog/whiteboard-sharewithuser.h"
63 #include "ui/dialog/whiteboard-sharewithchat.h"
64 #endif
66 using namespace Inkscape::UI;
67 using namespace Inkscape::UI::Widget;
69 namespace Inkscape {
70 namespace UI {
71 namespace View {
73 EditWidget::EditWidget (SPDocument *doc)
74     : _main_window_table(4),
75       _viewport_table(3,3),
76       _act_grp(Gtk::ActionGroup::create()),
77       _ui_mgr(Gtk::UIManager::create()),
78       _update_s_f(false),
79       _update_a_f(false)
80 {
81     g_warning("Creating new EditWidget");
83     _desktop = 0;
84     Icons::init();
85     Stock::init();
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();
153     // The statusbar comes last and appears at the bottom of _main_window_table
154     initStatusbar();
156     signal_size_allocate().connect (sigc::mem_fun (*this, &EditWidget::onWindowSizeAllocate), false);
157     signal_realize().connect (sigc::mem_fun (*this, &EditWidget::onWindowRealize));
158     show_all_children();
161 void
162 EditWidget::onMenuItem()
164     g_warning("onMenuItem called");
167 void
168 EditWidget::onActionFileNew()
170 //    g_warning("onActionFileNew called");
171     sp_file_new_default();
174 void
175 EditWidget::onActionFileOpen()
177 //    g_warning("onActionFileOpen called");
178     sp_file_open_dialog (NULL, NULL);
181 void
182 EditWidget::onActionFileQuit()
184     g_warning("onActionFileQuit");
185     sp_ui_close_all();
188 void
189 EditWidget::onActionFilePrint()
191     g_warning("onActionFilePrint");
194 void
195 EditWidget::onToolbarItem()
197     g_warning("onToolbarItem called");
200 void
201 EditWidget::onSelectTool()
203     _tool_ctrl->remove();
204     _tool_ctrl->add(*_select_ctrl);
207 void
208 EditWidget::onNodeTool()
210     _tool_ctrl->remove();
211     _tool_ctrl->add(*_node_ctrl);
214 void
215 EditWidget::onDialogInkscapePreferences()
217     _dlg_mgr.showDialog("InkscapePreferences");
220 void
221 EditWidget::onDialogAbout()
225 void
226 EditWidget::onDialogAlignAndDistribute()
228     _dlg_mgr.showDialog("AlignAndDistribute");
231 void
232 EditWidget::onDialogDocumentProperties()
234 //    manage (Inkscape::UI::Dialog::DocumentPreferences::create());
235     _dlg_mgr.showDialog("DocumentPreferences");
238 void
239 EditWidget::onDialogExport()
241     _dlg_mgr.showDialog("Export");
244 void
245 EditWidget::onDialogExtensionEditor()
247     _dlg_mgr.showDialog("ExtensionEditor");
250 void
251 EditWidget::onDialogFillAndStroke()
253     _dlg_mgr.showDialog("FillAndStroke");
256 void
257 EditWidget::onDialogFind()
259     _dlg_mgr.showDialog("Find");
262 void
263 EditWidget::onDialogLayerEditor()
265     _dlg_mgr.showDialog("LayerEditor");
268 void
269 EditWidget::onDialogMessages()
271     _dlg_mgr.showDialog("Messages");
274 void
275 EditWidget::onDialogObjectProperties()
277     _dlg_mgr.showDialog("ObjectProperties");
280 void 
281 EditWidget::onDialogTextProperties()
283     _dlg_mgr.showDialog("TextProperties");
286 void
287 EditWidget::onDialogTrace()
291 void 
292 EditWidget::onDialogTransformation()
294     _dlg_mgr.showDialog("Transformation");
297 void
298 EditWidget::onDialogXmlEditor()
300     _dlg_mgr.showDialog("XmlEditor");
303 #ifdef WITH_INKBOARD
304 void
305 EditWidget::onDialogWhiteboardConnect()
307         Dialog::WhiteboardConnectDialogImpl* dlg = dynamic_cast< Dialog::WhiteboardConnectDialogImpl* >(_dlg_mgr.getDialog("WhiteboardConnect"));
308         dlg->setSessionManager();
309         _dlg_mgr.showDialog("WhiteboardConnect");
312 void
313 EditWidget::onDialogWhiteboardShareWithUser()
315                 Dialog::WhiteboardShareWithUserDialogImpl* dlg = dynamic_cast< Dialog::WhiteboardShareWithUserDialogImpl* >(_dlg_mgr.getDialog("WhiteboardShareWithUser"));
316                 dlg->setSessionManager();
317                 _dlg_mgr.showDialog("WhiteboardShareWithUser");
320 void
321 EditWidget::onDialogWhiteboardShareWithChat()
323         Dialog::WhiteboardShareWithChatroomDialogImpl* dlg = dynamic_cast< Dialog::WhiteboardShareWithChatroomDialogImpl* >(_dlg_mgr.getDialog("WhiteboardShareWithChat"));
324         dlg->setSessionManager();
325         _dlg_mgr.showDialog("WhiteboardShareWithChat");
328 void
329 EditWidget::onDialogOpenSessionFile()
331         g_log(NULL, G_LOG_LEVEL_DEBUG, "not reimplemented yet");
334 void
335 EditWidget::onDumpXMLTracker()
337         g_log(NULL, G_LOG_LEVEL_DEBUG, "not reimplemented yet");
340 #endif
342 void
343 EditWidget::onUriChanged()
345     g_message("onUriChanged called");
346     
349 // FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled
350 // See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details
352 void
353 EditWidget::initMenuActions()
355 //    _act_grp->add(Gtk::Action::create("MenuFile",   _("PLACEHOLDER, do not translate")));
356 //    _act_grp->add(Gtk::Action::create("MenuEdit",   _("PLACEHOLDER, do not translate")));
357 //    _act_grp->add(Gtk::Action::create("MenuView",   _("PLACEHOLDER, do not translate")));
358 //    _act_grp->add(Gtk::Action::create("MenuLayer",  _("PLACEHOLDER, do not translate")));
359 //    _act_grp->add(Gtk::Action::create("MenuObject", _("PLACEHOLDER, do not translate")));
360 //    _act_grp->add(Gtk::Action::create("MenuPath",   _("PLACEHOLDER, do not translate")));
361 //    _act_grp->add(Gtk::Action::create("MenuText",   _("PLACEHOLDER, do not translate")));
362 #ifdef WITH_INKBOARD
363 //    _act_grp->add(Gtk::Action::create("MenuWhiteboard",   _("PLACEHOLDER, do not translate")));
364 #endif
365 //    _act_grp->add(Gtk::Action::create("MenuHelp",   _("PLACEHOLDER, do not translate")));
366 // temporarily replaced with non-gettext version to have a well-sized menu
367 // for testing:
369     _act_grp->add(Gtk::Action::create("MenuFile",   "File"));
370     _act_grp->add(Gtk::Action::create("MenuEdit",   "Edit"));
371     _act_grp->add(Gtk::Action::create("MenuView",   "View"));
372     _act_grp->add(Gtk::Action::create("MenuLayer",  "Layer"));
373     _act_grp->add(Gtk::Action::create("MenuObject", "Object"));
374     _act_grp->add(Gtk::Action::create("MenuPath",   "Path"));
375     _act_grp->add(Gtk::Action::create("MenuText",   "Text"));
376 #ifdef WITH_INKBOARD
377     _act_grp->add(Gtk::Action::create("MenuWhiteboard",   "Whiteboard"));
378 #endif
379     _act_grp->add(Gtk::Action::create("MenuHelp",   "Help"));
381     // File menu
382     _act_grp->add(Gtk::Action::create("New",
383                                       Gtk::Stock::NEW, Glib::ustring(),
384                                       _("PLACEHOLDER, do not translate")),
385                   sigc::mem_fun(*this, &EditWidget::onActionFileNew));
387     _act_grp->add(Gtk::Action::create("Open",
388                                       Gtk::Stock::OPEN, Glib::ustring(),
389                                       _("PLACEHOLDER, do not translate")),
390                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
392     _act_grp->add(Gtk::Action::create("OpenRecent",
393                                       Stock::OPEN_RECENT));
395     _act_grp->add(Gtk::Action::create("Revert",
396                                       Gtk::Stock::REVERT_TO_SAVED, Glib::ustring(),
397                                       _("PLACEHOLDER, do not translate")),
398                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
400     _act_grp->add(Gtk::Action::create("Save",
401                                       Gtk::Stock::SAVE, Glib::ustring(),
402                                       _("PLACEHOLDER, do not translate")),
403                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
405     _act_grp->add(Gtk::Action::create("SaveAs",
406                                       Gtk::Stock::SAVE_AS, Glib::ustring(),
407                                       _("PLACEHOLDER, do not translate")),
408                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
410     _act_grp->add(Gtk::Action::create("Import",
411                                       Stock::IMPORT, Glib::ustring(),
412                                       _("PLACEHOLDER, do not translate")),
413                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
415     _act_grp->add(Gtk::Action::create("Export",
416                                       Stock::EXPORT, Glib::ustring(),
417                                       _("PLACEHOLDER, do not translate")),
418                   sigc::mem_fun(*this, &EditWidget::onDialogExport));
420     _act_grp->add(Gtk::Action::create("Print",
421                                       Gtk::Stock::PRINT, Glib::ustring(),
422                                       _("PLACEHOLDER, do not translate")),
423                   sigc::mem_fun(*this, &EditWidget::onActionFilePrint));
425     _act_grp->add(Gtk::Action::create("PrintPreview",
426                                       Gtk::Stock::PRINT_PREVIEW),
427                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
429     _act_grp->add(Gtk::Action::create("VacuumDefs",
430                                       Stock::VACUUM_DEFS),
431                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
433     _act_grp->add(Gtk::Action::create("DocumentProperties",
434                                       Gtk::Stock::PROPERTIES, Glib::ustring(),
435                                       _("PLACEHOLDER, do not translate")),
436                   sigc::mem_fun(*this, &EditWidget::onDialogDocumentProperties));
438     _act_grp->add(Gtk::Action::create("InkscapePreferences",
439                                       Gtk::Stock::PREFERENCES, Glib::ustring(),
440                                       _("PLACEHOLDER, do not translate")),
441                   sigc::mem_fun(*this, &EditWidget::onDialogInkscapePreferences));
443     _act_grp->add(Gtk::Action::create("Close",
444                                       Gtk::Stock::CLOSE),
445                   sigc::mem_fun(*this, &EditWidget::onActionFileOpen));
447     _act_grp->add(Gtk::Action::create("Quit",
448                                       Gtk::Stock::QUIT),
449                   sigc::mem_fun(*this, &EditWidget::onActionFileQuit));
451     // EditWidget menu
452     _act_grp->add(Gtk::Action::create("Undo",
453                                       Gtk::Stock::UNDO, Glib::ustring(),
454                                       _("PLACEHOLDER, do not translate")));
456     _act_grp->add(Gtk::Action::create("Redo",
457                                       Gtk::Stock::REDO, Glib::ustring(),
458                                       _("PLACEHOLDER, do not translate")));
460     _act_grp->add(Gtk::Action::create("Cut",
461                                       Gtk::Stock::CUT, Glib::ustring(),
462                                       _("PLACEHOLDER, do not translate")));
464     _act_grp->add(Gtk::Action::create("Copy",
465                                       Gtk::Stock::COPY, Glib::ustring(),
466                                       _("PLACEHOLDER, do not translate")));
468     _act_grp->add(Gtk::Action::create("Paste",
469                                       Gtk::Stock::PASTE, Glib::ustring(),
470                                       _("PLACEHOLDER, do not translate")));
472     _act_grp->add(Gtk::Action::create("PasteInPlace",
473                                       Stock::PASTE_IN_PLACE));
475     _act_grp->add(Gtk::Action::create("PasteStyle",
476                                       Stock::PASTE_STYLE));
478     _act_grp->add(Gtk::Action::create("Find",
479                                       Gtk::Stock::FIND),
480                   sigc::mem_fun(*this, &EditWidget::onDialogFind));
482     _act_grp->add(Gtk::Action::create("Duplicate",
483                                       Stock::DUPLICATE, Glib::ustring(),
484                                       _("PLACEHOLDER, do not translate")));
486     _act_grp->add(Gtk::Action::create("Clone",
487                                       Stock::CLONE, Glib::ustring(),
488                                       _("PLACEHOLDER, do not translate")));
490     _act_grp->add(Gtk::Action::create("CloneUnlink",
491                                       Stock::CLONE_UNLINK, Glib::ustring(),
492                                       _("PLACEHOLDER, do not translate")));
494     _act_grp->add(Gtk::Action::create("CloneSelectOrig",
495                                       Stock::CLONE_SELECT_ORIG));
497     _act_grp->add(Gtk::Action::create("MakeBitmap",
498                                       Stock::MAKE_BITMAP));
500     _act_grp->add(Gtk::Action::create("Tile",
501                                      Stock::TILE));
503     _act_grp->add(Gtk::Action::create("Untile",
504                                       Stock::UNTILE));
506     _act_grp->add(Gtk::Action::create("Delete",
507                                       Gtk::Stock::DELETE));
509     _act_grp->add(Gtk::Action::create("SelectAll",
510                                       Stock::SELECT_ALL));
512     _act_grp->add(Gtk::Action::create("SelectAllInAllLayers",
513                                       Stock::SELECT_ALL_IN_ALL_LAYERS));
515     _act_grp->add(Gtk::Action::create("SelectInvert",
516                                       Stock::SELECT_INVERT));
518     _act_grp->add(Gtk::Action::create("SelectNone",
519                                       Stock::SELECT_NONE));
521     _act_grp->add(Gtk::Action::create("XmlEditor",
522                                       Stock::XML_EDITOR, Glib::ustring(),
523                                       _("PLACEHOLDER, do not translate")),
524                   sigc::mem_fun(*this, &EditWidget::onDialogXmlEditor));
526     // View menu
527     _act_grp->add(Gtk::Action::create("Zoom",
528                                       Stock::ZOOM));
530     _act_grp->add(Gtk::Action::create("ZoomIn",
531                                       Stock::ZOOM_IN, Glib::ustring(),
532                                       _("PLACEHOLDER, do not translate")));
534     _act_grp->add(Gtk::Action::create("ZoomOut",
535                                       Stock::ZOOM_OUT, Glib::ustring(),
536                                       _("PLACEHOLDER, do not translate")));
538     _act_grp->add(Gtk::Action::create("Zoom100",
539                                       Stock::ZOOM_100, Glib::ustring(),
540                                       _("PLACEHOLDER, do not translate")));
542     _act_grp->add(Gtk::Action::create("Zoom50",
543                                       Stock::ZOOM_50, Glib::ustring(),
544                                       _("PLACEHOLDER, do not translate")));
546     _act_grp->add(Gtk::Action::create("Zoom200",
547                                       Stock::ZOOM_200, Glib::ustring(),
548                                       _("PLACEHOLDER, do not translate")));
550     _act_grp->add(Gtk::Action::create("ZoomSelection",
551                                       Stock::ZOOM_SELECTION, Glib::ustring(),
552                                       _("PLACEHOLDER, do not translate")));
554     _act_grp->add(Gtk::Action::create("ZoomDrawing",
555                                       Stock::ZOOM_DRAWING, Glib::ustring(),
556                                       _("PLACEHOLDER, do not translate")));
558     _act_grp->add(Gtk::Action::create("ZoomPage",
559                                       Stock::ZOOM_PAGE, Glib::ustring(),
560                                       _("PLACEHOLDER, do not translate")));
562     _act_grp->add(Gtk::Action::create("ZoomWidth",
563                                       Stock::ZOOM_WIDTH, Glib::ustring(),
564                                       _("PLACEHOLDER, do not translate")));
566     _act_grp->add(Gtk::Action::create("ZoomPrev",
567                                       Stock::ZOOM_PREV, Glib::ustring(),
568                                       _("PLACEHOLDER, do not translate")));
570     _act_grp->add(Gtk::Action::create("ZoomNext",
571                                       Stock::ZOOM_NEXT, Glib::ustring(),
572                                       _("PLACEHOLDER, do not translate")));
574     _act_grp->add(Gtk::Action::create("ShowHide",
575                                       Stock::SHOW_HIDE));
577     _act_grp->add(Gtk::ToggleAction::create("ShowHideCommandsBar",
578                                             Stock::SHOW_HIDE_COMMANDS_BAR));
580     _act_grp->add(Gtk::ToggleAction::create("ShowHideToolControlsBar",
581                                             Stock::SHOW_HIDE_TOOL_CONTROLS_BAR));
583     _act_grp->add(Gtk::ToggleAction::create("ShowHideToolsBar",
584                                             Stock::SHOW_HIDE_TOOLS_BAR));
586     _act_grp->add(Gtk::ToggleAction::create("ShowHideRulers",
587                                             Stock::SHOW_HIDE_RULERS));
589     _act_grp->add(Gtk::ToggleAction::create("ShowHideScrollbars",
590                                             Stock::SHOW_HIDE_SCROLLBARS));
592     _act_grp->add(Gtk::ToggleAction::create("ShowHideStatusbar",
593                                             Stock::SHOW_HIDE_STATUSBAR));
595     _act_grp->add(Gtk::Action::create("ShowHideDialogs",
596                                       Stock::SHOW_HIDE_DIALOGS));
598     _act_grp->add(Gtk::Action::create("Grid",
599                                       Stock::GRID));
601     _act_grp->add(Gtk::Action::create("Guides",
602                                       Stock::GUIDES));
604     _act_grp->add(Gtk::Action::create("Fullscreen",
605                                       Stock::FULLSCREEN));
607     _act_grp->add(Gtk::Action::create("Messages",
608                                       Stock::MESSAGES),
609                   sigc::mem_fun(*this, &EditWidget::onDialogMessages));
611     _act_grp->add(Gtk::Action::create("Scripts",
612                                       Stock::SCRIPTS));
614     _act_grp->add(Gtk::Action::create("WindowPrev",
615                                       Stock::WINDOW_PREV));
617     _act_grp->add(Gtk::Action::create("WindowNext",
618                                       Stock::WINDOW_NEXT));
620     _act_grp->add(Gtk::Action::create("WindowDuplicate",
621                                       Stock::WINDOW_DUPLICATE));
623     // Layer menu
624     _act_grp->add(Gtk::Action::create("LayerNew",
625                                       Stock::LAYER_NEW));
627     _act_grp->add(Gtk::Action::create("LayerRename",
628                                       Stock::LAYER_RENAME));
630     _act_grp->add(Gtk::Action::create("LayerDuplicate",
631                                       Stock::LAYER_DUPLICATE));
633     _act_grp->add(Gtk::Action::create("LayerAnchor",
634                                       Stock::LAYER_ANCHOR));
636     _act_grp->add(Gtk::Action::create("LayerMergeDown",
637                                       Stock::LAYER_MERGE_DOWN));
639     _act_grp->add(Gtk::Action::create("LayerDelete",
640                                       Stock::LAYER_DELETE));
642     _act_grp->add(Gtk::Action::create("LayerSelectNext",
643                                       Stock::LAYER_SELECT_NEXT));
645     _act_grp->add(Gtk::Action::create("LayerSelectPrev",
646                                       Stock::LAYER_SELECT_PREV));
648     _act_grp->add(Gtk::Action::create("LayerSelectTop",
649                                       Stock::LAYER_SELECT_TOP));
651     _act_grp->add(Gtk::Action::create("LayerSelectBottom",
652                                       Stock::LAYER_SELECT_BOTTOM));
654     _act_grp->add(Gtk::Action::create("LayerRaise",
655                                       Stock::LAYER_RAISE));
657     _act_grp->add(Gtk::Action::create("LayerLower",
658                                       Stock::LAYER_LOWER));
660     _act_grp->add(Gtk::Action::create("LayerToTop",
661                                       Stock::LAYER_TO_TOP));
663     _act_grp->add(Gtk::Action::create("LayerToBottom",
664                                       Stock::LAYER_TO_BOTTOM));
666     // Object menu
667     _act_grp->add(Gtk::Action::create("FillAndStroke",
668                                       Stock::FILL_STROKE, Glib::ustring(),
669                                       _("PLACEHOLDER, do not translate")),
670                   sigc::mem_fun(*this, &EditWidget::onDialogFillAndStroke));
672     _act_grp->add(Gtk::Action::create("ObjectProperties",
673                                       Stock::OBJECT_PROPERTIES),
674                   sigc::mem_fun(*this, &EditWidget::onDialogObjectProperties));
676     _act_grp->add(Gtk::Action::create("Group",
677                                       Stock::GROUP, Glib::ustring(),
678                                       _("PLACEHOLDER, do not translate")));
680     _act_grp->add(Gtk::Action::create("Ungroup",
681                                       Stock::UNGROUP, Glib::ustring(),
682                                       _("PLACEHOLDER, do not translate")));
684     _act_grp->add(Gtk::Action::create("Raise",
685                                       Stock::RAISE, Glib::ustring(),
686                                       _("PLACEHOLDER, do not translate")));
688     _act_grp->add(Gtk::Action::create("Lower",
689                                       Stock::LOWER, Glib::ustring(),
690                                       _("PLACEHOLDER, do not translate")));
692     _act_grp->add(Gtk::Action::create("RaiseToTop",
693                                       Stock::RAISE_TO_TOP, Glib::ustring(),
694                                       _("PLACEHOLDER, do not translate")));
696     _act_grp->add(Gtk::Action::create("LowerToBottom",
697                                       Stock::LOWER_TO_BOTTOM, Glib::ustring(),
698                                       _("PLACEHOLDER, do not translate")));
700     _act_grp->add(Gtk::Action::create("MoveToNewLayer",
701                                       Stock::MOVE_TO_NEW_LAYER, Glib::ustring(),
702                                       _("PLACEHOLDER, do not translate")));
704     _act_grp->add(Gtk::Action::create("MoveToNextLayer",
705                                       Stock::MOVE_TO_NEXT_LAYER, Glib::ustring(),
706                                       _("PLACEHOLDER, do not translate")));
708     _act_grp->add(Gtk::Action::create("MoveToPrevLayer",
709                                       Stock::MOVE_TO_PREV_LAYER, Glib::ustring(),
710                                       _("PLACEHOLDER, do not translate")));
712     _act_grp->add(Gtk::Action::create("MoveToTopLayer",
713                                       Stock::MOVE_TO_TOP_LAYER, Glib::ustring(),
714                                       _("PLACEHOLDER, do not translate")));
716     _act_grp->add(Gtk::Action::create("MoveToBottomLayer",
717                                       Stock::MOVE_TO_BOTTOM_LAYER, Glib::ustring(),
718                                       _("PLACEHOLDER, do not translate")));
720     _act_grp->add(Gtk::Action::create("Rotate90CW",
721                                       Stock::ROTATE_90_CW, Glib::ustring(),
722                                       _("PLACEHOLDER, do not translate")));
724     _act_grp->add(Gtk::Action::create("Rotate90CCW",
725                                       Stock::ROTATE_90_CCW, Glib::ustring(),
726                                       _("PLACEHOLDER, do not translate")));
728     _act_grp->add(Gtk::Action::create("FlipHoriz",
729                                       Stock::FLIP_HORIZ, Glib::ustring(),
730                                       _("PLACEHOLDER, do not translate")));
732     _act_grp->add(Gtk::Action::create("FlipVert",
733                                       Stock::FLIP_VERT, Glib::ustring(),
734                                       _("PLACEHOLDER, do not translate")));
736     _act_grp->add(Gtk::Action::create("Transformation",
737                                       Stock::TRANSFORMATION, Glib::ustring(),
738                                       _("PLACEHOLDER, do not translate")),
739                   sigc::mem_fun(*this, &EditWidget::onDialogTransformation));
741     _act_grp->add(Gtk::Action::create("AlignAndDistribute",
742                                       Stock::ALIGN_DISTRIBUTE, Glib::ustring(),
743                                       _("PLACEHOLDER, do not translate")),
744                   sigc::mem_fun(*this, &EditWidget::onDialogAlignAndDistribute));
746     // Path menu
747     _act_grp->add(Gtk::Action::create("ObjectToPath",
748                                       Stock::OBJECT_TO_PATH, Glib::ustring(),
749                                       _("PLACEHOLDER, do not translate")));
751     _act_grp->add(Gtk::Action::create("StrokeToPath",
752                                       Stock::STROKE_TO_PATH, Glib::ustring(),
753                                       _("PLACEHOLDER, do not translate")));
755     _act_grp->add(Gtk::Action::create("Trace",
756                                       Stock::TRACE),
757                   sigc::mem_fun(*this, &EditWidget::onDialogTrace));
759     _act_grp->add(Gtk::Action::create("Union",
760                                       Stock::UNION));
762     _act_grp->add(Gtk::Action::create("Difference",
763                                       Stock::DIFFERENCE));
765     _act_grp->add(Gtk::Action::create("Intersection",
766                                       Stock::INTERSECTION));
768     _act_grp->add(Gtk::Action::create("Exclusion",
769                                       Stock::EXCLUSION));
771     _act_grp->add(Gtk::Action::create("Division",
772                                       Stock::DIVISION));
774     _act_grp->add(Gtk::Action::create("CutPath",
775                                       Stock::CUT_PATH));
777     _act_grp->add(Gtk::Action::create("Combine",
778                                       Stock::COMBINE));
780     _act_grp->add(Gtk::Action::create("BreakApart",
781                                       Stock::BREAK_APART));
783     _act_grp->add(Gtk::Action::create("Inset",
784                                       Stock::INSET));
786     _act_grp->add(Gtk::Action::create("Outset",
787                                       Stock::OUTSET));
789     _act_grp->add(Gtk::Action::create("OffsetDynamic",
790                                       Stock::OFFSET_DYNAMIC));
792     _act_grp->add(Gtk::Action::create("OffsetLinked",
793                                       Stock::OFFSET_LINKED));
795     _act_grp->add(Gtk::Action::create("Simplify",
796                                       Stock::SIMPLIFY));
798     _act_grp->add(Gtk::Action::create("Reverse",
799                                       Stock::REVERSE));
801     _act_grp->add(Gtk::Action::create("Cleanup",
802                                       Gtk::Stock::CLEAR,
803                                       _("PLACEHOLDER, do not translate")));
805     // Text menu
806     _act_grp->add(Gtk::Action::create("TextProperties",
807                                       Gtk::Stock::SELECT_FONT, Glib::ustring(),
808                                       _("PLACEHOLDER, do not translate")),
809                   sigc::mem_fun(*this, &EditWidget::onDialogTextProperties));
811     _act_grp->add(Gtk::Action::create("PutOnPath",
812                                       Stock::PUT_ON_PATH));
814     _act_grp->add(Gtk::Action::create("RemoveFromPath",
815                                       Stock::REMOVE_FROM_PATH));
817     _act_grp->add(Gtk::Action::create("RemoveManualKerns",
818                                       Stock::REMOVE_MANUAL_KERNS));
820         // Whiteboard menu
821 #ifdef WITH_INKBOARD
822     _act_grp->add(Gtk::Action::create("DialogWhiteboardConnect",
823                                       Gtk::Stock::CLEAR, Glib::ustring(),
824                                       _("PLACEHOLDER, do not translate")),
825                   sigc::mem_fun(*this, &EditWidget::onDialogWhiteboardConnect));
827     _act_grp->add(Gtk::Action::create("DialogWhiteboardShareWithUser",
828                                       Gtk::Stock::CLEAR, Glib::ustring(),
829                                       _("PLACEHOLDER, do not translate")),
830                   sigc::mem_fun(*this, &EditWidget::onDialogWhiteboardShareWithUser));
832     _act_grp->add(Gtk::Action::create("DialogWhiteboardShareWithChat",
833                                       Gtk::Stock::CLEAR, Glib::ustring(),
834                                       _("PLACEHOLDER, do not translate")),
835                   sigc::mem_fun(*this, &EditWidget::onDialogWhiteboardShareWithChat));
837     _act_grp->add(Gtk::Action::create("WhiteboardOpenSessionFile",
838                                       Gtk::Stock::CLEAR, Glib::ustring(),
839                                       _("PLACEHOLDER, do not translate")),
840                   sigc::mem_fun(*this, &EditWidget::onDialogOpenSessionFile));
842     _act_grp->add(Gtk::Action::create("WhiteboardDumpXMLTracker",
843                                       Gtk::Stock::CLEAR, Glib::ustring(),
844                                       _("PLACEHOLDER, do not translate")),
845                   sigc::mem_fun(*this, &EditWidget::onDumpXMLTracker));
846 #endif
848     // About menu
849     _act_grp->add(Gtk::Action::create("KeysAndMouse",
850                                       Stock::KEYS_MOUSE));
852     _act_grp->add(Gtk::Action::create("Tutorials",
853                                       Stock::TUTORIALS));
855     _act_grp->add(Gtk::Action::create("About",
856                                       Stock::ABOUT),
857                   sigc::mem_fun(*this, &EditWidget::onDialogAbout));
860 void
861 EditWidget::initToolbarActions()
863     // Tools bar
864     Gtk::RadioAction::Group tools;
866     _act_grp->add(Gtk::RadioAction::create(tools, "ToolSelect",
867                                            Stock::TOOL_SELECT, Glib::ustring(),
868                                            _("PLACEHOLDER, do not translate")),
869                   sigc::mem_fun(*this, &EditWidget::onSelectTool));
871     _act_grp->add(Gtk::RadioAction::create(tools, "ToolNode",
872                                            Stock::TOOL_NODE, Glib::ustring(),
873                                            _("PLACEHOLDER, do not translate")),
874                   sigc::mem_fun(*this, &EditWidget::onNodeTool));
876     _act_grp->add(Gtk::RadioAction::create(tools, "ToolZoom",
877                                            Stock::TOOL_ZOOM, Glib::ustring(),
878                                            _("PLACEHOLDER, do not translate")));
880     _act_grp->add(Gtk::RadioAction::create(tools, "ToolRect",
881                                            Stock::TOOL_RECT, Glib::ustring(),
882                                            _("PLACEHOLDER, do not translate")));
884     _act_grp->add(Gtk::RadioAction::create(tools, "ToolArc",
885                                            Stock::TOOL_ARC, Glib::ustring(),
886                                            _("PLACEHOLDER, do not translate")));
888     _act_grp->add(Gtk::RadioAction::create(tools, "ToolStar",
889                                            Stock::TOOL_STAR, Glib::ustring(),
890                                            _("PLACEHOLDER, do not translate")));
892     _act_grp->add(Gtk::RadioAction::create(tools, "ToolSpiral",
893                                            Stock::TOOL_SPIRAL, Glib::ustring(),
894                                            _("PLACEHOLDER, do not translate")));
896     _act_grp->add(Gtk::RadioAction::create(tools, "ToolFreehand",
897                                            Stock::TOOL_FREEHAND, Glib::ustring(),
898                                            _("PLACEHOLDER, do not translate")));
900     _act_grp->add(Gtk::RadioAction::create(tools, "ToolPen",
901                                            Stock::TOOL_PEN, Glib::ustring(),
902                                            _("PLACEHOLDER, do not translate")));
904     _act_grp->add(Gtk::RadioAction::create(tools, "ToolDynaDraw",
905                                            Stock::TOOL_DYNADRAW, Glib::ustring(),
906                                            _("PLACEHOLDER, do not translate")));
908     _act_grp->add(Gtk::RadioAction::create(tools, "ToolText",
909                                            Stock::TOOL_TEXT, Glib::ustring(),
910                                            _("PLACEHOLDER, do not translate")));
912     _act_grp->add(Gtk::RadioAction::create(tools, "ToolDropper",
913                                            Stock::TOOL_DROPPER, Glib::ustring(),
914                                            _("PLACEHOLDER, do not translate")));
916     // Select Controls bar
917     _act_grp->add(Gtk::ToggleAction::create("TransformStroke",
918                                             Stock::TRANSFORM_STROKE, Glib::ustring(),
919                                             _("PLACEHOLDER, do not translate")));
921     _act_grp->add(Gtk::ToggleAction::create("TransformCorners",
922                                             Stock::TRANSFORM_CORNERS, Glib::ustring(),
923                                             _("PLACEHOLDER, do not translate")));
925     _act_grp->add(Gtk::ToggleAction::create("TransformGradient",
926                                             Stock::TRANSFORM_GRADIENT, Glib::ustring(),
927                                             _("PLACEHOLDER, do not translate")));
929     _act_grp->add(Gtk::ToggleAction::create("TransformPattern",
930                                             Stock::TRANSFORM_PATTERN, Glib::ustring(),
931                                             _("PLACEHOLDER, do not translate")));
933     // Node Controls bar
934     _act_grp->add(Gtk::Action::create("NodeInsert",
935                                       Gtk::Stock::ADD, Glib::ustring(),
936                                       _("PLACEHOLDER, do not translate")));
938     _act_grp->add(Gtk::Action::create("NodeDelete",
939                                       Gtk::Stock::REMOVE, Glib::ustring(),
940                                       _("PLACEHOLDER, do not translate")));
942     _act_grp->add(Gtk::Action::create("NodeJoin",
943                                       Stock::NODE_JOIN, Glib::ustring(),
944                                       _("PLACEHOLDER, do not translate")));
946     _act_grp->add(Gtk::Action::create("NodeJoinSegment",
947                                       Stock::NODE_JOIN_SEGMENT, Glib::ustring(),
948                                       _("PLACEHOLDER, do not translate")));
950     _act_grp->add(Gtk::Action::create("NodeDeleteSegment",
951                                       Stock::NODE_DELETE_SEGMENT, Glib::ustring(),
952                                       _("PLACEHOLDER, do not translate")));
954     _act_grp->add(Gtk::Action::create("NodeBreak",
955                                       Stock::NODE_BREAK, Glib::ustring(),
956                                       _("PLACEHOLDER, do not translate")));
958     _act_grp->add(Gtk::Action::create("NodeCorner",
959                                       Stock::NODE_CORNER, Glib::ustring(),
960                                       _("PLACEHOLDER, do not translate")));
962     _act_grp->add(Gtk::Action::create("NodeSmooth",
963                                       Stock::NODE_SMOOTH, Glib::ustring(),
964                                       _("PLACEHOLDER, do not translate")));
966     _act_grp->add(Gtk::Action::create("NodeSymmetric",
967                                       Stock::NODE_SYMMETRIC, Glib::ustring(),
968                                       _("PLACEHOLDER, do not translate")));
970     _act_grp->add(Gtk::Action::create("NodeLine",
971                                       Stock::NODE_LINE, Glib::ustring(),
972                                       _("PLACEHOLDER, do not translate")));
974     _act_grp->add(Gtk::Action::create("NodeCurve",
975                                       Stock::NODE_CURVE, Glib::ustring(),
976                                       _("PLACEHOLDER, do not translate")));
979 void
980 EditWidget::initAccelMap()
982     gchar *filename = g_build_filename(INKSCAPE_UIDIR, "keybindings.rc", NULL);
983     Gtk::AccelMap::load(filename);
984     g_free(filename);
986     // One problem is that the keys 1-6 are zoom accelerators which get
987     // caught as accelerator _before_ any Entry input handler receives them,
988     // for example the zoom status. At the moment, the best way seems to
989     // disable them as accelerators when the Entry gets focus, and enable
990     // them when focus goes elsewhere. The code for this belongs here,
991     // and not in zoom-status.cpp .
993     _zoom_status.signal_focus_in_event().connect (sigc::mem_fun (*this, &EditWidget::onEntryFocusIn));
994     _zoom_status.signal_focus_out_event().connect (sigc::mem_fun (*this, &EditWidget::onEntryFocusOut));
997 bool
998 EditWidget::onEntryFocusIn (GdkEventFocus* ev)
1000     Gdk::ModifierType m = static_cast<Gdk::ModifierType>(0);
1001     Gtk::AccelMap::change_entry ("<Actions>//Zoom100", 0, m, false);
1002     Gtk::AccelMap::change_entry ("<Actions>//Zoom50", 0, m, false);
1003     Gtk::AccelMap::change_entry ("<Actions>//ZoomSelection", 0, m, false);
1004     Gtk::AccelMap::change_entry ("<Actions>//ZoomDrawing", 0, m, false);
1005     Gtk::AccelMap::change_entry ("<Actions>//ZoomPage", 0, m, false);
1006     Gtk::AccelMap::change_entry ("<Actions>//ZoomWidth", 0, m, false);
1007     return false;
1010 bool
1011 EditWidget::onEntryFocusOut (GdkEventFocus* ev)
1013     Gdk::ModifierType m = static_cast<Gdk::ModifierType>(0);
1014     Gtk::AccelMap::change_entry ("<Actions>//Zoom100", '1', m, false);
1015     Gtk::AccelMap::change_entry ("<Actions>//Zoom50", '2', m, false);
1016     Gtk::AccelMap::change_entry ("<Actions>//ZoomSelection", '3', m, false);
1017     Gtk::AccelMap::change_entry ("<Actions>//ZoomDrawing", '4', m, false);
1018     Gtk::AccelMap::change_entry ("<Actions>//ZoomPage", '5', m, false);
1019     Gtk::AccelMap::change_entry ("<Actions>//ZoomWidth", '6', m, false);
1020     return false;
1023 void
1024 EditWidget::initMenuBar()
1026     g_assert(_ui_mgr);
1027     Gtk::MenuBar *menu = static_cast<Gtk::MenuBar*>(_ui_mgr->get_widget("/MenuBar"));
1028     g_assert(menu != NULL);
1029     _main_window_table.attach(*Gtk::manage(menu), 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1032 void
1033 EditWidget::initCommandsBar()
1035     g_assert(_ui_mgr);
1036     Toolbox *bar = new Toolbox(static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/CommandsBar")),
1037                                Gtk::TOOLBAR_ICONS);
1038     g_assert(bar != NULL);
1039     _toolbars_vbox.pack_start(*Gtk::manage(bar), Gtk::PACK_SHRINK);
1042 void
1043 EditWidget::initToolControlsBar()
1045     // TODO: Do UIManager controlled widgets need to be deleted?
1046     _select_ctrl = static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/SelectControlsBar"));
1047     _node_ctrl = static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/NodeControlsBar"));
1049     _tool_ctrl = new Toolbox(_select_ctrl, Gtk::TOOLBAR_ICONS);
1051     _toolbars_vbox.pack_start(*Gtk::manage(_tool_ctrl), Gtk::PACK_SHRINK);
1054 void
1055 EditWidget::initUriBar()
1057     /// \todo  Create an Inkscape::UI::Widget::UriBar class (?)
1059     _uri_ctrl = new Gtk::Toolbar();
1061     _uri_label.set_label(_("PLACEHOLDER, DO NOT TRANSLATE"));
1062     _uri_ctrl->add(_uri_label);
1063     _uri_ctrl->add(_uri_entry);
1065     _uri_entry.signal_activate()
1066         .connect_notify(sigc::mem_fun(*this, &EditWidget::onUriChanged));
1068     _toolbars_vbox.pack_start(*Gtk::manage(_uri_ctrl), Gtk::PACK_SHRINK);
1071 void
1072 EditWidget::initToolsBar()
1074     Toolbox *bar = new Toolbox(static_cast<Gtk::Toolbar*>(_ui_mgr->get_widget("/ToolsBar")),
1075                                Gtk::TOOLBAR_ICONS,
1076                                Gtk::ORIENTATION_VERTICAL);
1077     g_assert(bar != NULL);
1078     _sub_window_hbox.pack_start(*Gtk::manage(bar), Gtk::PACK_SHRINK);
1081 void
1082 EditWidget::initTopRuler()
1084     _viewport_table.attach(_top_ruler,  1, 2, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1085     
1086     _tooltips.set_tip (_top_ruler, _top_ruler.get_tip());
1089 void
1090 EditWidget::initLeftRuler()
1092     _viewport_table.attach(_left_ruler, 0, 1, 1, 2, Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
1093     
1094     _tooltips.set_tip (_left_ruler, _left_ruler.get_tip());
1097 void
1098 EditWidget::initBottomScrollbar()
1100     _viewport_table.attach(_bottom_scrollbar, 1, 2, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
1101     _bottom_scrollbar.signal_value_changed().connect (sigc::mem_fun (*this, &EditWidget::onAdjValueChanged));
1102     _bottom_scrollbar.property_adjustment() = new Gtk::Adjustment (0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0);
1105 void
1106 EditWidget::initRightScrollbar()
1108     _viewport_table.attach(_right_scrollbar, 2, 3, 1, 2, Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
1110     _right_scrollbar.signal_value_changed().connect (sigc::mem_fun (*this, &EditWidget::onAdjValueChanged));
1111     _right_scrollbar.property_adjustment() = new Gtk::Adjustment (0.0, -4000.0, 4000.0, 10.0, 100.0, 4.0);
1114 void 
1115 EditWidget::initStickyZoom()
1117     _viewport_table.attach(_sticky_zoom, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
1119     _sticky_zoom.set_active (prefs_get_int_attribute ("options.stickyzoom", "value", 0) != 0);
1120     _tooltips.set_tip (_sticky_zoom, _("Zoom drawing if window size changes"));
1121     
1122     /// \todo icon not implemented
1125 void
1126 EditWidget::initStatusbar()
1128     _statusbar.pack_start (_selected_style_status, false, false, 1);
1129     _statusbar.pack_start (*new Gtk::VSeparator(), false, false, 0);
1131     _tooltips.set_tip (_zoom_status, _("Zoom"));
1133     _layer_selector.reference();
1134     _statusbar.pack_start (_layer_selector, false, false, 1);
1136     _coord_status.property_n_rows() = 2;    
1137     _coord_status.property_n_columns() = 5;    
1138     _coord_status.property_row_spacing() = 0;
1139     _coord_status.property_column_spacing() = 2;
1140     _coord_eventbox.add (_coord_status);
1141     _tooltips.set_tip (_coord_eventbox, _("Cursor coordinates"));
1142     _coord_status.attach (*new Gtk::VSeparator(), 0,1, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1143     _coord_status.attach (*new Gtk::Label("X:", 0.0, 0.5), 1,2, 0,1, Gtk::FILL,Gtk::FILL, 0,0);
1144     _coord_status.attach (*new Gtk::Label("Y:", 0.0, 0.5), 1,2, 1,2, Gtk::FILL,Gtk::FILL, 0,0);
1145     _coord_status_x.set_text ("0.0");
1146     _coord_status_x.set_alignment (0.0, 0.5);
1147     _coord_status_y.set_text ("0.0");
1148     _coord_status_y.set_alignment (0.0, 0.5);
1149     _coord_status.attach (_coord_status_x, 2,3, 0,1, Gtk::FILL,Gtk::FILL, 0,0);
1150     _coord_status.attach (_coord_status_y, 2,3, 1,2, Gtk::FILL,Gtk::FILL, 0,0);
1151     _coord_status.attach (*new Gtk::Label("Z:", 0.0, 0.5), 3,4, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1152     _coord_status.attach (_zoom_status, 4,5, 0,2, Gtk::FILL,Gtk::FILL, 0,0);
1153     sp_set_font_size_smaller (static_cast<GtkWidget*>((void*)_coord_status.gobj()));
1154     _statusbar.pack_end (_coord_eventbox, false, false, 1);
1156     _select_status.property_xalign() = 0.0;
1157     _select_status.property_yalign() = 0.5;
1158     _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."));
1159     // include this again with Gtk+-2.6
1160 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 6
1161     _select_status.property_ellipsize() = Pango::ELLIPSIZE_END;
1162 #endif
1163     _select_status.set_size_request (1, -1);
1164     _statusbar.pack_start (_select_status, true, true, 0);
1165     
1166     _main_window_table.attach(_statusbar, 0, 1, 3, 4, Gtk::FILL, Gtk::SHRINK);
1169 //========================================
1170 //----------implements EditWidgetInterface
1172 void *
1173 EditWidget::getWindow() 
1174
1175     return this; 
1178 void 
1179 EditWidget::setTitle (gchar const* new_title) 
1181     set_title (new_title);    
1184 void 
1185 EditWidget::layout() 
1187    show_all_children();
1190 void 
1191 EditWidget::present() 
1193     this->Gtk::Window::present();
1196 void 
1197 EditWidget::getGeometry (gint &x, gint &y, gint &w, gint &h) 
1199     get_position (x, y);
1200     get_size (w, h);
1203 void 
1204 EditWidget::setSize (gint w, gint h) 
1206     resize (w, h);
1209 void 
1210 EditWidget::setPosition (NR::Point p) 
1212     move (int(p[NR::X]), int(p[NR::Y]));
1215 /// \param p is already gobj()!
1216 void 
1217 EditWidget::setTransient (void* p, int i) 
1219 #ifndef WIN32
1220     gtk_window_set_transient_for (static_cast<GtkWindow*>(p), this->gobj());
1221     if (i==2)
1222         this->Gtk::Window::present();
1223 #endif
1226 NR::Point 
1227 EditWidget::getPointer() 
1228
1229     int x, y;
1230     get_pointer (x, y);
1231     return NR::Point (x, y); 
1234 void 
1235 EditWidget::setFullscreen() 
1237     fullscreen();
1240 /**
1241  *  Shuts down the desktop object for the view being closed.  It checks
1242  *  to see if the document has been edited, and if so prompts the user
1243  *  to save, discard, or cancel.  Returns TRUE if the shutdown operation
1244  *  is cancelled or if the save is cancelled or fails, FALSE otherwise.
1245  */
1246 bool 
1247 EditWidget::shutdown() 
1249     g_assert (_desktop != NULL);
1250     if (Inkscape::NSApplication::Editor::isDuplicatedView (_desktop))
1251         return false;
1253     SPDocument *doc = _desktop->doc();
1254     if (sp_document_repr_root(doc)->attribute("sodipodi:modified") != NULL) 
1255     {
1256         gchar *markup;
1257         /// \todo FIXME !!! obviously this will have problems if the document 
1258         /// name contains markup characters
1259         markup = g_strdup_printf(
1260                 _("<span weight=\"bold\" size=\"larger\">Save changes to document \"%s\" before closing?</span>\n\n"
1261                   "If you close without saving, your changes will be discarded."),
1262                 SP_DOCUMENT_NAME(doc));
1263         
1264         Gtk::MessageDialog dlg (*this, 
1265                        markup,
1266                        true,
1267                        Gtk::MESSAGE_WARNING,
1268                        Gtk::BUTTONS_NONE,
1269                        true);
1270         g_free(markup);
1271         Gtk::Button close_button (_("Close _without saving"), true);
1272         dlg.add_action_widget (close_button, Gtk::RESPONSE_NO);
1273         close_button.show();
1274         dlg.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1275         dlg.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_YES);
1276         dlg.set_default_response (Gtk::RESPONSE_YES);
1278         int response = dlg.run();
1279         switch (response) 
1280         {
1281             case Gtk::RESPONSE_YES:
1282                 sp_document_ref(doc);
1283                 if (sp_file_save_document(doc)) {
1284                     sp_document_unref(doc);
1285                 } else { // save dialog cancelled or save failed
1286                     sp_document_unref(doc);
1287                     return TRUE;
1288                 }
1289                 break;
1290             case Gtk::RESPONSE_NO:
1291                 break;
1292             default: // cancel pressed, or dialog was closed
1293                 return TRUE;
1294                 break;
1295         }
1296     }
1298     /* Code to check data loss */
1299     bool allow_data_loss = FALSE;
1300     while (sp_document_repr_root(doc)->attribute("inkscape:dataloss") != NULL && allow_data_loss == FALSE) 
1301     {
1302         gchar *markup;
1303         /// \todo FIXME !!! obviously this will have problems if the document 
1304         /// name contains markup characters
1305         markup = g_strdup_printf(
1306                 _("<span weight=\"bold\" size=\"larger\">The file \"%s\" was saved with a format (%s) that may cause data loss!</span>\n\n"
1307                   "Do you want to save this file in another format?"),
1308                 SP_DOCUMENT_NAME(doc),
1309                 Inkscape::Extension::db.get(sp_document_repr_root(doc)->attribute("inkscape:output_extension"))->get_name());
1310         
1311         Gtk::MessageDialog dlg (*this, 
1312                        markup,
1313                        true,
1314                        Gtk::MESSAGE_WARNING,
1315                        Gtk::BUTTONS_NONE,
1316                        true);
1317         g_free(markup);
1318         Gtk::Button close_button (_("Close _without saving"), true);
1319         dlg.add_action_widget (close_button, Gtk::RESPONSE_NO);
1320         close_button.show();
1321         dlg.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1322         dlg.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_YES);
1323         dlg.set_default_response (Gtk::RESPONSE_YES);
1325         int response = dlg.run();
1326         
1327         switch (response) 
1328         {
1329             case Gtk::RESPONSE_YES:
1330                 sp_document_ref(doc);
1331                 if (sp_file_save_document(doc)) {
1332                     sp_document_unref(doc);
1333                 } else { // save dialog cancelled or save failed
1334                     sp_document_unref(doc);
1335                     return TRUE;
1336                 }
1337                 break;
1338             case Gtk::RESPONSE_NO:
1339                 allow_data_loss = TRUE;
1340                 break;
1341             default: // cancel pressed, or dialog was closed
1342                 return TRUE;
1343                 break;
1344         }
1345     }
1346     
1347     return false;
1351 void 
1352 EditWidget::destroy() 
1353
1354     delete this; 
1357 void 
1358 EditWidget::requestCanvasUpdate() 
1360     _svg_canvas.widget().queue_draw();
1363 void 
1364 EditWidget::activateDesktop() 
1366     /// \todo active_desktop_indicator not implemented 
1369 void 
1370 EditWidget::deactivateDesktop() 
1372     /// \todo active_desktop_indicator not implemented
1375 void 
1376 EditWidget::viewSetPosition (NR::Point p) 
1378     p -= _namedview->gridorigin;
1379     double lo, up, pos, max;
1380     _top_ruler.get_range (lo, up, pos, max);
1381     _top_ruler.set_range (lo, up, p[NR::X], max);
1382     _left_ruler.get_range (lo, up, pos, max);
1383     _left_ruler.set_range (lo, up, p[NR::Y], max);
1386 void 
1387 EditWidget::updateRulers() 
1388 {    
1389     NR::Point origin = _namedview->gridorigin;
1391     NR::Rect const viewbox = _svg_canvas.spobj()->getViewbox();
1392     double lo, up, pos, max;
1393     double const scale = _desktop->current_zoom();
1394     double s = viewbox.min()[NR::X] / scale - origin[NR::X];
1395     double e = viewbox.max()[NR::X] / scale - origin[NR::X];
1396     _top_ruler.get_range(lo, up, pos, max);
1397     _top_ruler.set_range(s, e, pos, e);
1398     s = viewbox.min()[NR::Y] / -scale - origin[NR::Y];
1399     e = viewbox.max()[NR::Y] / -scale - origin[NR::Y];
1400     _left_ruler.set_range(s, e, origin[NR::Y], e);
1401     /// \todo is that correct?
1404 void 
1405 EditWidget::updateScrollbars (double scale) 
1407     // do not call this function before canvas has its size allocated
1408     if (!is_realized() || _update_s_f) {
1409         return;
1410     }
1412     _update_s_f = true;
1414     /* The desktop region we always show unconditionally */
1415     SPDocument *doc = _desktop->doc();
1416     NR::Rect const r = sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc)));
1417     NR::Rect darea(NR::Point(MIN(r.min()[NR::X], -sp_document_width(doc)),
1418                              MIN(r.min()[NR::Y], -sp_document_height(doc))),
1419                    NR::Point(MAX(r.max()[NR::X], 2 * sp_document_width(doc)),
1420                              MAX(r.max()[NR::Y], 2 * sp_document_height(doc))));
1422     /* Canvas region we always show unconditionally */
1423     NR::Rect carea(NR::Point(darea.min()[NR::X] * scale - 64,
1424                              darea.max()[NR::Y] * -scale - 64),
1425                    NR::Point(darea.max()[NR::X] * scale + 64,
1426                              darea.min()[NR::Y] * -scale + 64));
1428     NR::Rect const viewbox = _svg_canvas.spobj()->getViewbox();
1430     /* Viewbox is always included into scrollable region */
1431     carea = NR::Rect::union_bounds(carea, viewbox);
1433     Gtk::Adjustment *adj = _bottom_scrollbar.get_adjustment();
1434     adj->set_value(viewbox.min()[NR::X]);
1435     adj->set_lower(carea.min()[NR::X]);
1436     adj->set_upper(carea.max()[NR::X]);
1437     adj->set_page_increment(viewbox.dimensions()[NR::X]);
1438     adj->set_step_increment(0.1 * (viewbox.dimensions()[NR::X]));
1439     adj->set_page_size(viewbox.dimensions()[NR::X]);
1441     adj = _right_scrollbar.get_adjustment();
1442     adj->set_value(viewbox.min()[NR::Y]);
1443     adj->set_lower(carea.min()[NR::Y]);
1444     adj->set_upper(carea.max()[NR::Y]);
1445     adj->set_page_increment(viewbox.dimensions()[NR::Y]);
1446     adj->set_step_increment(0.1 * viewbox.dimensions()[NR::Y]);
1447     adj->set_page_size(viewbox.dimensions()[NR::Y]);
1449     _update_s_f = false;
1452 void
1453 EditWidget::toggleRulers() 
1455     if (_top_ruler.is_visible())
1456     {
1457         _top_ruler.hide_all();
1458         _left_ruler.hide_all();
1459         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 0);
1460     } else {
1461         _top_ruler.show_all();
1462         _left_ruler.show_all();
1463         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 1);
1464     }
1467 void 
1468 EditWidget::toggleScrollbars() 
1470     if (_bottom_scrollbar.is_visible())
1471     {
1472         _bottom_scrollbar.hide_all();
1473         _right_scrollbar.hide_all();
1474         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 0);
1475     } else {
1476         _bottom_scrollbar.show_all();
1477         _right_scrollbar.show_all();
1478         prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 1);
1479     }
1482 void 
1483 EditWidget::updateZoom() 
1485     _zoom_status.update();
1488 void 
1489 EditWidget::letZoomGrabFocus() 
1491     _zoom_status.grab_focus();
1494 void 
1495 EditWidget::setToolboxFocusTo (const gchar *)
1497     /// \todo not implemented
1500 void 
1501 EditWidget::setToolboxAdjustmentValue (const gchar *, double)
1503     /// \todo not implemented
1506 bool 
1507 EditWidget::isToolboxButtonActive (gchar const*)
1509     /// \todo not implemented
1510     return true;
1513 void 
1514 EditWidget::setCoordinateStatus (NR::Point p) 
1516     gchar *cstr = g_strdup_printf ("%6.2f", _dt2r * p[NR::X]);
1517     _coord_status_x.property_label() = cstr;
1518     g_free (cstr);
1519     cstr = g_strdup_printf ("%6.2f", _dt2r * p[NR::Y]);
1520     _coord_status_y.property_label() = cstr;
1521     g_free (cstr);
1524 void 
1525 EditWidget::setMessage (Inkscape::MessageType type, gchar const* msg) 
1527     _select_status.set_markup (msg? msg : "");
1530 bool 
1531 EditWidget::warnDialog (gchar* msg)
1533     Gtk::MessageDialog dlg (*this, 
1534                        msg,
1535                        true,
1536                        Gtk::MESSAGE_WARNING,
1537                        Gtk::BUTTONS_YES_NO,
1538                        true);
1539     int r = dlg.run();
1540     return r == Gtk::RESPONSE_YES;
1544 void 
1545 EditWidget::initEdit (SPDocument *doc)
1547     _desktop = new SPDesktop();
1548     _desktop->registerEditWidget (this);
1550     _namedview = sp_document_namedview (doc, 0);
1551     _svg_canvas.init (_desktop);
1552     _desktop->init (_namedview, _svg_canvas.spobj());
1553     sp_namedview_window_from_document (_desktop);
1554     _dt2r = 1.0 / _namedview->doc_units->unittobase;
1556     /// \todo convert to sigc++ when SPObject hierarchy gets converted
1557     /* Listen on namedview modification */
1558     g_signal_connect (G_OBJECT (_desktop->namedview), "modified", G_CALLBACK (_namedview_modified), this);
1559     _layer_selector.setDesktop (_desktop);
1560     _selected_style_status.setDesktop (_desktop);
1561  
1562     Inkscape::NSApplication::Editor::addDesktop (_desktop);
1564     _zoom_status.init (_desktop);
1565     _top_ruler.init (_desktop, _svg_canvas.widget());
1566     _left_ruler.init (_desktop, _svg_canvas.widget());
1567     updateRulers();
1570 void 
1571 EditWidget::destroyEdit()
1573     if (_desktop) {
1574         _layer_selector.unreference();
1575         Inkscape::NSApplication::Editor::removeDesktop (_desktop); // clears selection too
1576         sp_signal_disconnect_by_data (G_OBJECT (_desktop->namedview), this);
1577         _desktop->destroy();
1578         Inkscape::GC::release (_desktop);
1579         _desktop = 0;
1580     }
1583 //----------end of EditWidgetInterface implementation
1585 //----------start of other callbacks
1587 bool 
1588 EditWidget::on_key_press_event (GdkEventKey* event)
1590     // this is the original code from helper/window.cpp
1592     unsigned int shortcut;
1593     shortcut = get_group0_keyval (event) |
1594                    ( event->state & GDK_SHIFT_MASK ?
1595                      SP_SHORTCUT_SHIFT_MASK : 0 ) |
1596                    ( event->state & GDK_CONTROL_MASK ?
1597                      SP_SHORTCUT_CONTROL_MASK : 0 ) |
1598                    ( event->state & GDK_MOD1_MASK ?
1599                      SP_SHORTCUT_ALT_MASK : 0 );
1600     return sp_shortcut_invoke (shortcut, 
1601                              Inkscape::NSApplication::Editor::getActiveDesktop());
1604 bool 
1605 EditWidget::on_delete_event (GdkEventAny*)
1607     return shutdown();
1610 bool 
1611 EditWidget::on_focus_in_event (GdkEventFocus*)
1613     Inkscape::NSApplication::Editor::activateDesktop (_desktop);
1614     _svg_canvas.widget().grab_focus();
1616     return false;
1619 void
1620 EditWidget::onWindowSizeAllocate (Gtk::Allocation &newall)
1622     if (!is_realized()) return;
1623     
1624     const Gtk::Allocation& all = get_allocation();
1625     if ((newall.get_x() == all.get_x()) &&
1626         (newall.get_y() == all.get_y()) &&
1627         (newall.get_width() == all.get_width()) &&
1628         (newall.get_height() == all.get_height())) {
1629         return;
1630     }
1632     NR::Rect const area = _desktop->get_display_area();
1633     double zoom = _desktop->current_zoom();
1635     if (_sticky_zoom.get_active()) {
1636         /* Calculate zoom per pixel */
1637         double const zpsp = zoom / hypot(area.dimensions()[NR::X], area.dimensions()[NR::Y]);
1638         /* Find new visible area */
1639         NR::Rect const newarea = _desktop->get_display_area();
1640         /* Calculate adjusted zoom */
1641         zoom = zpsp * hypot(newarea.dimensions()[NR::X], newarea.dimensions()[NR::Y]);
1642     }
1644     _desktop->zoom_absolute(area.midpoint()[NR::X], area.midpoint()[NR::Y], zoom);
1647 void
1648 EditWidget::onWindowRealize()
1650     NR::Rect d(NR::Point(0, 0),
1651                NR::Point(sp_document_width(_desktop->doc()), sp_document_height(_desktop->doc())));
1653     if (fabs(d.dimensions()[NR::X]) < 1.0 || fabs(d.dimensions()[NR::Y]) < 1.0) {
1654         return;
1655     }
1657     _desktop->set_display_area(d.min()[NR::X], d.min()[NR::Y], d.max()[NR::X], d.max()[NR::Y], 10);
1658     _namedview_modified(_desktop->namedview, SP_OBJECT_MODIFIED_FLAG, this);
1659     setTitle (SP_DOCUMENT_NAME(_desktop->doc()));
1662 void
1663 EditWidget::onAdjValueChanged()
1665     if (_update_a_f) return;
1666     _update_a_f = true;
1667     
1668     sp_canvas_scroll_to (_svg_canvas.spobj(), 
1669                          _bottom_scrollbar.get_value(), 
1670                          _right_scrollbar.get_value(), 
1671                          false);
1672     updateRulers();
1673     
1674     _update_a_f = false;
1677 /// \todo make this a member function when the signal is a sigc++ signal
1678 void _namedview_modified (SPNamedView* nv, guint flags, EditWidget* ew)
1680     if (flags & SP_OBJECT_MODIFIED_FLAG)
1681     {
1682         ew->_dt2r = 1.0 / nv->doc_units->unittobase;
1683         ew->_top_ruler.update_metric();
1684         ew->_left_ruler.update_metric();
1685         ew->_tooltips.set_tip (ew->_top_ruler, ew->_top_ruler.get_tip());
1686         ew->_tooltips.set_tip (ew->_left_ruler, ew->_left_ruler.get_tip());
1687         ew->updateRulers();
1688     }
1691 } // namespace View
1692 } // namespace UI
1693 } // namespace Inkscape
1695 /*
1696   Local Variables:
1697   mode:c++
1698   c-file-style:"stroustrup"
1699   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1700   indent-tabs-mode:nil
1701   fill-column:99
1702   End:
1703 */
1704 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :