Пример #1
0
class MasterTestCase(OfficeTestCase):

    def setUp(self):
        super().setUp()
        self.master = Master(MASTER_LIST_SHEET_NAME)
        self.actions = self.master.getActions()

    def testMasterInstance(self):
        self.assertIsInstance(self.master.data, list)
        self.assertEqual(self.master.name, MASTER_LIST_SHEET_NAME)
        self.assertEqual(len(self.master.actionColors), len(self.master.dataRows))

    def testGetActions(self):
        self.assertIsInstance(self.actions, list)
        self.assertTrue(self.actions)
        for action in self.actions:
            self.assertIsInstance(action, Action)

    def testGetActionsForView(self):
        actions = self.master.getActions('Target')
        self.assertTrue(actions[0].name, 'Minotaur (Idle)')

    def testGetDefaultActions(self):
        actions = self.master.getActions('Default')
        self.assertNotEqual(len(self.master.getActions()), len(actions))
Пример #2
0
    def testSetVerticalAlignmentToRange(self):
        """
        A test that sets vertical alignment to a range and then tests if it's
        what it should be.
        """
        sheet = Master(MASTER_LIST_SHEET_NAME).sheet
        format.setVerticalAlignmentToRange(sheet, VerticalAlignment.CENTER, 1,
                                           10, 20, 25)

        cellRange = sheet.getCellRangeByPosition(1, 10, 20, 25)
        self.assertEqual(cellRange.VertJustify, CENTER)
Пример #3
0
    def testSetHorizontalAlignmentToRange(self):
        """
        A test that sets horizontal alignment to a range and then tests if it's
        what it should be.
        """
        sheet = Master(MASTER_LIST_SHEET_NAME).sheet
        format.setHorizontalAlignmentToRange(sheet, HorizontalAlignment.RIGHT,
                                             1, 4)

        area = cursor.getSheetContent(sheet)
        cellRange = sheet.getCellRangeByPosition(1, 0, 1 + 4, len(area) - 1)
        self.assertEqual(cellRange.HoriJustify, RIGHT)
Пример #4
0
 def testActionConditionalFormats(self):
     masterSheet = Master(MASTER_LIST_SHEET_NAME)
     detailsUnoSheet = Sheet.getByName(self.detailsName)
     actionConditionalFormat = conditionalFormat.createActionConditionalFormats(
         detailsUnoSheet, masterSheet, self.view)
     self.assertGreater(actionConditionalFormat.getCount(), 0)
     self.assertIn('Entry1', actionConditionalFormat.getElementNames())
Пример #5
0
 def _readSheetContent(self):
     # We need master sheet to get number of phases for each Action in the
     # Detail class. Details sheet doesn't provide enough information.
     self.masterSheet = Master(MASTER_LIST_SHEET_NAME)
     self.sheet = Sheet.getByName(self.name)
     self.data = cursor.getSheetContent(self.sheet)
     self.nameColumnIndex = helper.getColumnPosition(
         self.data, 'Action Name', 0)
     self.modifiersColumnIndex = helper.getColumnPosition(
         self.data, 'Modifiers', 1)
     self.inputToCompareColumnIndex = helper.getColumnPosition(
         self.data, 'Input to Compare', 2)
     self.notesIndex1 = helper.getColumnPosition(self.data, 'Notes 1', 3)
     self.notesIndex2 = helper.getColumnPosition(self.data, 'Notes 2', 4)
     self.notesIndex3 = helper.getColumnPosition(self.data, 'Notes 3', 5)
     self.dataRows = self._dataRows()
     self.details = self._readDetails()
Пример #6
0
 def testFilterBy(self):
     master = Master(MASTER_LIST_SHEET_NAME)
     filteredRows = filter.filterRows(
         lambda row: row[master.viewColumnIndex] == 'Default',
         master.dataRows)
     self.assertTrue(filteredRows)
     for row in filteredRows:
         self.assertEqual(row[master.viewColumnIndex], 'Default')
Пример #7
0
def updateDetails(*args, **kwargs):
    """
    A macro function that will update one Details-sheet while preserving
    previous user data. Movelister can have multiple Details-views. To determine
    which one is updated, the code checks which Overview button was pressed to
    trigger the macro.
    """
    try:
        if not Sheet.checkTemplatesExists():
            message_box.showWarningWithOk(
                'This file doesn\'t seem to have all necessary templates. Can\'t generate.'
            )
            return

        # Get Overview sheet name from active sheet or from provided kwargs.
        activeOverviewName = kwargs.get('activeSheet',
                                        helper.getActiveSheetName())
        # Get view name for the Details. This is presented in Overview sheet name inside parentheses.
        viewName = names.getViewName(activeOverviewName)
        detailsSheetName = names.getDetailsName(viewName)
        previousDetails = Details(viewName)
        if Sheet.hasByName(detailsSheetName):
            # Check if user wants to update existing Details-sheet.
            if not message_box.showSheetUpdateWarning():
                return
            previousDetails = Details.fromSheet(detailsSheetName)
        modifiersSheet = Modifiers(MODIFIER_LIST_SHEET_NAME)
        parentOverview = Overview.fromSheet(activeOverviewName)
        # Create new Details sheet by combining new and existing data.
        newDetails = UpdateDetails.update(modifiersSheet, parentOverview,
                                          previousDetails, viewName)
        # Delete previous Details-sheet and generate a new one.
        Sheet.deleteSheetByName(detailsSheetName)
        formatter = DetailsFormatter(newDetails, parentOverview)
        unoDetailsSheet = formatter.generate()
        # Make columns width optimal.
        length = cursor.getWidth(unoDetailsSheet)
        format.setOptimalWidthToRange(unoDetailsSheet, 0, length)
        # Generate data validation.
        validation.setDataValidationToDetailsSheet(unoDetailsSheet, viewName)
        # Generate named ranges.
        about = About(ABOUT_SHEET_NAME)
        if about.isGenerateNamedRangesOn():
            NamedRanges(unoDetailsSheet, 0, viewName).generate()
        # Generate cell styles used for details sheet.
        UpdateStyles.update()
        # Create conditional format ranges to the new details sheet which uses
        # styles created above.
        masterSheet = Master(MASTER_LIST_SHEET_NAME)
        resultsSheet = Results(RESULT_LIST_SHEET_NAME)
        inputSheet = Inputs(INPUT_LIST_SHEET_NAME)
        conditionalFormat.createDetailsConditionalFormats(
            unoDetailsSheet, masterSheet, resultsSheet, inputSheet, viewName)
        # Set new sheet as currently active sheet.
        helper.setActiveSheet(unoDetailsSheet)
    except errors.MovelisterError as e:
        helper.setActiveSheet(e.activeSheet)
        message_box.showWarningWithOk(str(e))
Пример #8
0
 def update(cls):
     """
     Remove all old non-default styles and create new ones from sheets
     Results, Inputs and Master List.
     """
     cls.resultsSheet = Results(RESULT_LIST_SHEET_NAME)
     cls.inputsSheet = Inputs(INPUT_LIST_SHEET_NAME)
     cls.masterSheet = Master(MASTER_LIST_SHEET_NAME)
     cls._removeOldStyles()
     cls._createStyles()
Пример #9
0
 def testCreateOverview(self):
     master = Master(MASTER_LIST_SHEET_NAME)
     viewName = 'Default'
     overview = OverviewFactory.createOverview(master, viewName)
     modifiers = [
         'WPN1', 'WPN2', 'WPN3', 'Super', 'FL1', 'FL2', 'PG', 'LAM', 'PAM',
         's_b', 't_b'
     ]
     actions = [
         'Attack s1', 'Attack s2', 'Attack s3', 'Attack s4', 'Swim', 'Rush'
     ]
     self.assertEqual(overview.name, 'Overview ({0})'.format(viewName))
     self.assertEqual(overview.viewName, viewName)
     self.assertTrue(
         all(modifier.name in modifiers for modifier in overview.modifiers))
     self.assertTrue(
         all(modAction.name in actions for modAction in overview.actions))
Пример #10
0
def updateOverview(*args, **kwargs):
    """
    A macro function to update or create a new Overview sheet. Updated sheet
    will include earlier user data in the old Overview if any.
    """
    try:
        if not Sheet.checkTemplatesExists():
            message_box.showWarningWithOk(
                'This file doesn\'t seem to have all necessary templates. Can\'t generate.'
            )
            return

        # Get name of the Overview which user wants to generate.
        masterSheet = Master(MASTER_LIST_SHEET_NAME)
        activeSheetName = kwargs.get('activeSheet', '')
        if activeSheetName == '':
            viewName = masterSheet.getOverviewName()
            overviewSheetName = names.getOverviewName(viewName)
        else:
            viewName = names.getViewName(activeSheetName)
            overviewSheetName = activeSheetName

        # Some error checking.
        if not viewName:
            message_box.showWarningWithOk(
                'You can\'t generate an Overview if no View-name is set in cell C1.'
            )
            return

        if viewName not in masterSheet.getViewNames():
            message_box.showWarningWithOk(
                'You can\'t generate a View that has no Actions. Make sure at least one '
                +
                'Action uses the View-name written in cell C1 before continuing.'
            )
            return

        oldOverview = Overview(viewName)
        # If document has existing Overview, then that is set as previous instead.
        if Sheet.hasByName(overviewSheetName):
            # Check if user wants to update existing Overview.
            if not message_box.showSheetUpdateWarning():
                return
            oldOverview = Overview.fromSheet(overviewSheetName)

        newOverview = UpdateOverview.update(oldOverview, viewName)

        # Place new Overview sheet on the same position as the previous one. If previous one
        # does not exist, then place right of the Master sheet instead.
        position = Sheet.getPosition(overviewSheetName)
        if not position:
            position = Sheet.getPosition(MASTER_LIST_SHEET_NAME) + 1
        # Delete old sheet if exists.
        Sheet.deleteSheetByName(overviewSheetName)
        # Generate a new one.
        formatter = OverviewFormatter(newOverview)
        unoOverviewSheet = formatter.generate(position)
        # Make columns width optimal.
        length = cursor.getWidth(unoOverviewSheet)
        format.setOptimalWidthToRange(unoOverviewSheet, 0, length)
        # Fix sheet colors.
        formatter.setOverviewModifierColors(overviewSheetName)
        # Set new sheet as currently active sheet.
        helper.setActiveSheet(unoOverviewSheet)
    except errors.MovelisterError as e:
        helper.setActiveSheet(e.activeSheet)
        message_box.showWarningWithOk(str(e))
Пример #11
0
 def setUp(self):
     super().setUp()
     self.master = Master(MASTER_LIST_SHEET_NAME)
Пример #12
0
 def setUp(self):
     super().setUp()
     self.master = Master(MASTER_LIST_SHEET_NAME)
     self.actions = self.master.getActions()
Пример #13
0
 def _updateLatestActions(cls, viewName):
     """
     Update latest actions filtered by given view name and add them to new overview.
     """
     masterSheet = Master(MASTER_LIST_SHEET_NAME)
     cls.newOverview.actions = masterSheet.getActions(viewName)
Пример #14
0
class Details:
    def __init__(self, viewName):
        self.name = names.getDetailsName(viewName)
        self.viewName = viewName
        self.details = []

    @classmethod
    def fromSheet(cls, sheetName):
        """
        Build instance of Detail from given sheet name which should represents
        current details sheet.
        """
        instance = cls(names.getViewName(sheetName))
        instance._readSheetContent()
        return instance

    def addDetail(self, detail):
        self.details.append(detail)

    def findDetail(self, seekedDetail):
        """
        Find given details instance from this Details sheet. Return it if it's
        found, otherwise return None.
        """
        return next(
            (detail for detail in self.details if detail == seekedDetail),
            None)

    def _readSheetContent(self):
        # We need master sheet to get number of phases for each Action in the
        # Detail class. Details sheet doesn't provide enough information.
        self.masterSheet = Master(MASTER_LIST_SHEET_NAME)
        self.sheet = Sheet.getByName(self.name)
        self.data = cursor.getSheetContent(self.sheet)
        self.nameColumnIndex = helper.getColumnPosition(
            self.data, 'Action Name', 0)
        self.modifiersColumnIndex = helper.getColumnPosition(
            self.data, 'Modifiers', 1)
        self.inputToCompareColumnIndex = helper.getColumnPosition(
            self.data, 'Input to Compare', 2)
        self.notesIndex1 = helper.getColumnPosition(self.data, 'Notes 1', 3)
        self.notesIndex2 = helper.getColumnPosition(self.data, 'Notes 2', 4)
        self.notesIndex3 = helper.getColumnPosition(self.data, 'Notes 3', 5)
        self.dataRows = self._dataRows()
        self.details = self._readDetails()

    def _dataRows(self):
        data = self.data[1:]
        return helper.stripTrailingEmptyRows(data)

    def _readDetails(self):
        # If details sheet is empty return.
        if not self.dataRows:
            return []
        currentName = ''
        currentMod = ''
        tempArray = []
        details = []
        filteredData = filter.filterRows(
            lambda row: row[self.nameColumnIndex] != '', self.dataRows)
        # Create an unused action to the array so that the loop can register all legit actions.
        emptyRow = helper.createEmptyRow(len(filteredData[0]))
        emptyRow[self.nameColumnIndex] = 'Unused'
        emptyRow[self.inputToCompareColumnIndex] = 'Unused'
        filteredData.append(emptyRow)
        # Iterate through filteredData to find out which rows contain relevant data for a single Detail.
        # Then send the relevant rows to _parseArrayIntoDetail function.
        for row in filteredData:
            if row[self.nameColumnIndex] != currentName or row[
                    self.modifiersColumnIndex] != currentMod:
                currentName = row[self.nameColumnIndex]
                currentMod = row[self.modifiersColumnIndex]
                if tempArray != []:
                    detail = self._parseArrayIntoDetail(tempArray)
                    tempArray = []
                    if not detail:
                        continue
                    details.append(detail)
            tempArray.append(row)
        return details

    def _parseArrayIntoDetail(self, data):
        """
        This function goes through rows to parse everything that belongs to a single Detail,
        then returns the data inside a Detail object.
        """
        # TODO: Clean this up to separate functions.
        # collect Input column.
        inputList = []
        for line in data:
            inputList.append(line[2])
        # collect everything from the phases. Data won't be ordered.
        phasesList = {}
        notesList = {}
        for line in data:
            cellNum = 2
            counter = -1
            for cell in line:
                counter = counter + 1
                cellNum = cellNum + 1
                # stops the loop and gathers notes-related data once the phases end.
                if cellNum == self.notesIndex1:
                    notesList[line[2]] = [
                        line[self.notesIndex1], line[self.notesIndex2],
                        line[self.notesIndex3]
                    ]
                    break
                # ensures the data is taken from the first column of a phase.
                if counter == 3:
                    counter = 0
                # takes data from the three cells of a single phase and places them in a list inside the dict.
                if counter == 0:
                    if line[2] not in phasesList:
                        phasesList[line[2]] = []
                    phasesList[line[2]].append(
                        Result(line[cellNum], line[cellNum + 1],
                               line[cellNum + 2]))
        modifiers = self._parseModifiers(data[0][self.modifiersColumnIndex])
        action = self.masterSheet.findAction(self.viewName,
                                             data[0][self.nameColumnIndex])
        # If Action instance was not found then user must have removed it.
        if not action:
            return None
        detail = Detail(action, modifiers)
        detail.inputs = inputList
        detail.phases = phasesList
        detail.notes = notesList
        return detail

    def _parseModifiers(self, modifierCell):
        """
        Parse string of modifier names to list of Modifier instances.
        For example 'WPN1 WPN2' will be two Modifier instances.
        """
        modifiers = []
        pattern = re.compile(r'\b\w+\b')
        for name in re.findall(pattern, modifierCell):
            modifiers.append(Modifier(name))
        return modifiers