Unverified Commit 53cc3033 authored by kledmundson's avatar kledmundson Committed by GitHub
Browse files

Merge pull request #137 from TracieSucharski/ipce

Ipce Fixed seg fault in ControlNetTool when no control has been loaded
parents daef3014 43dade8e
Loading
Loading
Loading
Loading
+75 −10
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ namespace Isis {
      m_directory = new Directory(this);
      connect(m_directory, SIGNAL( newWidgetAvailable(QWidget *) ),
              this, SLOT( addView(QWidget *) ) );
      connect(m_directory, SIGNAL(viewClosed(QWidget *)), this, SLOT(removeView(QWidget *)));
      connect(m_directory, SIGNAL( directoryCleaned() ),
              this, SLOT( removeAllViews() ) );
      connect(m_directory->project(), SIGNAL(projectLoaded(Project *)),
@@ -226,11 +227,41 @@ namespace Isis {
      if ( QMdiArea *mdiArea = qobject_cast<QMdiArea *>( centralWidget() ) ) {
        mdiArea->addSubWindow(newWidget);
        newWidget->show();
        mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(newWidget));
        setActiveView(qobject_cast<AbstractProjectItemView *>(newWidget));
      }
    }
  }


  /**
   * @description This slot is connected from Directory::viewClosed(QWidget *) signal.  It will 
   * close the given QMdiSubWindow from the QMdiArea.  This will also delete the widget contained 
   * within the subwindow which is an AbstractProjectItemView. 
   * 
   * @param view QWidget* 
   *
   */
  void IpceMainWindow::removeView(QWidget *view) {

    QMdiArea *mdiArea = qobject_cast<QMdiArea *>( centralWidget() );
    if (mdiArea){
      // Get all QMdiSubWindows, then find subwindow that hold widget
      QList<QMdiSubWindow *> subWindowList = mdiArea->subWindowList();
      foreach (QMdiSubWindow *sub, subWindowList) {
        if (sub->widget() == view) {
          sub->close();
          break;
        }
      }
//    QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(view);
//    qDebug()<<"IpceMainWindow::removeView activewindow = "<<window;
//    mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(view));
//    qDebug()<<"IpceMainWindow::removeView";
//    mdiArea->closeActiveSubWindow();
      delete view;
    }
  }


  /**
   * Removes All Views in main window, connected to directory signal directoryCleaned()
   */
@@ -238,12 +269,12 @@ namespace Isis {
    setWindowTitle("ipce");
    QMdiArea *mdiArea = qobject_cast<QMdiArea *>( centralWidget() );
    if (mdiArea){
      QMdiSubWindow* window = new QMdiSubWindow();
      window->show();
      window->activateWindow();
      mdiArea->addSubWindow(window);
//    QMdiSubWindow* window = new QMdiSubWindow();
//    window->show();
//    window->activateWindow();
//    mdiArea->addSubWindow(window);
      mdiArea->closeAllSubWindows();
      delete window;
//    delete window;
    }
    if (!m_detachedViews.isEmpty()) {
      foreach ( QMainWindow* view, m_detachedViews ) {
@@ -411,7 +442,13 @@ namespace Isis {
      m_permToolBar->addAction(action);
    }
    foreach (QAction *action, m_permToolBarActions) {
      if (action->text() == "&Save Active Control Network") {
        m_permToolBar->addSeparator();
      }
      m_permToolBar->addAction(action); 
      if (action->text() == "&Save Active Control Network") {
        m_permToolBar->addSeparator();
      }
    }
    m_permToolBar->addSeparator();
    if (m_activeView) {
@@ -515,6 +552,30 @@ namespace Isis {
    m_fileMenuActions.append(exitAction);
    m_permToolBarActions.append(exitAction);

    QAction *saveNet = new QAction("&Save Active Control Network", this);
    saveNet->setIcon( QIcon::fromTheme("document-save") );
    saveNet->setShortcut(Qt::CTRL + Qt::Key_S);
    saveNet->setToolTip("Save current active control network");
    saveNet->setStatusTip("Save current active control network");
    QString whatsThis = "<b>Function:</b> Saves the current active<i>"
                        "control network</i>";
    saveNet->setWhatsThis(whatsThis);
    connect(saveNet, SIGNAL(triggered()), m_directory, SLOT(saveActiveControl()));
    m_permToolBarActions.append(saveNet);

//  m_saveAsNet = new QAction(QPixmap(toolIconDir() + "/mActionFileSaveAs.png"),
//                            "Save Control Network &As...",
//                            m_matchTool);
//  m_saveAsNet->setToolTip("Save current control network to chosen file");
//  m_saveAsNet->setStatusTip("Save current control network to chosen file");
//  whatsThis = "<b>Function:</b> Saves the current <i>"
//      "control network</i> under chosen filename";
//  m_saveAsNet->setWhatsThis(whatsThis);
//  connect(m_saveAsNet, SIGNAL(triggered()), this, SLOT(saveAsNet()));




    QAction *undoAction = m_directory->undoAction();
    undoAction->setShortcut(Qt::Key_Z | Qt::CTRL);

@@ -806,7 +867,11 @@ namespace Isis {
   * state information before forwarding the event to the QMainWindow.
   */
  void IpceMainWindow::closeEvent(QCloseEvent *event) {
    if (!m_directory->project()->isClean()) {

    // The active control is checked here for modification because this was the simplest solution
    // vs changing the project clean state every time the control is modified or saved.
    if (!m_directory->project()->isClean() || (m_directory->project()->activeControl() &&
                                               m_directory->project()->activeControl()->isModified())) {
      QMessageBox *box = new QMessageBox(QMessageBox::NoIcon, QString("Current Project Has Unsaved Changes"),
                             QString("Would you like to save your current project?"),
                             NULL, qobject_cast<QWidget *>(parent()), Qt::Dialog);
@@ -1045,7 +1110,7 @@ namespace Isis {
    menuBar->addMenu(viewMenu);

    if ( !view->settingsMenuActions().isEmpty() ) {
      QMenu *settingsMenu = new QMenu("&Settings", newWindow);
      QMenu *settingsMenu = new QMenu("S&ettings", newWindow);
      foreach ( QAction *action, view->settingsMenuActions() ) {
        settingsMenu->addAction(action);
      }
+6 −0
Original line number Diff line number Diff line
@@ -123,6 +123,11 @@ namespace Isis {
   *                           the history dock. Fixes #5151.
   *   @history 2018-03-02 Tracie Sucharski - added static keyword to the m_maxRecentProject member
   *                           variable, fixes OSX compile warning.  References #5341.
   *   @history 2018-04-04 Tracie Sucharski - Added removeView slot which removes the view
   *                           containing the given widget. In the closeEvent method check whether
   *                           there is an active control and if it has been modified as additional
   *                           test to determine whether project needs saving.
   *  
   */
  class IpceMainWindow : public QMainWindow {
      Q_OBJECT
@@ -132,6 +137,7 @@ namespace Isis {

    public slots:
      void addView(QWidget *newWidget);
      void removeView(QWidget *view);
      void removeAllViews();

      void setActiveView(AbstractProjectItemView *view);
+328 −0
Original line number Diff line number Diff line
/**
 * @file
 * $Date$
 * $Revision$
 *
 *   Unless noted otherwise, the portions of Isis written by the USGS are
 *   public domain. See individual third-party library and package descriptions
 *   for intellectual property information, user agreements, and related
 *   information.
 *
 *   Although Isis has been used by the USGS, no warranty, expressed or
 *   implied, is made by the USGS as to the accuracy and functioning of such
 *   software and related material nor shall the fact of distribution
 *   constitute any such warranty, and no responsibility is assumed by the
 *   USGS in connection therewith.
 *
 *   For additional information, launch
 *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html
 *   in a browser or see the Privacy &amp; Disclaimers page on the Isis website,
 *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
 *   http://www.usgs.gov/privacy.html.
 */
#include "IsisDebug.h"

#include "CnetEditorView.h"

#include <QAction>
#include <QGridLayout>
#include <QList>
#include <QMap>
#include <QMapIterator>
#include <QMenu>
#include <QMenuBar>
#include <QSize>
#include <QSizePolicy>
#include <QString>
#include <QTabWidget>
#include <QToolBar>
#include <QtXml>
#include <QVBoxLayout>
#include <QWidgetAction>

#include "Control.h"
#include "ControlNet.h"
#include "CnetEditorWidget.h"
#include "Directory.h"
#include "FileName.h"
#include "Project.h"
#include "ToolPad.h"
#include "XmlStackedHandlerReader.h"


namespace Isis {
  /**
   * Constructor.
   */
  CnetEditorView::CnetEditorView(Directory *directory, Control *control, FileName configFile,
                                 QWidget *parent) : AbstractProjectItemView(parent) {

    // TODO: This layout should be inside of the cnet editor widget, but I put it here to not
    //     conflict with current work in the cnet editor widget code.
    //QWidget *result = new QWidget;
    QGridLayout *resultLayout = new QGridLayout;
    setLayout(resultLayout);

    int row = 0;

    QMenuBar *menuBar = new QMenuBar;
    resultLayout->addWidget(menuBar, row, 0, 1, 2);
    row++;

    m_cnetEditorWidget = new CnetEditorWidget(control, configFile.expanded());
    m_control = control;

    resultLayout->addWidget(m_cnetEditorWidget, row, 0, 1, 2);
    row++;

    // Populate the menu...
    QMap< QAction *, QList< QString > > actionMap = m_cnetEditorWidget->menuActions();
    QMapIterator< QAction *, QList< QString > > actionMapIterator(actionMap);

    QMap<QString, QMenu *> topLevelMenus;

    while ( actionMapIterator.hasNext() ) {
      actionMapIterator.next();
      QAction *actionToAdd = actionMapIterator.key();
      QList< QString > location = actionMapIterator.value();

      QMenu *menuToPutActionInto = NULL;

      if ( location.count() ) {
        QString topLevelMenuTitle = location.takeFirst();
        if (!topLevelMenus[topLevelMenuTitle]) {
          topLevelMenus[topLevelMenuTitle] = menuBar->addMenu(topLevelMenuTitle);
        }

        menuToPutActionInto = topLevelMenus[topLevelMenuTitle];
      }

      foreach (QString menuName, location) {
        bool foundSubMenu = false;
        foreach ( QAction *possibleSubMenu, menuToPutActionInto->actions() ) {
          if (!foundSubMenu &&
              possibleSubMenu->menu() && possibleSubMenu->menu()->title() == menuName) {
            foundSubMenu = true;
            menuToPutActionInto = possibleSubMenu->menu();
          }
        }

        if (!foundSubMenu) {
          menuToPutActionInto = menuToPutActionInto->addMenu(menuName);
        }
      }

      menuToPutActionInto->addAction(actionToAdd);
    }

    QTabWidget *treeViews = new QTabWidget;
    treeViews->addTab( m_cnetEditorWidget->pointTreeView(), tr("Point View") );
    treeViews->addTab( m_cnetEditorWidget->serialTreeView(), tr("Serial View") );
    treeViews->addTab( m_cnetEditorWidget->connectionTreeView(), tr("Connection View") );
    resultLayout->addWidget(treeViews, row, 0, 1, 1);

    QTabWidget *filterViews = new QTabWidget;
    filterViews->addTab( m_cnetEditorWidget->pointFilterWidget(), tr("Filter Points and Measures") );
    filterViews->addTab( m_cnetEditorWidget->serialFilterWidget(), tr("Filter Images and Points") );
    filterViews->addTab( m_cnetEditorWidget->connectionFilterWidget(), tr("Filter Connections") );
    resultLayout->addWidget(filterViews, row, 1, 1, 1);
    row++;





    m_permToolBar = new QToolBar("Standard Tools", 0);
    m_permToolBar->setObjectName("permToolBar");
    m_permToolBar->setIconSize(QSize(22, 22));
    //toolBarLayout->addWidget(m_permToolBar);

    m_activeToolBar = new QToolBar("Active Tool", 0);
    m_activeToolBar->setObjectName("activeToolBar");
    m_activeToolBar->setIconSize(QSize(22, 22));
    //toolBarLayout->addWidget(m_activeToolBar);

    m_toolPad = new ToolPad("Tool Pad", 0);
    m_toolPad->setObjectName("toolPad");
    //toolBarLayout->addWidget(m_toolPad);


//  m_cnetEditorWidget->addToPermanent(m_permToolBar);
//  m_cnetEditorWidget->addTo(m_activeToolBar);
//  m_cnetEditorWidget->addTo(m_toolPad);

    m_activeToolBarAction = new QWidgetAction(this);
    m_activeToolBarAction->setDefaultWidget(m_activeToolBar);

    setAcceptDrops(true);

    QSizePolicy policy = sizePolicy();
    policy.setHorizontalPolicy(QSizePolicy::Expanding);
    policy.setVerticalPolicy(QSizePolicy::Expanding);
    setSizePolicy(policy);

  }


  /**
   * Destructor
   */
  CnetEditorView::~CnetEditorView() {
    
    delete m_cnetEditorWidget;
    delete m_permToolBar;
    delete m_activeToolBar;
    delete m_toolPad;

    m_permToolBar = 0;
    m_activeToolBar = 0;
    m_toolPad = 0;
  }


  /**
   * Returns the cnetEditorWidget.
   *
   * @return (cnetEditorWidget *) The cnetEditorWidget used to
   *         display the footprints.
   */
  CnetEditorWidget *CnetEditorView::cnetEditorWidget() {
    return m_cnetEditorWidget;
  }


  /**
   * @description Returns the Control displayed in the CnetEditorWidget 
   *  
   * @return (Control *) The Control displayed in the CnetEditorWidget 
   */
  Control *CnetEditorView::control() {
    return m_control;
  }


  /**
   * Returns the suggested size for the widget.
   *
   * @return (QSize) The size
   */
  QSize CnetEditorView::sizeHint() const {
    return QSize(800, 600);
  }


  /**
   * Returns a list of actions for the permanent tool bar.
   *
   * @return (QList<QAction *>) The actions
   */
  QList<QAction *> CnetEditorView::permToolBarActions() {
    return m_permToolBar->actions();
  }


  /**
   * Returns a list of actions for the active tool bar.
   *
   * @return (QList<QAction *>) The actions
   */
  QList<QAction *> CnetEditorView::activeToolBarActions() {
    QList<QAction *> actions;
    actions.append(m_activeToolBarAction);
    return actions;
  }


  /**
   * Returns a list of actions for the tool pad.
   *
   * @return (QList<QAction *>) The actions
   */
  QList<QAction *> CnetEditorView::toolPadActions() {
    return m_toolPad->actions();
  }




  /**
   * This method pushes a new XmlHandler into the parser stack.
   *
   * @param xmlReader This is the parser stack.
   */
  void CnetEditorView::load(XmlStackedHandlerReader *xmlReader) {
    xmlReader->pushContentHandler(new XmlHandler(this));
  }


  /**
   * This method saves the Controls object ids to the stream.
   *
   * @param stream The stream that will output to directory.xml
   * @param project The project to save the users settings to
   * @param newProjectRoot New project's root directory
   */
  void CnetEditorView::save(QXmlStreamWriter &stream, Project *, FileName) const {

    stream.writeStartElement("control");
    stream.writeAttribute("id", m_control->id());
    stream.writeEndElement();
  }


  /**
   * Creates an XmlHandler for cnetEditor
   *
   * @param cnetEditor The widget to be serialized
   */
  CnetEditorView::XmlHandler::XmlHandler(CnetEditorView *cnetEditorView) {
    m_cnetEditorView = cnetEditorView;
  }


  /**
   * Destructor
   */
  CnetEditorView::XmlHandler::~XmlHandler() {
    delete m_cnetEditorView;
    m_cnetEditorView = NULL;
  }


  /**
   * Placeholder for later serialization of CnetEditorViews
   *
   * @param cnetEditor The CnetEditorView to be serialized
   * @param namespaceURI ???
   * @param localName Determines what attributes to retrieve from atts.
   * @param qName ???
   * @param atts Stores the attributes.
   *
   * @return @b bool The result of XmlStackedHandler's startElement() method.
   */
  bool CnetEditorView::XmlHandler::startElement(const QString &namespaceURI,
      const QString &localName, const QString &qName, const QXmlAttributes &atts) {

    bool result = XmlStackedHandler::startElement(namespaceURI, localName, qName, atts);
    return result;
  }


  /**
   * This method calls XmlStackedHandler's endElement() and dereferences pointers according to
   * the value of localName.
   *
   * @param namespaceURI ???
   * @param localName Determines which pointers to dereference.
   * @param qName ???
   *
   * @return @b bool The result of XmlStackedHandler's endElement() method.
   */
  bool CnetEditorView::XmlHandler::endElement(const QString &namespaceURI,
      const QString &localName, const QString &qName) {

    bool result = XmlStackedHandler::endElement(namespaceURI, localName, qName);
    return result;
  }
}
+113 −0
Original line number Diff line number Diff line
#ifndef CnetEditorView_h
#define CnetEditorView_h
/**
 * @file
 * $Date$
 * $Revision$
 *
 *   Unless noted otherwise, the portions of Isis written by the USGS are
 *   public domain. See individual third-party library and package descriptions
 *   for intellectual property information, user agreements, and related
 *   information.
 *
 *   Although Isis has been used by the USGS, no warranty, expressed or
 *   implied, is made by the USGS as to the accuracy and functioning of such
 *   software and related material nor shall the fact of distribution
 *   constitute any such warranty, and no responsibility is assumed by the
 *   USGS in connection therewith.
 *
 *   For additional information, launch
 *   $ISISROOT/doc//documents/Disclaimers/Disclaimers.html
 *   in a browser or see the Privacy &amp; Disclaimers page on the Isis website,
 *   http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
 *   http://www.usgs.gov/privacy.html.
 */
#include <QList>
#include <QMap>
#include <QPointer>
#include <QSize>

#include "AbstractProjectItemView.h"
#include "FileName.h"
#include "XmlStackedHandler.h"

class QAction;
class QToolBar;
class QWidgetAction;
class QXmlStreamWriter;

namespace Isis {
  class Control;
  class CnetEditorWidget;
  class Directory;
  class FileName;
  class Project;
  class ToolPad;
  class XmlStackedHandlerReader;

  /**
   * Ipce view containing the CnetEditorWidget
   *
   * @author 2018-04-04 Tracie Sucharski
   *    
   * @internal 
   */

class CnetEditorView : public AbstractProjectItemView {

  Q_OBJECT

  public:
    CnetEditorView(Directory *directory, Control *control, FileName configFile, 
                   QWidget *parent = 0);
    ~CnetEditorView();

    virtual QList<QAction *> permToolBarActions();
    virtual QList<QAction *> activeToolBarActions();
    virtual QList<QAction *> toolPadActions();

    CnetEditorWidget *cnetEditorWidget();
    Control *control();

    QSize sizeHint() const;

    void load(XmlStackedHandlerReader *xmlReader);
    void save(QXmlStreamWriter &stream, Project *project, FileName newProjectRoot) const;


    private:
      /**
       * @author 2012-09-?? Steven Lambright
       *
       * @internal
       *   @history 2018-04-04 Tracie Sucharski - Implemented for CnetEditorView
       */
      class XmlHandler : public XmlStackedHandler {
        public:
          XmlHandler(CnetEditorView *cnetEditorView);
          ~XmlHandler();

          virtual bool startElement(const QString &namespaceURI, const QString &localName,
                                    const QString &qName, const QXmlAttributes &atts);
          virtual bool endElement(const QString &namespaceURI, const QString &localName,
                                  const QString &qName);

        private:
          Q_DISABLE_COPY(XmlHandler);

          CnetEditorView *m_cnetEditorView; //!< The view we are working with
      };

  private:
    QPointer<CnetEditorWidget> m_cnetEditorWidget;
    QPointer<Control> m_control;

    QToolBar *m_permToolBar; //!< The permanent tool bar
    QToolBar *m_activeToolBar; //!< The active tool bar
    ToolPad *m_toolPad; //!< The tool pad

    QWidgetAction *m_activeToolBarAction; //!< Stores the active tool bar
  };
}

#endif // CNETEDITORVIEW_H
+7 −0
Original line number Diff line number Diff line
ifeq ($(ISISROOT), $(BLANK))
.SILENT:
error:
	echo "Please set ISISROOT";
else
	include $(ISISROOT)/make/isismake.objs
endif
 No newline at end of file
Loading