From 39870635971cd1ae8e82637149590b242c834a79 Mon Sep 17 00:00:00 2001
From: manongjohn <manongjohn@users.noreply.github.com>
Date: May 28 2018 05:16:28 +0000
Subject: Open sub-xsheet at selected sub-xsheet frame (#1980)


* Open sub-xsheet at selected frame
---

diff --git a/toonz/sources/toonz/subscenecommand.cpp b/toonz/sources/toonz/subscenecommand.cpp
index c3cc040..938cd64 100644
--- a/toonz/sources/toonz/subscenecommand.cpp
+++ b/toonz/sources/toonz/subscenecommand.cpp
@@ -970,69 +970,90 @@ public:
 
 void openSubXsheet() {
   TApp *app = TApp::instance();
-  /*- 選択セル又は選択カラムの中にChildLevelが有った場合のみ中に入る -*/
+  /*- Enter only when ChildLevel exists in selected cell or selected column -*/
   TCellSelection *cellSelection =
       dynamic_cast<TCellSelection *>(TSelection::getCurrent());
   TColumnSelection *columnSelection =
       dynamic_cast<TColumnSelection *>(TSelection::getCurrent());
 
-  bool ret          = false;
-  ToonzScene *scene = app->getCurrentScene()->getScene();
+  bool ret               = false;
+  ToonzScene *scene      = app->getCurrentScene()->getScene();
+  int row                = app->getCurrentFrame()->getFrame();
+  int col                = app->getCurrentColumn()->getColumnIndex();
+  TXsheet *currentXsheet = app->getCurrentXsheet()->getXsheet();
+  TXshCell targetCell;
 
-  /*- カラム選択の場合 -*/
+  /*- For column selection -*/
   if (columnSelection && !columnSelection->isEmpty()) {
-    TXsheet *currentXsheet = app->getCurrentXsheet()->getXsheet();
-    int sceneLength        = currentXsheet->getFrameCount();
+    int sceneLength = currentXsheet->getFrameCount();
 
     std::set<int> columnIndices = columnSelection->getIndices();
     std::set<int>::iterator it;
-    /*- 各Columnについて各セルでopenChildを試みる -*/
+    /*- Try openChild on each cell for each Column -*/
     for (it = columnIndices.begin(); it != columnIndices.end(); ++it) {
       int c = *it;
-      /*- Column内の各Cellについて、中身が見つかったらbreak -*/
+      // See if the current row indicator is on an exposed sub-xsheet frame
+      // If so, use that.
+      targetCell = currentXsheet->getCell(row, c);
+      if (!targetCell.isEmpty() &&
+          (ret = scene->getChildStack()->openChild(row, c)))
+        break;
+
+      /*- For each Cell in the Column, if contents are found break -*/
       for (int r = 0; r < sceneLength; r++) {
         ret = scene->getChildStack()->openChild(r, c);
-        if (ret) break;
+        if (ret) {
+          targetCell = currentXsheet->getCell(r, c);
+          break;
+        }
       }
       if (ret) break;
     }
   }
 
-  /*- それ以外の場合(セル選択、又はその他)-*/
+  /*- In other cases (cell selection or other) -*/
   else {
     TRect selectedArea;
-    /*- セル選択でも無い場合、カレントフレーム/カラムを見る -*/
+    /*- If it is not cell selection, see current frame / column -*/
     if (!cellSelection || cellSelection->isEmpty()) {
-      int row = app->getCurrentFrame()->getFrame();
-      int col = app->getCurrentColumn()->getColumnIndex();
-      /*- セル選択でない場合、1×1の選択範囲 -*/
+      /*- When it is not cell selection, 1 × 1 selection range -*/
       selectedArea = TRect(col, row, col, row);
     }
-    /*- セル選択の場合 -*/
+    /*- In case of cell selection -*/
     else {
       int r0, c0, r1, c1;
       cellSelection->getSelectedCells(r0, c0, r1, c1);
       selectedArea = TRect(c0, r0, c1, r1);
     }
-    /*- Rectに含まれる各セルでopenChildを試みる -*/
+    /*- Try openChild on each cell in Rect -*/
     for (int c = selectedArea.x0; c <= selectedArea.x1; c++) {
       for (int r = selectedArea.y0; r <= selectedArea.y1; r++) {
         ret = scene->getChildStack()->openChild(r, c);
-        if (ret) break;
+        if (ret) {
+          // When opening based on cell selection use the 1st
+          // exposed frame in the sub-xsheet it finds
+          targetCell = currentXsheet->getCell(r, c);
+          break;
+        }
       }
       if (ret) break;
     }
   }
 
-  /*- subXsheet Levelが見つかった場合 -*/
+  /*- When subXsheet Level is found -*/
   if (ret) {
+    int subXsheetFrame = 0;
+
+    if (!targetCell.isEmpty())
+      subXsheetFrame = targetCell.getFrameId().getNumber() - 1;
+
     if (TSelection::getCurrent()) TSelection::getCurrent()->selectNone();
 
     TUndoManager::manager()->add(new OpenChildUndo());
     app->getCurrentXsheet()->setXsheet(scene->getXsheet());
     app->getCurrentXsheet()->notifyXsheetChanged();
     app->getCurrentColumn()->setColumnIndex(0);
-    app->getCurrentFrame()->setFrameIndex(0);
+    app->getCurrentFrame()->setFrameIndex(subXsheetFrame);
     changeSaveSubXsheetAsCommand();
   } else
     DVGui::error(QObject::tr("Select a sub-xsheet cell."));
diff --git a/toonz/sources/toonz/xshcellviewer.cpp b/toonz/sources/toonz/xshcellviewer.cpp
index 5508a4a..a934b26 100644
--- a/toonz/sources/toonz/xshcellviewer.cpp
+++ b/toonz/sources/toonz/xshcellviewer.cpp
@@ -2812,6 +2812,7 @@ void CellArea::contextMenuEvent(QContextMenuEvent *event) {
   CellPosition cellPosition = m_viewer->xyToPosition(event->pos());
   int row                   = cellPosition.frame();
   int col                   = cellPosition.layer();
+  TXshCell cell             = m_viewer->getXsheet()->getCell(row, col);
 
   QMenu menu(this);
 
@@ -2887,7 +2888,7 @@ void CellArea::contextMenuEvent(QContextMenuEvent *event) {
         }
       if (areCellsEmpty) break;
     }
-    createCellMenu(menu, areCellsEmpty);
+    createCellMenu(menu, areCellsEmpty, cell);
   } else {
     if (col >= 0) {
       m_viewer->getCellSelection()->makeCurrent();
@@ -2895,9 +2896,9 @@ void CellArea::contextMenuEvent(QContextMenuEvent *event) {
       m_viewer->setCurrentColumn(col);
     }
     if (!xsh->getCell(row, col).isEmpty())
-      createCellMenu(menu, true);
+      createCellMenu(menu, true, cell);
     else
-      createCellMenu(menu, false);
+      createCellMenu(menu, false, cell);
   }
 
   if (!menu.isEmpty()) menu.exec(event->globalPos());
@@ -2971,7 +2972,7 @@ void CellArea::onControlPressed(bool pressed) {
 const bool CellArea::isControlPressed() { return isCtrlPressed; }
 
 //-----------------------------------------------------------------------------
-void CellArea::createCellMenu(QMenu &menu, bool isCellSelected) {
+void CellArea::createCellMenu(QMenu &menu, bool isCellSelected, TXshCell cell) {
   CommandManager *cmdManager = CommandManager::instance();
 
   bool soundCellsSelected = m_viewer->areSoundCellsSelected();
@@ -3111,6 +3112,13 @@ void CellArea::createCellMenu(QMenu &menu, bool isCellSelected) {
       menu.addAction(cmdManager->getAction(MI_ViewFile));
 
     menu.addSeparator();
+
+    if (!cell.isEmpty() && cell.m_level && cell.m_level->getChildLevel()) {
+      menu.addAction(cmdManager->getAction(MI_OpenChild));
+
+      menu.addSeparator();
+    }
+
     if (selectionContainRasterImage(m_viewer->getCellSelection(),
                                     m_viewer->getXsheet())) {
       QMenu *editImageMenu = new QMenu(tr("Edit Image"), this);
diff --git a/toonz/sources/toonz/xshcellviewer.h b/toonz/sources/toonz/xshcellviewer.h
index 1d3e3c3..41b9d61 100644
--- a/toonz/sources/toonz/xshcellviewer.h
+++ b/toonz/sources/toonz/xshcellviewer.h
@@ -7,6 +7,8 @@
 #include <QLineEdit>
 #include "orientation.h"
 
+#include "toonz/txshcell.h"
+
 // forward declaration
 class XsheetViewer;
 class QMenu;
@@ -144,7 +146,7 @@ protected:
   /*!Crea il menu' del tasto destro che si visualizza quando si clicca sulla
 cella,
 distinguendo i due casi: cella piena, cella vuota.*/
-  void createCellMenu(QMenu &menu, bool isCellSelected);
+  void createCellMenu(QMenu &menu, bool isCellSelected, TXshCell cell);
   //! Crea il menu' del tasto destro che si visualizza si clicca su un key
   //! frame.
   void createKeyMenu(QMenu &menu);