Mercurial > octave-nkf
view libgui/graphics/Figure.cc @ 19756:31d5d251f010
Remove unimplemented "New Figure" and "Open" options from Qt Figure File menu.
They are confusing and differ from FLTK options. They can easily be added back
when an implementation is developed.
* Figure.cc (createFigureToolBarAndMenuBar): Remove "New Figure" and "Open"
options.
* Figure.cc (fileNewFigure): Delete blank function.
* Figure.h (fileNewFigure): Remove function prototype.
author | Rik <rik@octave.org> |
---|---|
date | Sun, 15 Feb 2015 11:25:18 -0800 |
parents | 7335cc071ab0 |
children | c9dc27cad3c0 |
line wrap: on
line source
/* Copyright (C) 2011-2014 Michael Goffioul This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <QAction> #include <QActionEvent> #include <QActionGroup> #include <QApplication> #include <QEvent> #include <QFileDialog> #include <QFileInfo> #include <QFrame> #include <QMainWindow> #include <QMenu> #include <QMenuBar> #include <QMessageBox> #include <QtDebug> #include <QTimer> #include <QToolBar> #include "Canvas.h" #include "Container.h" #include "Figure.h" #include "FigureWindow.h" #include "MouseModeActionGroup.h" #include "QtHandlesUtils.h" #include "octave-qt-link.h" #include "builtin-defun-decls.h" namespace QtHandles { #define ABOUT_TEXT "<b>QtHandles</b> - a Qt-based toolkit for <a href=\"http://www.octave.org\">Octave</a>.<br><br>Copyright (C) 2011-2014 Michael Goffioul" DECLARE_GENERICEVENTNOTIFY_SENDER(MenuBar, QMenuBar); static bool hasUiControlChildren (const figure::properties& fp) { Matrix kids = fp.get_all_children (); for (int i = 0; i < kids.numel (); i++) { graphics_object go (gh_manager::get_object (kids(i))); if (go && (go.isa ("uicontrol") || go.isa ("uipanel") || go.isa ("uibuttongroup"))) return true; } return false; } static bool hasUiMenuChildren (const figure::properties& fp) { Matrix kids = fp.get_all_children (); for (int i = 0; i < kids.numel (); i++) { graphics_object go (gh_manager::get_object (kids(i))); if (go && go.isa ("uimenu")) return true; } return false; } static QRect boundingBoxToRect (const Matrix& bb) { QRect r; if (bb.numel () == 4) { r = QRect (xround (bb(0)), xround (bb(1)), xround (bb(2)), xround (bb(3))); if (! r.isValid ()) r = QRect (); } return r; } Figure* Figure::create (const graphics_object& go) { return new Figure (go, new FigureWindow ()); } Figure::Figure (const graphics_object& go, FigureWindow* win) : Object (go, win), m_blockUpdates (false), m_figureToolBar (0), m_menuBar (0), m_innerRect (), m_outerRect (), m_mouseModeGroup (0) { m_container = new Container (win); win->setCentralWidget (m_container); figure::properties& fp = properties<figure> (); createFigureToolBarAndMenuBar (); int offset = 0; if (fp.toolbar_is ("figure") || (fp.toolbar_is ("auto") && ! hasUiControlChildren (fp))) offset += m_figureToolBar->sizeHint ().height (); else m_figureToolBar->hide (); if (fp.menubar_is ("figure") || hasUiMenuChildren (fp)) offset += m_menuBar->sizeHint ().height () + 1; else m_menuBar->hide (); m_innerRect = boundingBoxToRect (fp.get_boundingbox (true)); m_outerRect = boundingBoxToRect (fp.get_boundingbox (false)); //qDebug () << "Figure::Figure:" << m_innerRect; win->setGeometry (m_innerRect.adjusted (0, -offset, 0, 0)); //qDebug () << "Figure::Figure(adjusted)" << m_innerRect.adjusted (0, -offset, 0, 0); win->setWindowTitle (Utils::fromStdString (fp.get_title ())); int eventMask = 0; if (! fp.get_keypressfcn ().is_empty ()) eventMask |= Canvas::KeyPress; if (! fp.get_keyreleasefcn ().is_empty ()) eventMask |= Canvas::KeyRelease; m_container->canvas (m_handle)->setEventMask (eventMask); if (! fp.get_windowbuttonmotionfcn ().is_empty ()) { m_container->setMouseTracking (true); m_container->canvas (m_handle)->qWidget ()->setMouseTracking (true); } connect (this, SIGNAL (asyncUpdate (void)), this, SLOT (updateContainer (void))); if (fp.is_visible ()) QTimer::singleShot (0, win, SLOT (show ())); else win->hide (); win->addReceiver (this); m_container->addReceiver (this); } Figure::~Figure (void) { } static std::string mouse_mode_to_string (MouseMode mode) { switch (mode) { case NoMode: return "none"; case RotateMode: return "rotate"; case ZoomMode: return "zoom"; case PanMode: return "pan"; case TextMode: return "text"; case SelectMode: return "select"; default: break; } return "none"; } static MouseMode mouse_mode_from_string (const std::string& mode) { if (mode == "none") return NoMode; else if (mode == "rotate") return RotateMode; else if (mode == "zoom") return ZoomMode; else if (mode == "pan") return PanMode; else if (mode == "text") return TextMode; else if (mode == "select") return SelectMode; else return NoMode; } QString Figure::fileName (void) { gh_manager::auto_lock lock; const figure::properties& fp = properties<figure> (); std::string name = fp.get_filename (); return QString::fromStdString (name); } void Figure::setFileName (const QString& name) { gh_manager::auto_lock lock; figure::properties& fp = properties<figure> (); fp.set_filename (name.toStdString ()); } MouseMode Figure::mouseMode (void) { gh_manager::auto_lock lock; const figure::properties& fp = properties<figure> (); std::string mode = fp.get___mouse_mode__ (); return mouse_mode_from_string (mode); } void Figure::createFigureToolBarAndMenuBar (void) { QMainWindow* win = qWidget<QMainWindow> (); m_figureToolBar = win->addToolBar (tr ("Figure ToolBar")); m_figureToolBar->setMovable (false); m_figureToolBar->setFloatable (false); m_mouseModeGroup = new MouseModeActionGroup (win); connect (m_mouseModeGroup, SIGNAL (modeChanged (MouseMode)), SLOT (setMouseMode (MouseMode))); m_figureToolBar->addActions (m_mouseModeGroup->actions ()); QAction *toggle_axes = m_figureToolBar->addAction ("Axes"); connect (toggle_axes, SIGNAL (triggered (void)), this, SLOT (toggleAxes (void))); QAction *toggle_grid = m_figureToolBar->addAction ("Grid"); connect (toggle_grid, SIGNAL (triggered (void)), this, SLOT (toggleGrid (void))); m_menuBar = new MenuBar (win); win->setMenuBar (m_menuBar); QMenu* fileMenu = m_menuBar->addMenu (tr ("&File")); fileMenu->menuAction ()->setObjectName ("builtinMenu"); fileMenu->addAction (tr ("&Save"), this, SLOT (fileSaveFigure (bool))); fileMenu->addAction (tr ("Save &As"), this, SLOT (fileSaveFigureAs (void))); fileMenu->addSeparator (); fileMenu->addAction (tr ("&Close Figure"), this, SLOT (fileCloseFigure (void)), Qt::CTRL|Qt::Key_W); QMenu* editMenu = m_menuBar->addMenu (tr ("&Edit")); editMenu->menuAction ()->setObjectName ("builtinMenu"); editMenu->addAction (tr ("Cop&y"), this, SLOT (editCopy (void)), Qt::CTRL|Qt::Key_C)->setEnabled (false); editMenu->addAction (tr ("Cu&t"), this, SLOT (editCut (void)), Qt::CTRL|Qt::Key_X)->setEnabled (false); editMenu->addAction (tr ("&Paste"), this, SLOT (editPaste(void)), Qt::CTRL|Qt::Key_V)->setEnabled (false); editMenu->addSeparator (); editMenu->addActions (m_mouseModeGroup->actions ()); QMenu* helpMenu = m_menuBar->addMenu (tr ("&Help")); helpMenu->menuAction ()->setObjectName ("builtinMenu"); helpMenu->addAction (tr ("&About QtHandles"), this, SLOT (helpAboutQtHandles (void))); helpMenu->addAction (tr ("About &Qt"), qApp, SLOT (aboutQt (void))); m_menuBar->addReceiver (this); } void Figure::updateFigureToolBarAndMenuBar (void) { if (m_mouseModeGroup) { m_blockUpdates = true; m_mouseModeGroup->setMode (mouseMode ()); m_blockUpdates = false; } } Container* Figure::innerContainer (void) { return m_container; } void Figure::redraw (void) { Canvas* canvas = m_container->canvas (m_handle); if (canvas) { canvas->redraw (); //canvas->setMouseMode (RotateMode); } foreach (QFrame* frame, qWidget<QWidget> ()->findChildren<QFrame*> ("UIPanel")) { Object* obj = Object::fromQObject (frame); if (obj) obj->slotRedraw (); } updateFigureToolBarAndMenuBar (); } void Figure::print (const QString& file_cmd, const QString& term) { Canvas* canvas = m_container->canvas (m_handle); if (canvas) canvas->print (file_cmd, term); } void Figure::beingDeleted (void) { Canvas* canvas = m_container->canvas (m_handle.value (), false); if (canvas) canvas->blockRedraw (true); m_menuBar->removeReceiver (this); m_container->removeReceiver (this); qWidget<FigureWindow> ()->removeReceiver (this); } void Figure::update (int pId) { if (m_blockUpdates) return; figure::properties& fp = properties<figure> (); QMainWindow* win = qWidget<QMainWindow> (); m_blockUpdates = true; switch (pId) { case figure::properties::ID_POSITION: { m_innerRect = boundingBoxToRect (fp.get_boundingbox (true)); //qDebug () << "Figure::update(position):" << m_innerRect; int offset = 0; foreach (QToolBar* tb, win->findChildren<QToolBar*> ()) if (! tb->isHidden ()) offset += tb->sizeHint ().height (); if (! m_menuBar->isHidden ()) offset += m_menuBar->sizeHint ().height () + 1; //qDebug () << "Figure::update(position)(adjusted):" << m_innerRect.adjusted (0, -offset, 0, 0); win->setGeometry (m_innerRect.adjusted (0, -offset, 0, 0)); //qDebug () << "Figure::update(position): done"; } break; case figure::properties::ID_NAME: case figure::properties::ID_NUMBERTITLE: win->setWindowTitle (Utils::fromStdString (fp.get_title ())); break; case figure::properties::ID_VISIBLE: if (fp.is_visible ()) QTimer::singleShot (0, win, SLOT (show ())); else win->hide (); break; case figure::properties::ID_TOOLBAR: if (fp.toolbar_is ("none")) showFigureToolBar (false); else if (fp.toolbar_is ("figure")) showFigureToolBar (true); else // "auto" showFigureToolBar (! hasUiControlChildren (fp)); break; case figure::properties::ID_MENUBAR: showMenuBar (fp.menubar_is ("figure")); break; case figure::properties::ID_KEYPRESSFCN: if (fp.get_keypressfcn ().is_empty ()) m_container->canvas (m_handle)->clearEventMask (Canvas::KeyPress); else m_container->canvas (m_handle)->addEventMask (Canvas::KeyPress); break; case figure::properties::ID_KEYRELEASEFCN: if (fp.get_keyreleasefcn ().is_empty ()) m_container->canvas (m_handle)->clearEventMask (Canvas::KeyRelease); else m_container->canvas (m_handle)->addEventMask (Canvas::KeyRelease); break; case figure::properties::ID_WINDOWBUTTONMOTIONFCN: { bool hasCallback = ! fp.get_windowbuttonmotionfcn ().is_empty (); m_container->setMouseTracking (hasCallback); foreach (QWidget* w, m_container->findChildren<QWidget*> ()) { w->setMouseTracking (hasCallback); } } break; default: break; } m_blockUpdates = false; } void Figure::showFigureToolBar (bool visible) { if ((! m_figureToolBar->isHidden ()) != visible) { int dy = m_figureToolBar->sizeHint ().height (); QRect r = qWidget<QWidget> ()->geometry (); if (! visible) r.adjust (0, dy, 0, 0); else r.adjust (0, -dy, 0, 0); m_blockUpdates = true; qWidget<QWidget> ()->setGeometry (r); m_figureToolBar->setVisible (visible); m_blockUpdates = false; updateBoundingBox (false); } } void Figure::showMenuBar (bool visible) { int h1 = m_menuBar->sizeHint ().height (); foreach (QAction* a, m_menuBar->actions ()) if (a->objectName () == "builtinMenu") a->setVisible (visible); int h2 = m_menuBar->sizeHint ().height (); if (! visible) visible = hasUiMenuChildren (properties<figure> ()); if ((! m_menuBar->isHidden ()) != visible) { int dy = qMax (h1, h2) + 1; QRect r = qWidget<QWidget> ()->geometry (); //qDebug () << "Figure::showMenuBar:" << r; if (! visible) r.adjust (0, dy, 0, 0); else r.adjust (0, -dy, 0, 0); //qDebug () << "Figure::showMenuBar(adjusted):" << r; m_blockUpdates = true; qWidget<QWidget> ()->setGeometry (r); m_menuBar->setVisible (visible); m_blockUpdates = false; updateBoundingBox (false); } } void Figure::updateMenuBar (void) { gh_manager::auto_lock lock; graphics_object go = object (); if (go.valid_object ()) showMenuBar (Utils::properties<figure> (go).menubar_is ("figure")); } QWidget* Figure::menu (void) { return qWidget<QMainWindow> ()->menuBar (); } struct UpdateBoundingBoxData { Matrix m_bbox; bool m_internal; graphics_handle m_handle; Figure* m_figure; }; void Figure::updateBoundingBoxHelper (void* data) { gh_manager::auto_lock lock; UpdateBoundingBoxData* d = reinterpret_cast<UpdateBoundingBoxData*> (data); graphics_object go = gh_manager::get_object (d->m_handle); if (go.valid_object ()) { figure::properties& fp = Utils::properties<figure> (go); //qDebug ("Figure::updateBoundingBoxHelper: internal=%d, bbox=[%g %g %g %g]", // d->m_internal, d->m_bbox(0), d->m_bbox(1), d->m_bbox(2), d->m_bbox(3)); fp.set_boundingbox (d->m_bbox, d->m_internal, false); if (d->m_internal) emit d->m_figure->asyncUpdate (); } delete d; } void Figure::updateBoundingBox (bool internal, int flags) { QWidget* win = qWidget<QWidget> (); Matrix bb (1, 4); if (internal) { QRect r = m_innerRect; if (flags & UpdateBoundingBoxPosition) r.moveTopLeft (win->mapToGlobal (m_container->pos ())); if (flags & UpdateBoundingBoxSize) r.setSize (m_container->size ()); if (r.isValid () && r != m_innerRect) { //qDebug() << "inner rect changed:" << m_innerRect << "->>" << r; m_innerRect = r; bb(0) = r.x (); bb(1) = r.y (); bb(2) = r.width (); bb(3) = r.height (); } else return; } else { QRect r = m_outerRect; if (flags & UpdateBoundingBoxPosition) r.moveTopLeft (win->pos ()); if (flags & UpdateBoundingBoxSize) r.setSize (win->frameGeometry ().size ()); if (r.isValid () && r != m_outerRect) { //qDebug() << "outer rect changed:" << m_outerRect << "->>" << r; m_outerRect = r; bb(0) = r.x (); bb(1) = r.y (); bb(2) = r.width (); bb(3) = r.height (); } else return; } UpdateBoundingBoxData* d = new UpdateBoundingBoxData (); d->m_bbox = bb; d->m_internal = internal; d->m_handle = m_handle; d->m_figure = this; //qDebug ("Figure::updateBoundingBox: internal=%d, bbox=[%g %g %g %g]", // d->m_internal, d->m_bbox(0), d->m_bbox(1), d->m_bbox(2), d->m_bbox(3)); gh_manager::post_function (Figure::updateBoundingBoxHelper, d); } bool Figure::eventNotifyBefore (QObject* obj, QEvent* xevent) { if (! m_blockUpdates) { if (obj == m_container) { // Do nothing... } else if (obj == m_menuBar) { switch (xevent->type ()) { case QEvent::ActionRemoved: { QAction* a = dynamic_cast<QActionEvent*> (xevent)->action (); if (! a->isSeparator () && a->objectName () != "builtinMenu") updateMenuBar (); } break; default: break; } } else { switch (xevent->type ()) { case QEvent::Close: xevent->ignore (); gh_manager::post_callback (m_handle, "closerequestfcn"); return true; default: break; } } } return false; } void Figure::eventNotifyAfter (QObject* watched, QEvent* xevent) { if (! m_blockUpdates) { if (watched == m_container) { switch (xevent->type ()) { case QEvent::Resize: updateBoundingBox (true, UpdateBoundingBoxSize); break; case QEvent::ChildAdded: if (dynamic_cast<QChildEvent*> (xevent)->child ()->isWidgetType()) { gh_manager::auto_lock lock; const figure::properties& fp = properties<figure> (); showFigureToolBar (! hasUiControlChildren (fp)); } default: break; } } else if (watched == m_menuBar) { switch (xevent->type ()) { case QEvent::ActionAdded: { QAction* a = dynamic_cast<QActionEvent*> (xevent)->action (); if (! a->isSeparator () && a->objectName () != "builtinMenu") updateMenuBar (); } break; default: break; } } else { switch (xevent->type ()) { case QEvent::Move: updateBoundingBox (false, UpdateBoundingBoxPosition); updateBoundingBox (true, UpdateBoundingBoxPosition); break; case QEvent::Resize: updateBoundingBox (false, UpdateBoundingBoxSize); break; default: break; } } } } void Figure::helpAboutQtHandles (void) { QMessageBox::about (qWidget<QMainWindow> (), tr ("About QtHandles"), ABOUT_TEXT); } void Figure::setMouseMode (MouseMode mode) { if (m_blockUpdates) return; gh_manager::auto_lock lock; figure::properties& fp = properties<figure> (); fp.set___mouse_mode__ (mouse_mode_to_string (mode)); Canvas* canvas = m_container->canvas (m_handle); if (canvas) canvas->setCursor (mode); } void Figure::fileSaveFigure (bool prompt) { QString file = fileName (); if (file.isEmpty ()) { prompt = true; file = "untitled.eps"; } if (prompt || file.isEmpty ()) { QFileInfo finfo (file); file = QFileDialog::getSaveFileName (qWidget<FigureWindow> (), tr ("Save Figure As"), finfo.absoluteFilePath (), 0, 0, QFileDialog::DontUseNativeDialog); } if (! file.isEmpty ()) { QFileInfo finfo (file); setFileName (finfo.absoluteFilePath ()); octave_link::post_event (this, &Figure::save_figure_callback, file.toStdString ()); } } void Figure::save_figure_callback (const std::string& file) { Ffeval (ovl ("print", file)); } void Figure::fileSaveFigureAs (void) { fileSaveFigure (true); } void Figure::fileCloseFigure (void) { qWidget<QMainWindow> ()->close (); } void Figure::editCopy (void) { } void Figure::editCut (void) { } void Figure::editPaste (void) { } void Figure::addCustomToolBar (QToolBar* bar, bool visible) { QMainWindow* win = qWidget<QMainWindow> (); if (! visible) win->addToolBar (bar); else { QSize sz = bar->sizeHint (); QRect r = win->geometry (); //qDebug () << "Figure::addCustomToolBar:" << r; r.adjust (0, -sz.height (), 0, 0); m_blockUpdates = true; win->setGeometry (r); win->addToolBarBreak (); win->addToolBar (bar); m_blockUpdates = false; //qDebug () << "Figure::addCustomToolBar:" << win->geometry (); updateBoundingBox (false); } } void Figure::showCustomToolBar (QToolBar* bar, bool visible) { QMainWindow* win = qWidget<QMainWindow> (); if ((! bar->isHidden ()) != visible) { QSize sz = bar->sizeHint (); QRect r = win->geometry (); if (visible) r.adjust (0, -sz.height (), 0, 0); else r.adjust (0, sz.height (), 0, 0); m_blockUpdates = true; win->setGeometry (r); bar->setVisible (visible); m_blockUpdates = false; updateBoundingBox (false); } } void Figure::updateContainer (void) { redraw (); } void Figure::toggleAxes (void) { Canvas* canvas = m_container->canvas (m_handle); if (canvas) canvas->toggleAxes (m_handle); } void Figure::toggleGrid (void) { Canvas* canvas = m_container->canvas (m_handle); if (canvas) canvas->toggleGrid (m_handle); } }; // namespace QtHandles