def _initStorageCombo(self):
        # If there's only one dataset, show the path in the combo
        showpaths = False
        if len(self._laneIndexes) == 1:
            op = self.tempOps.values()[0]
            info = op.Dataset.value
            cwd = op.WorkingDirectory.value
            filePath = PathComponents(info.filePath).externalPath
            absPath, relPath = getPathVariants(filePath, cwd)
            showpaths = not info.fromstack

        if showpaths:
            self.storageComboBox.addItem("Copied to Project File",
                                         userData=StorageLocation.ProjectFile)
            self.storageComboBox.addItem("Absolute Link: " + absPath,
                                         userData=StorageLocation.AbsoluteLink)
            self.storageComboBox.addItem("Relative Link: " + relPath,
                                         userData=StorageLocation.RelativeLink)
        else:
            self.storageComboBox.addItem("Copied to Project File",
                                         userData=StorageLocation.ProjectFile)
            self.storageComboBox.addItem("Absolute Link",
                                         userData=StorageLocation.AbsoluteLink)
            self.storageComboBox.addItem("Relative Link",
                                         userData=StorageLocation.RelativeLink)

        self.storageComboBox.setCurrentIndex(-1)
    def _applyStorageComboToTempOps(self, index):
        if index == -1:
            return

        newStorageLocation, goodcast = self.storageComboBox.itemData(
            index).toInt()
        assert goodcast

        # Save a copy of our settings
        oldInfos = {}
        for laneIndex, op in self.tempOps.items():
            oldInfos[laneIndex] = copy.copy(op.Dataset.value)

        # Attempt to apply to all temp operators
        try:
            for laneIndex, op in self.tempOps.items():
                info = copy.copy(op.Dataset.value)

                if info.location == DatasetInfo.Location.ProjectInternal:
                    thisLaneStorage = StorageLocation.ProjectFile
                elif info.location == DatasetInfo.Location.FileSystem:
                    # Determine if the path is relative or absolute
                    if os.path.isabs(info.filePath):
                        thisLaneStorage = StorageLocation.AbsoluteLink
                    else:
                        thisLaneStorage = StorageLocation.RelativeLink

                if thisLaneStorage != newStorageLocation:
                    if newStorageLocation == StorageLocation.ProjectFile:
                        info.location = DatasetInfo.Location.ProjectInternal
                    else:
                        info.location = DatasetInfo.Location.FileSystem
                        cwd = op.WorkingDirectory.value
                        absPath, relPath = getPathVariants(info.filePath, cwd)
                        if newStorageLocation == StorageLocation.AbsoluteLink:
                            info.filePath = absPath
                        elif newStorageLocation == StorageLocation.RelativeLink:
                            info.filePath = relPath
                        else:
                            assert False, "Unknown storage location setting."
                    op.Dataset.setValue(info)
            self._error_fields.discard('Storage Location')
            return True

        except Exception as e:
            # Revert everything back to the previous state
            for laneIndex, op in self.tempOps.items():
                op.Dataset.setValue(oldInfos[laneIndex])

            traceback.print_exc()
            msg = "Could not set new storage location settings due to an exception:\n"
            msg += "{}".format(e)
            QMessageBox.warning(self, "Error", msg)
            self._error_fields.add('Storage Location')
            return False

        finally:
            self._updateStorageCombo()
    def _applyStorageComboToTempOps(self, index):
        if index == -1:
            return
        
        newStorageLocation, goodcast = self.storageComboBox.itemData( index ).toInt()
        assert goodcast
        
        # Save a copy of our settings
        oldInfos = {}
        for laneIndex, op in self.tempOps.items():
            oldInfos[laneIndex] = copy.copy( op.Dataset.value )
        
        # Attempt to apply to all temp operators
        try:
            for laneIndex, op in self.tempOps.items():
                info = copy.copy( op.Dataset.value )
                
                if info.location == DatasetInfo.Location.ProjectInternal:
                    thisLaneStorage = StorageLocation.ProjectFile
                elif info.location == DatasetInfo.Location.FileSystem:
                    # Determine if the path is relative or absolute
                    if os.path.isabs(info.filePath):
                        thisLaneStorage = StorageLocation.AbsoluteLink
                    else:
                        thisLaneStorage = StorageLocation.RelativeLink

                if thisLaneStorage != newStorageLocation:
                    if newStorageLocation == StorageLocation.ProjectFile:
                        info.location = DatasetInfo.Location.ProjectInternal
                    else:
                        info.location = DatasetInfo.Location.FileSystem 
                        cwd = op.WorkingDirectory.value
                        absPath, relPath = getPathVariants( info.filePath, cwd )
                        if newStorageLocation == StorageLocation.AbsoluteLink:
                            info.filePath = absPath
                        elif newStorageLocation == StorageLocation.RelativeLink:
                            info.filePath = relPath
                        else:
                            assert False, "Unknown storage location setting."
                    op.Dataset.setValue( info )
            self._error_fields.discard('Storage Location')
            return True
        
        except Exception as e:
            # Revert everything back to the previous state
            for laneIndex, op in self.tempOps.items():
                op.Dataset.setValue( oldInfos[laneIndex] )
            
            traceback.print_exc()
            msg = "Could not set new storage location settings due to an exception:\n"
            msg += "{}".format( e )
            QMessageBox.warning(self, "Error", msg)
            self._error_fields.add('Storage Location')
            return False
        
        finally:
            self._updateStorageCombo()
    def _initInternalDatasetNameCombo(self):
        # If any dataset is either (1) not hdf5 or (2) project-internal, then we can't change the internal path.
        h5Exts = ['.ilp', '.h5', '.hdf5']
        for laneIndex in self._laneIndexes:
            tmpOp = self.tempOps[laneIndex]
            datasetInfo = tmpOp.Dataset.value
            externalPath = PathComponents(datasetInfo.filePath).externalPath
            if os.path.splitext(externalPath)[1] not in h5Exts \
            or datasetInfo.location == DatasetInfo.Location.ProjectInternal:
                self.internalDatasetNameComboBox.addItem("N/A")
                self.internalDatasetNameComboBox.setEnabled(False)
                return

        # Enable IFF all datasets have at least one common internal dataset, and only show COMMON datasets
        allInternalPaths = set()
        commonInternalPaths = None

        for laneIndex in self._laneIndexes:
            tmpOp = self.tempOps[laneIndex]
            datasetInfo = tmpOp.Dataset.value

            externalPath = PathComponents(datasetInfo.filePath).externalPath
            absPath, relPath = getPathVariants(externalPath,
                                               tmpOp.WorkingDirectory.value)
            internalPaths = set(self._getPossibleInternalPaths(absPath))

            if commonInternalPaths is None:
                # Init with the first file's set of paths
                commonInternalPaths = internalPaths

            # Set operations
            allInternalPaths |= internalPaths
            commonInternalPaths &= internalPaths
            if len(commonInternalPaths) == 0:
                self.internalDatasetNameComboBox.addItem(
                    "Couldn't find a dataset name common to all selected files."
                )
                self.internalDatasetNameComboBox.setEnabled(False)
                return

        uncommonInternalPaths = allInternalPaths - commonInternalPaths
        # Add all common paths to the combo
        for path in sorted(commonInternalPaths):
            self.internalDatasetNameComboBox.addItem(path)

        # Add the remaining ones, but disable them since they aren't common to all files:
        for path in sorted(uncommonInternalPaths):
            self.internalDatasetNameComboBox.addItem(path)
            # http://theworldwideinternet.blogspot.com/2011/01/disabling-qcombobox-items.html
            model = self.internalDatasetNameComboBox.model()
            index = model.index(self.internalDatasetNameComboBox.count() - 1,
                                0)
            model.setData(index, 0, Qt.UserRole - 1)

        # Finally, initialize with NO item selected
        self.internalDatasetNameComboBox.setCurrentIndex(-1)
    def _initInternalDatasetNameCombo(self):
        # If any dataset is either (1) not hdf5 or (2) project-internal, then we can't change the internal path.
        h5Exts = [".ilp", ".h5", ".hdf5"]
        for laneIndex in self._laneIndexes:
            tmpOp = self.tempOps[laneIndex]
            datasetInfo = tmpOp.Dataset.value
            externalPath = PathComponents(datasetInfo.filePath).externalPath
            if (
                os.path.splitext(externalPath)[1] not in h5Exts
                or datasetInfo.location == DatasetInfo.Location.ProjectInternal
            ):
                self.internalDatasetNameComboBox.addItem("N/A")
                self.internalDatasetNameComboBox.setEnabled(False)
                return

        # Enable IFF all datasets have at least one common internal dataset, and only show COMMON datasets
        allInternalPaths = set()
        commonInternalPaths = None

        for laneIndex in self._laneIndexes:
            tmpOp = self.tempOps[laneIndex]
            datasetInfo = tmpOp.Dataset.value

            externalPath = PathComponents(datasetInfo.filePath).externalPath
            absPath, relPath = getPathVariants(externalPath, tmpOp.WorkingDirectory.value)
            internalPaths = set(self._getPossibleInternalPaths(absPath))

            if commonInternalPaths is None:
                # Init with the first file's set of paths
                commonInternalPaths = internalPaths

            # Set operations
            allInternalPaths |= internalPaths
            commonInternalPaths &= internalPaths
            if len(commonInternalPaths) == 0:
                self.internalDatasetNameComboBox.addItem("Couldn't find a dataset name common to all selected files.")
                self.internalDatasetNameComboBox.setEnabled(False)
                return

        uncommonInternalPaths = allInternalPaths - commonInternalPaths
        # Add all common paths to the combo
        for path in sorted(commonInternalPaths):
            self.internalDatasetNameComboBox.addItem(path)

        # Add the remaining ones, but disable them since they aren't common to all files:
        for path in sorted(uncommonInternalPaths):
            self.internalDatasetNameComboBox.addItem(path)
            # http://theworldwideinternet.blogspot.com/2011/01/disabling-qcombobox-items.html
            model = self.internalDatasetNameComboBox.model()
            index = model.index(self.internalDatasetNameComboBox.count() - 1, 0)
            model.setData(index, 0, Qt.UserRole - 1)

        # Finally, initialize with NO item selected
        self.internalDatasetNameComboBox.setCurrentIndex(-1)
    def _initStorageCombo(self):
        # If there's only one dataset, show the path in the combo
        showpaths = False
        if len( self._laneIndexes ) == 1:
            op = self.tempOps.values()[0]
            info = op.Dataset.value
            cwd = op.WorkingDirectory.value
            filePath = PathComponents(info.filePath).externalPath
            absPath, relPath = getPathVariants(filePath, cwd)
            showpaths = not info.fromstack

        if showpaths:
            self.storageComboBox.addItem( "Copied to Project File", userData=StorageLocation.ProjectFile )
            self.storageComboBox.addItem( "Absolute Link: " + absPath, userData=StorageLocation.AbsoluteLink )
            self.storageComboBox.addItem( "Relative Link: " + relPath, userData=StorageLocation.RelativeLink )
        else:
            self.storageComboBox.addItem( "Copied to Project File", userData=StorageLocation.ProjectFile )
            self.storageComboBox.addItem( "Absolute Link", userData=StorageLocation.AbsoluteLink )
            self.storageComboBox.addItem( "Relative Link", userData=StorageLocation.RelativeLink )

        self.storageComboBox.setCurrentIndex(-1)