Skip to content

Commit

Permalink
Save Improvements and Radius Line event
Browse files Browse the repository at this point in the history
Save Improvement: Checking for dirty and undo/ redos before allowing user to save.
Created separate event for radius line changes
  • Loading branch information
jtle00 committed Aug 2, 2024
1 parent d675fb5 commit 04896c3
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 74 deletions.
29 changes: 28 additions & 1 deletion pymapmanager/annotations/baseAnnotationsCore.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def __init__(self,

self._defaultColums = defaultColums

self._isDirty = False #abj

self._buildDataFrame()

@property
Expand Down Expand Up @@ -181,6 +183,8 @@ def moveSpine(self, spineID :int, x, y, z):
# rebuild df from mutated full map
self._buildDataFrame()

self._setDirty(True) #abj

def manualConnectSpine(self, spineID : int, x, y, z):
"""Manually connect a spine to specified image (x,y,z).
Expand All @@ -196,6 +200,8 @@ def manualConnectSpine(self, spineID : int, x, y, z):
# rebuild df from mutated full map
self._buildDataFrame()

self._setDirty(True) #abj

#abj
def autoResetBrightestIndex(self, spineID, segmentID, point, findBrightest : bool = True):

Expand Down Expand Up @@ -255,12 +261,13 @@ def setValue(self, colName : str, row : int, value):
logger.error(f'did not set value for col "{colName}" at row {row}')

def undo(self):
# abj - this doesnt actually get called???
logger.info("undo in baseAnnotationsCore")
self._fullMap.undo()
self._buildDataFrame()

def redo(self):
self._fullMap.redo()
self._buildDataFrame()

def __str__(self):
_str = ''
Expand All @@ -269,6 +276,15 @@ def __str__(self):

def _getClassName(self) -> str:
return self.__class__.__name__

def _setDirty(self, dirtyVal : bool = True):
"""
# reset to false everytime there is a save
"""
self._isDirty = dirtyVal

def getDirty(self):
return self._isDirty

class SpineAnnotationsCore(AnnotationsCore):

Expand Down Expand Up @@ -390,6 +406,8 @@ def addSpine(self, segmentID : int, x : int, y : int, z : int) -> int:

self._buildDataFrame()

self._setDirty(True) #abj

return newSpineID

def deleteAnnotation(self, rowIdx : Union[int, List[int]]) -> None:
Expand All @@ -404,6 +422,8 @@ def deleteAnnotation(self, rowIdx : Union[int, List[int]]) -> None:

self._buildDataFrame()

self._setDirty(True) #abj

def editSpine(self, editSpineProperty : EditSpinePropertyEvent):
# spineID:117 col:isBad value:True
# logger.info(editSpineProperty)
Expand All @@ -417,6 +437,8 @@ def editSpine(self, editSpineProperty : EditSpinePropertyEvent):

self._buildDataFrame()

self._setDirty(True) #abj

class LineAnnotationsCore(AnnotationsCore):

@property
Expand All @@ -441,6 +463,8 @@ def newSegment(self) -> int:
logger.info(f'created new segment {newSegmentID} {type(newSegmentID)}')

self._buildDataFrame()

self._setDirty(True) #abj

# print('df:')
# print(self.getDataFrame())
Expand All @@ -456,6 +480,9 @@ def deleteSegment(self, segmentID : int):
# logger.info(f'segmentID:{segmentID} _numSpines:{_numSpines}')

_deleted = self._fullMap.deleteSegment(segmentID)

self._setDirty(True) #abj

# logger.info(f'_deleted:{_deleted}')

self._buildDataFrame()
Expand Down
140 changes: 96 additions & 44 deletions pymapmanager/interface2/mainMenus.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from qtpy import QtWidgets

from pymapmanager._logger import logger, setLogLevel
from pymapmanager.interface2.stackWidgets import stackWidget2

class PyMapManagerMenus:
"""Main app menus including loaded map and stack widgets.
Expand All @@ -25,55 +26,56 @@ def _buildMenus(self, mainMenu, mainWindow):

#
# file
fileMenu = mainMenu.addMenu("&File")

loadFileAction = QtWidgets.QAction("Open...", self.getApp())
loadFileAction.setCheckable(False) # setChecked is True by default?
loadFileAction.setShortcut("Ctrl+O")
loadFileAction.triggered.connect(self.getApp().openFile)
fileMenu.addAction(loadFileAction)
self.fileMenu = mainMenu.addMenu("&File")
self.fileMenu.aboutToShow.connect(self._refreshFileMenu)

# loadFileAction = QtWidgets.QAction("Open...", self.getApp())
# loadFileAction.setCheckable(False) # setChecked is True by default?
# loadFileAction.setShortcut("Ctrl+O")
# loadFileAction.triggered.connect(self.getApp().openFile)
# fileMenu.addAction(loadFileAction)

loadFolderAction = QtWidgets.QAction("Open Time-Series...", self.getApp())
loadFolderAction.setCheckable(False) # setChecked is True by default?
loadFolderAction.triggered.connect(self.getApp().openTimeSeries)
fileMenu.addAction(loadFolderAction)

# like the help menu, this gets rerouted to the main python/sanp menu
# settingsMenu = fileMenu.addMenu('Settings...')
# name = "Settings..."
# action = QtWidgets.QAction(name, self.getApp())
# # action.aboutToShow.connect(self._refreshSettingsMenu)
# action.triggered.connect(self._on_settings_menu_action)
# settingsMenu.aboutToShow.connect(self._refreshSettingsMenu)
# settingsMenu.addAction(action)

fileMenu.addSeparator()

# abj
saveFileAction = QtWidgets.QAction("Save", self.getApp())
saveFileAction.setCheckable(False) # setChecked is True by default?
saveFileAction.setShortcut("Ctrl+S")
saveFileAction.triggered.connect(self.getApp().saveFile)
fileMenu.addAction(saveFileAction)
# loadFolderAction = QtWidgets.QAction("Open Time-Series...", self.getApp())
# loadFolderAction.setCheckable(False) # setChecked is True by default?
# loadFolderAction.triggered.connect(self.getApp().openTimeSeries)
# fileMenu.addAction(loadFolderAction)

# # like the help menu, this gets rerouted to the main python/sanp menu
# # settingsMenu = fileMenu.addMenu('Settings...')
# # name = "Settings..."
# # action = QtWidgets.QAction(name, self.getApp())
# # # action.aboutToShow.connect(self._refreshSettingsMenu)
# # action.triggered.connect(self._on_settings_menu_action)
# # settingsMenu.aboutToShow.connect(self._refreshSettingsMenu)
# # settingsMenu.addAction(action)

# fileMenu.addSeparator()

# # abj
# saveFileAction = QtWidgets.QAction("Save", self.getApp())
# saveFileAction.setCheckable(False) # setChecked is True by default?
# saveFileAction.setShortcut("Ctrl+S")
# saveFileAction.triggered.connect(self.getApp().saveFile)
# fileMenu.addAction(saveFileAction)

saveAsFileAction = QtWidgets.QAction("Save As", self.getApp())
saveAsFileAction.setCheckable(False) # setChecked is True by default?
saveAsFileAction.triggered.connect(self.getApp().saveAsFile)
fileMenu.addAction(saveAsFileAction)
# saveAsFileAction = QtWidgets.QAction("Save As", self.getApp())
# saveAsFileAction.setCheckable(False) # setChecked is True by default?
# saveAsFileAction.triggered.connect(self.getApp().saveAsFile)
# fileMenu.addAction(saveAsFileAction)

fileMenu.addSeparator()
# fileMenu.addSeparator()

# open recent (submenu) will show two lists, one for files and then one for folders
self.openRecentMenu = QtWidgets.QMenu("Open Recent ...")
self.openRecentMenu.aboutToShow.connect(self._refreshOpenRecent)
fileMenu.addMenu(self.openRecentMenu)
# # open recent (submenu) will show two lists, one for files and then one for folders
# self.openRecentMenu = QtWidgets.QMenu("Open Recent ...")
# self.openRecentMenu.aboutToShow.connect(self._refreshOpenRecent)
# fileMenu.addMenu(self.openRecentMenu)

fileMenu.addSeparator()
# fileMenu.addSeparator()

self.settingsMenu = fileMenu.addMenu('User Options...')
# _emptyAction = QtWidgets.QAction("None", self.getApp())
# self.settingsMenu.addAction(_emptyAction)
self.settingsMenu.aboutToShow.connect(self._refreshSettingsMenu)
# self.settingsMenu = fileMenu.addMenu('User Options...')
# # _emptyAction = QtWidgets.QAction("None", self.getApp())
# # self.settingsMenu.addAction(_emptyAction)
# self.settingsMenu.aboutToShow.connect(self._refreshSettingsMenu)

#
# edit
Expand Down Expand Up @@ -311,7 +313,7 @@ def _refreshEditMenu(self):
enableUndo = True
enableRedo = True

from pymapmanager.interface2.stackWidgets import stackWidget2
# from pymapmanager.interface2.stackWidgets import stackWidget2
frontWindow = self.getApp().getFrontWindow()
if isinstance(frontWindow, stackWidget2):
nextUndo = frontWindow.getUndoRedo().nextUndoStr()
Expand Down Expand Up @@ -406,6 +408,56 @@ def _on_settings_menu_action(self, action):
else:
logger.warning(f'did not understand "{text}" action?')

#abj
def _refreshFileMenu(self):
""" Dynamically generate the file stack/map menu.
"""
self.fileMenu.clear()

loadFileAction = QtWidgets.QAction("Open...", self.getApp())
loadFileAction.setCheckable(False) # setChecked is True by default?
loadFileAction.setShortcut("Ctrl+O")
loadFileAction.triggered.connect(self.getApp().openFile)
self.fileMenu.addAction(loadFileAction)

loadFolderAction = QtWidgets.QAction("Open Time-Series...", self.getApp())
loadFolderAction.setCheckable(False) # setChecked is True by default?
loadFolderAction.triggered.connect(self.getApp().openTimeSeries)
self.fileMenu.addAction(loadFolderAction)
self.fileMenu.addSeparator()

# abj
frontWindow = self.getApp().getFrontWindow()
if isinstance(frontWindow, stackWidget2):
enableUndo = frontWindow.getUndoRedo().numUndo() > 0
enableRedo = frontWindow.getUndoRedo().numRedo() > 0
isDirty = frontWindow.getDirty()
logger.info(f"isDirty: {isDirty}")

saveFileAction = QtWidgets.QAction("Save", self.getApp())
saveFileAction.setCheckable(False) # setChecked is True by default?
saveFileAction.setShortcut("Ctrl+S")
# saveFileAction.setEnabled(enableUndo and isDirty)
saveFileAction.setEnabled(isDirty and (enableUndo or enableRedo))

saveFileAction.triggered.connect(self.getApp().saveFile)
self.fileMenu.addAction(saveFileAction)

saveAsFileAction = QtWidgets.QAction("Save As", self.getApp())
saveAsFileAction.setCheckable(False) # setChecked is True by default?
saveAsFileAction.triggered.connect(self.getApp().saveAsFile)
self.fileMenu.addAction(saveAsFileAction)
self.fileMenu.addSeparator()

# open recent (submenu) will show two lists, one for files and then one for folders
self.openRecentMenu = QtWidgets.QMenu("Open Recent ...")
self.openRecentMenu.aboutToShow.connect(self._refreshOpenRecent)
self.fileMenu.addMenu(self.openRecentMenu)
self.fileMenu.addSeparator()

self.settingsMenu = self.fileMenu.addMenu('User Options...')
self.settingsMenu.aboutToShow.connect(self._refreshSettingsMenu)

def _refreshOpenRecent(self):
"""Dynamically generate the open recent stack/map menu.
Expand Down
26 changes: 21 additions & 5 deletions pymapmanager/interface2/runInterfaceJohnson.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,33 @@ def run():
# path = 'C:\\Users\\johns\\Documents\\GitHub\\MapManagerCore\\data\\rr30a_s0u.mmap'
# path = '\\Users\\johns\\Documents\\GitHub\\MapManagerCore\\data\\rr30a_s0u.mmap'
# path = '/Users/johns/Documents/GitHub/MapManagerCore/data/rr30a_s0u.mmap'
path = '/Users/johns/Documents/GitHub/MapManagerCore/data/test2.mmap'


path = '/Users/johns/Documents/GitHub/MapManagerCore/data/rr30a_s0u_v3.mmap'
# path = '/Users/johns/Documents/GitHub/MapManagerCore/data/test2.mmap'
# path = '/Users/johns/Documents/GitHub/PyMapManager-Data/one-timepoint/rr30a_s0_ch1.mmap'
# import mapmanagercore

# pooch path
import mapmanagercore.data
# path = mapmanagercore.getSingleTimepointMap()
# path = mapmanagercore.data.getSingleTimepointMap()
print("path", path)
sw2 = app.loadStackWidget(path)

# from mapmanagercore.data import getSingleTimepointMap

# path = getSingleTimepointMap()
# print("path: ", path)
# # sys.exit()
# sw2 = app.loadStackWidget(path)


df = sw2.getStack().getPointAnnotations().getDataFrame()
# df = sw2.getStack().getPointAnnotations().getDataFrame()
# df['userType'] = 1
# sw2.getStack().getPointAnnotations().intializeIsBad()
# sw2.getStack().getPointAnnotations().intializeUserType()

sw2.zoomToPointAnnotation(120, isAlt=True)
# sw2.runPlugin('Scatter Plot', inDock=True)

Expand All @@ -53,5 +69,5 @@ def run2():
sys.exit(app.exec_())

if __name__ == '__main__':
run()
# run2()
# run()
run2()
13 changes: 7 additions & 6 deletions pymapmanager/interface2/stackWidgets/annotationPlotWidget2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,7 @@ def _getScatterConnect(self, df : pd.DataFrame):
return dfRet

def slot_setSlice(self, sliceNumber: int):

logger.info("setting slice in line plot")
# startSec = time.time()

# abb
Expand All @@ -1272,7 +1272,13 @@ def slot_setSlice(self, sliceNumber: int):

super().slot_setSlice(sliceNumber) # draws centerline

self.refreshRadiusLines(sliceNumber)

# stopSec = time.time()
# logger.info(f'{self.getClassName()} took {round(stopSec-startSec,4)} sec')

def refreshRadiusLines(self, sliceNumber: int):

if self.showRadiusLines:
zPlusMinus = self._displayOptions["zPlusMinus"]
radiusOffset = self._displayOptions['radius']
Expand All @@ -1285,8 +1291,6 @@ def slot_setSlice(self, sliceNumber: int):
dfLeft["y"].to_numpy(),
connect=_lineConnect,
)

# dfRight = self._annotations.getRightRadiusPlot(None, sliceNumber, 1)

dfRight = self._annotations.getRightRadiusPlot(None, sliceNumber, zPlusMinus, radiusOffset)
_lineConnect = self._getScatterConnect(dfRight)
Expand All @@ -1296,9 +1300,6 @@ def slot_setSlice(self, sliceNumber: int):
connect=_lineConnect,
)

# stopSec = time.time()
# logger.info(f'{self.getClassName()} took {round(stopSec-startSec,4)} sec')

def selectedEvent(self, event: pmmEvent):
"""
Expand Down
9 changes: 6 additions & 3 deletions pymapmanager/interface2/stackWidgets/event/spineEvent.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,13 @@ class AutoConnectSpineEvent(_EditSpine):
"""
def __init__(self,
mmWidget : mmWidget2,
spineID : int = None):
spineID : int):
super().__init__(pmmEventType.autoConnectSpine, mmWidget)
if spineID is not None:
self.addEdit(spineID=spineID)
# if spineID is not None:
self.addEdit(spineID=spineID)

def getName(self) -> str:
return 'Auto Connect Spine'

def _getItem(self, item : SpineEdit):
"""Get the meaningful keys for this edit type.
Expand Down
Loading

0 comments on commit 04896c3

Please sign in to comment.