diff --git a/doc/help_dialogs/Input_files/eventbuttons.xlsx b/doc/help_dialogs/Input_files/eventbuttons.xlsx index 05307d86f..19f88f30e 100644 Binary files a/doc/help_dialogs/Input_files/eventbuttons.xlsx and b/doc/help_dialogs/Input_files/eventbuttons.xlsx differ diff --git a/doc/help_dialogs/Input_files/eventsliders.xlsx b/doc/help_dialogs/Input_files/eventsliders.xlsx index f0ef774a1..334dee142 100644 Binary files a/doc/help_dialogs/Input_files/eventsliders.xlsx and b/doc/help_dialogs/Input_files/eventsliders.xlsx differ diff --git a/doc/help_dialogs/Output_html/eventbuttons_help.html b/doc/help_dialogs/Output_html/eventbuttons_help.html index b71352e8b..50180424f 100644 --- a/doc/help_dialogs/Output_html/eventbuttons_help.html +++ b/doc/help_dialogs/Output_html/eventbuttons_help.html @@ -827,6 +827,16 @@ playbackmode(<int>) sets playback mode to 0: off, 1: time, 2: BT, 3: ET + +   + quantifier(n,<bool>) + activate/deactivate quantification per event type n from {1,2,3,4} + + +   + setBatchSize(<float>) + set the batch size to the given value. If the value is negative, the batch size is taken from the background profile, if any is loaded +   openProperties diff --git a/doc/help_dialogs/Output_html/eventsliders_help.html b/doc/help_dialogs/Output_html/eventsliders_help.html index ababec56f..1d0855f2e 100644 --- a/doc/help_dialogs/Output_html/eventsliders_help.html +++ b/doc/help_dialogs/Output_html/eventsliders_help.html @@ -557,6 +557,16 @@ playbackmode(<int>) sets playback mode to 0: off, 1: time, 2: BT, 3: ET + +   + quantifier(n,<bool>) + activate/deactivate quantification per event type n from {1,2,3,4} + + +   + setBatchSize(<float>) + set the batch size to the given value. If the value is negative, the batch size is taken from the background profile, if any is loaded +   openProperties diff --git a/src/artisanlib/background.py b/src/artisanlib/background.py index 0bdac5faa..987b38581 100644 --- a/src/artisanlib/background.py +++ b/src/artisanlib/background.py @@ -222,11 +222,18 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', activeTab:int = 0) -> self.etimeSpinBox.setValue(int(self.aw.qmc.detectBackgroundEventTime)) self.etimeSpinBox.valueChanged.connect(self.setreproduce) self.etimeSpinBox.setEnabled(self.aw.qmc.backgroundReproduce) - self.clearBgbeforeprofileload = QCheckBox(QApplication.translate('CheckBox','Clear the background before loading a new profile')) + self.clearBgbeforeprofileload = QCheckBox(QApplication.translate('CheckBox','Clear background before loading')) + self.clearBgbeforeprofileload.setToolTip(QApplication.translate('Tooltip', 'Clear background before loading a profile')) self.clearBgbeforeprofileload.setChecked(self.aw.qmc.clearBgbeforeprofileload) self.clearBgbeforeprofileload.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.clearBgbeforeprofileload.stateChanged.connect(self.optclearbgbeforeprofileload) - self.hideBgafterprofileload = QCheckBox(QApplication.translate('CheckBox','Always hide background when loading a profile')) + self.setBatchSizeFromBackground = QCheckBox(QApplication.translate('CheckBox','Set batch size')) + self.setBatchSizeFromBackground.setToolTip(QApplication.translate('Tooltip', 'Set batch size from background profile on load')) + self.setBatchSizeFromBackground.setChecked(self.aw.qmc.setBatchSizeFromBackground) + self.setBatchSizeFromBackground.setFocusPolicy(Qt.FocusPolicy.NoFocus) + self.setBatchSizeFromBackground.stateChanged.connect(self.optsetBatchSizeFromBackground) + self.hideBgafterprofileload = QCheckBox(QApplication.translate('CheckBox','Always hide background on loading')) + self.hideBgafterprofileload.setToolTip(QApplication.translate('Tooltip', 'Always hide background on loading a profile')) self.hideBgafterprofileload.setChecked(self.aw.qmc.hideBgafterprofileload) self.hideBgafterprofileload.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.hideBgafterprofileload.stateChanged.connect(self.opthideBgafterprofileload) @@ -284,37 +291,37 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', activeTab:int = 0) -> alignButtonBoxed.addWidget(alignButton) alignButtonBoxed.addWidget(self.alignComboBox) - self.backgroundPlaybackAid0Label = QLabel('1') - self.backgroundPlaybackAid0Label.setEnabled(self.aw.qmc.backgroundReproduce) +# self.backgroundPlaybackAid0Label = QLabel('1') +# self.backgroundPlaybackAid0Label.setEnabled(self.aw.qmc.backgroundReproduce) self.backgroundPlaybackAid0 = QCheckBox(self.aw.qmc.etypesf(0)) self.backgroundPlaybackAid0.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.backgroundPlaybackAid0.setChecked(self.aw.qmc.specialeventplaybackaid[0]) self.backgroundPlaybackAid0.stateChanged.connect(self.setplaybackaideventtypeenabled) self.backgroundPlaybackAid0.setEnabled(self.aw.qmc.backgroundReproduce) +# self.backgroundPlaybackAid1Label = QLabel('2') +# self.backgroundPlaybackAid1Label.setEnabled(self.aw.qmc.backgroundReproduce) self.backgroundPlaybackAid1 = QCheckBox(self.aw.qmc.etypesf(1)) self.backgroundPlaybackAid1.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.backgroundPlaybackAid1.setChecked(self.aw.qmc.specialeventplaybackaid[1]) self.backgroundPlaybackAid1.stateChanged.connect(self.setplaybackaideventtypeenabled) self.backgroundPlaybackAid1.setEnabled(self.aw.qmc.backgroundReproduce) - self.backgroundPlaybackAid1Label = QLabel('2') - self.backgroundPlaybackAid1Label.setEnabled(self.aw.qmc.backgroundReproduce) +# self.backgroundPlaybackAid2Label = QLabel('3') +# self.backgroundPlaybackAid2Label.setEnabled(self.aw.qmc.backgroundReproduce) self.backgroundPlaybackAid2 = QCheckBox(self.aw.qmc.etypesf(2)) self.backgroundPlaybackAid2.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.backgroundPlaybackAid2.setChecked(self.aw.qmc.specialeventplaybackaid[2]) self.backgroundPlaybackAid2.stateChanged.connect(self.setplaybackaideventtypeenabled) self.backgroundPlaybackAid2.setEnabled(self.aw.qmc.backgroundReproduce) - self.backgroundPlaybackAid2Label = QLabel('3') - self.backgroundPlaybackAid2Label.setEnabled(self.aw.qmc.backgroundReproduce) +# self.backgroundPlaybackAid3Label = QLabel('4') +# self.backgroundPlaybackAid3Label.setEnabled(self.aw.qmc.backgroundReproduce) self.backgroundPlaybackAid3 = QCheckBox(self.aw.qmc.etypesf(3)) self.backgroundPlaybackAid3.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.backgroundPlaybackAid3.setChecked(self.aw.qmc.specialeventplaybackaid[3]) self.backgroundPlaybackAid3.stateChanged.connect(self.setplaybackaideventtypeenabled) self.backgroundPlaybackAid3.setEnabled(self.aw.qmc.backgroundReproduce) - self.backgroundPlaybackAid3Label = QLabel('4') - self.backgroundPlaybackAid3Label.setEnabled(self.aw.qmc.backgroundReproduce) tab4content1 = QHBoxLayout() tab4content1.addWidget(self.backgroundReproduce) @@ -326,44 +333,44 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', activeTab:int = 0) -> tab4content1.addWidget(self.etimeunit) tab4content1.addSpacing(20) tab4content1.addStretch() - tab4content1.addWidget(self.backgroundPlaybackAid0Label) +# tab4content1.addWidget(self.backgroundPlaybackAid0Label) tab4content1.addWidget(self.backgroundPlaybackAid0) tab4content1.addSpacing(10) - tab4content1.addWidget(self.backgroundPlaybackAid1Label) +# tab4content1.addWidget(self.backgroundPlaybackAid1Label) tab4content1.addWidget(self.backgroundPlaybackAid1) tab4content1.addSpacing(10) - tab4content1.addWidget(self.backgroundPlaybackAid2Label) +# tab4content1.addWidget(self.backgroundPlaybackAid2Label) tab4content1.addWidget(self.backgroundPlaybackAid2) tab4content1.addSpacing(10) - tab4content1.addWidget(self.backgroundPlaybackAid3Label) +# tab4content1.addWidget(self.backgroundPlaybackAid3Label) tab4content1.addWidget(self.backgroundPlaybackAid3) - self.backgroundPlaybackEvent0Label = QLabel('1') - self.backgroundPlaybackEvent0Label.setEnabled(self.aw.qmc.backgroundPlaybackEvents) +# self.backgroundPlaybackEvent0Label = QLabel('1') +# self.backgroundPlaybackEvent0Label.setEnabled(self.aw.qmc.backgroundPlaybackEvents) self.backgroundPlaybackEvent0 = QCheckBox(self.aw.qmc.etypesf(0)) self.backgroundPlaybackEvent0.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.backgroundPlaybackEvent0.setChecked(self.aw.qmc.specialeventplayback[0]) self.backgroundPlaybackEvent0.stateChanged.connect(self.setplaybackeventtypeenabled) self.backgroundPlaybackEvent0.setEnabled(self.aw.qmc.backgroundPlaybackEvents) - self.backgroundPlaybackEvent1Label = QLabel('2') - self.backgroundPlaybackEvent1Label.setEnabled(self.aw.qmc.backgroundPlaybackEvents) +# self.backgroundPlaybackEvent1Label = QLabel('2') +# self.backgroundPlaybackEvent1Label.setEnabled(self.aw.qmc.backgroundPlaybackEvents) self.backgroundPlaybackEvent1 = QCheckBox(self.aw.qmc.etypesf(1)) self.backgroundPlaybackEvent1.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.backgroundPlaybackEvent1.setChecked(self.aw.qmc.specialeventplayback[1]) self.backgroundPlaybackEvent1.stateChanged.connect(self.setplaybackeventtypeenabled) self.backgroundPlaybackEvent1.setEnabled(self.aw.qmc.backgroundPlaybackEvents) - self.backgroundPlaybackEvent2Label = QLabel('3') - self.backgroundPlaybackEvent2Label.setEnabled(self.aw.qmc.backgroundPlaybackEvents) +# self.backgroundPlaybackEvent2Label = QLabel('3') +# self.backgroundPlaybackEvent2Label.setEnabled(self.aw.qmc.backgroundPlaybackEvents) self.backgroundPlaybackEvent2 = QCheckBox(self.aw.qmc.etypesf(2)) self.backgroundPlaybackEvent2.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.backgroundPlaybackEvent2.setChecked(self.aw.qmc.specialeventplayback[2]) self.backgroundPlaybackEvent2.stateChanged.connect(self.setplaybackeventtypeenabled) self.backgroundPlaybackEvent2.setEnabled(self.aw.qmc.backgroundPlaybackEvents) - self.backgroundPlaybackEvent3Label = QLabel('4') - self.backgroundPlaybackEvent3Label.setEnabled(self.aw.qmc.backgroundPlaybackEvents) +# self.backgroundPlaybackEvent3Label = QLabel('4') +# self.backgroundPlaybackEvent3Label.setEnabled(self.aw.qmc.backgroundPlaybackEvents) self.backgroundPlaybackEvent3 = QCheckBox(self.aw.qmc.etypesf(3)) self.backgroundPlaybackEvent3.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.backgroundPlaybackEvent3.setChecked(self.aw.qmc.specialeventplayback[3]) @@ -372,34 +379,39 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', activeTab:int = 0) -> tab4content2 = QHBoxLayout() tab4content2.addWidget(self.backgroundPlaybackDROP) - tab4content2.addSpacing(25) + tab4content2.addSpacing(10) tab4content2.addStretch() tab4content2.addWidget(self.backgroundPlaybackEvents) tab4content2.addSpacing(10) tab4content2.addWidget(self.replayComboBox) tab4content2.addSpacing(10) tab4content2.addStretch() - tab4content2.addWidget(self.backgroundPlaybackEvent0Label) +# tab4content2.addWidget(self.backgroundPlaybackEvent0Label) tab4content2.addWidget(self.backgroundPlaybackEvent0) tab4content2.addSpacing(10) - tab4content2.addWidget(self.backgroundPlaybackEvent1Label) +# tab4content2.addWidget(self.backgroundPlaybackEvent1Label) tab4content2.addWidget(self.backgroundPlaybackEvent1) tab4content2.addSpacing(10) - tab4content2.addWidget(self.backgroundPlaybackEvent2Label) +# tab4content2.addWidget(self.backgroundPlaybackEvent2Label) tab4content2.addWidget(self.backgroundPlaybackEvent2) tab4content2.addSpacing(10) - tab4content2.addWidget(self.backgroundPlaybackEvent3Label) +# tab4content2.addWidget(self.backgroundPlaybackEvent3Label) tab4content2.addWidget(self.backgroundPlaybackEvent3) tab4content = QVBoxLayout() tab4content.addLayout(tab4content1) tab4content.addLayout(tab4content2) + tab4content.setSpacing(7) playbackGroupLayout = QGroupBox(QApplication.translate('GroupBox','Playback')) playbackGroupLayout.setLayout(tab4content) optcontent = QHBoxLayout() optcontent.addWidget(self.clearBgbeforeprofileload) + optcontent.addSpacing(5) + optcontent.addStretch() + optcontent.addWidget(self.setBatchSizeFromBackground) + optcontent.addSpacing(5) optcontent.addStretch() optcontent.addWidget(self.hideBgafterprofileload) tab1layout = QVBoxLayout() @@ -531,10 +543,11 @@ def setplaybackevent(self, _:int) -> None: self.backgroundPlaybackEvent1, self.backgroundPlaybackEvent2, self.backgroundPlaybackEvent3, - self.backgroundPlaybackEvent0Label, - self.backgroundPlaybackEvent1Label, - self.backgroundPlaybackEvent2Label, - self.backgroundPlaybackEvent3Label]: +# self.backgroundPlaybackEvent0Label, +# self.backgroundPlaybackEvent1Label, +# self.backgroundPlaybackEvent2Label, +# self.backgroundPlaybackEvent3Label + ]: widget.setEnabled(self.aw.qmc.backgroundPlaybackEvents) @pyqtSlot(int) @@ -591,16 +604,24 @@ def setreproduce(self, _:int) -> None: self.backgroundPlaybackAid1, self.backgroundPlaybackAid2, self.backgroundPlaybackAid3, - self.backgroundPlaybackAid0Label, - self.backgroundPlaybackAid1Label, - self.backgroundPlaybackAid2Label, - self.backgroundPlaybackAid3Label]: +# self.backgroundPlaybackAid0Label, +# self.backgroundPlaybackAid1Label, +# self.backgroundPlaybackAid2Label, +# self.backgroundPlaybackAid3Label + ]: widget.setEnabled(self.aw.qmc.backgroundReproduce) self.backgroundReproduceBeep.setEnabled(self.aw.qmc.backgroundReproduce) self.etimeSpinBox.setEnabled(self.aw.qmc.backgroundReproduce) self.etimelabel.setEnabled(self.aw.qmc.backgroundReproduce) self.etimeunit.setEnabled(self.aw.qmc.backgroundReproduce) + @pyqtSlot(int) + def optsetBatchSizeFromBackground(self, _:int) -> None: + if self.setBatchSizeFromBackground.isChecked(): + self.aw.qmc.setBatchSizeFromBackground = True + else: + self.aw.qmc.setBatchSizeFromBackground = False + @pyqtSlot(int) def optclearbgbeforeprofileload(self, _:int) -> None: if self.clearBgbeforeprofileload.isChecked(): diff --git a/src/artisanlib/canvas.py b/src/artisanlib/canvas.py index 32162cb77..760058af6 100644 --- a/src/artisanlib/canvas.py +++ b/src/artisanlib/canvas.py @@ -243,7 +243,7 @@ class tgraphcanvas(FigureCanvas): 'backgroundReproduce', 'backgroundReproduceBeep', 'backgroundPlaybackEvents', 'backgroundPlaybackDROP', 'Betypes', 'backgroundFlavors', 'flavorbackgroundflag', 'E1backgroundtimex', 'E2backgroundtimex', 'E3backgroundtimex', 'E4backgroundtimex', 'E1backgroundvalues', 'E2backgroundvalues', 'E3backgroundvalues', 'E4backgroundvalues', 'l_backgroundeventtype1dots', 'l_backgroundeventtype2dots', 'l_backgroundeventtype3dots', 'l_backgroundeventtype4dots', - 'DeltaETBflag', 'DeltaBTBflag', 'clearBgbeforeprofileload', 'hideBgafterprofileload', 'heating_types', 'operator', 'organization', 'roastertype', 'roastersize', 'roasterheating', 'drumspeed', + 'DeltaETBflag', 'DeltaBTBflag', 'clearBgbeforeprofileload', 'setBatchSizeFromBackground', 'hideBgafterprofileload', 'heating_types', 'operator', 'organization', 'roastertype', 'roastersize', 'roasterheating', 'drumspeed', 'organization_setup', 'operator_setup', 'roastertype_setup', 'roastersize_setup', 'roastersize_setup_default', 'roasterheating_setup', 'roasterheating_setup_default', 'drumspeed_setup', 'last_batchsize', 'machinesetup_energy_ratings', 'machinesetup', 'roastingnotes', 'cuppingnotes', 'roastdate', 'roastepoch', 'roastepoch_timeout', 'lastroastepoch', 'batchcounter', 'batchsequence', 'batchprefix', 'neverUpdateBatchCounter', 'roastbatchnr', 'roastbatchprefix', 'roastbatchpos', 'roasttzoffset', 'roastUUID', 'scheduleID', 'scheduleDate', 'plus_default_store', 'plus_store', 'plus_store_label', 'plus_coffee', @@ -1414,6 +1414,7 @@ def __init__(self, parent:QWidget, dpi:int, locale:str, aw:'ApplicationWindow') self.DeltaETBflag:bool = False self.DeltaBTBflag:bool = True self.clearBgbeforeprofileload:bool = False + self.setBatchSizeFromBackground:bool = False self.hideBgafterprofileload:bool = False self.heating_types: Final[List[str]] = [ @@ -3297,6 +3298,13 @@ def event_popup_action(self, action:QAction) -> None: self.aw.orderEvents() self.fileDirtySignal.emit() self.redraw_keep_view(recomputeAllDeltas=(action.key[0] in {0, 6})) # type: ignore[attr-defined] # "QAction" has no attribute "key" # on moving CHARGE or DROP, we have to recompute the Deltas + # redraw minieditor event selection line + currentevent = self.aw.eNumberSpinBox.value() + if currentevent: + self.aw.plotEventSelection(currentevent-1) + if not self.flagstart: + self.fig.canvas.draw() + try: dlg.dialogbuttons.accepted.disconnect() dlg.dialogbuttons.rejected.disconnect() @@ -5207,7 +5215,7 @@ def playbackdrop(self) -> None: self.adderror((QApplication.translate('Error Message','Exception:') + ' playbackdrop() {0}').format(str(ex)),getattr(exc_tb, 'tb_lineno', '?')) - # turns playback event on and fills self.replayedBackgroundEvents with already passed events if any + # turns playback event on and fills self.replayedBackgroundEvents with already passed events (w.r.t. time) if any def turn_playback_event_ON(self) -> None: if not self.backgroundPlaybackEvents: # only if playback is freshly turned ON we consider to enable (potentially) already fired background events to be replayed @@ -5223,10 +5231,13 @@ def turn_playback_event_ON(self) -> None: additional_samples = (3 if self.autoChargeFlag else 2) # to catch also background events scheduled for around 00:00 we relax the condition to mark # events before now where time has already passed by 2 (or 3 with autoCHARGE) samples + short_after_CHARGE:bool = False if self.timeindex[0] != -1 and now - start < additional_samples*sample_interval: now -= additional_samples*sample_interval + short_after_CHARGE = True for i, bge in enumerate(self.backgroundEvents): - if (self.timeB[bge] - now) <= 0: + if (self.timeB[bge] - now) <= 0 and not (short_after_CHARGE and self.timeB[bge] < 0): + # switching on short after CHARGE, does not disable background events before CHARGE self.replayedBackgroundEvents.append(i) def turn_playback_event_OFF(self) -> None: @@ -6705,7 +6716,11 @@ def reset(self,redraw:bool = True, soundOn:bool = True, keepProperties:bool = Fa self.restoreEnergyLoadDefaults() self.restoreEnergyProtocolDefaults() # - self.weight = (self.last_batchsize,0,self.weight[2]) + if (self.backgroundprofile is not None and 'weight' in self.backgroundprofile and + self.setBatchSizeFromBackground and self.aw.schedule_window is None): + self.weight = (float(self.backgroundprofile['weight'][0]),0,str(self.backgroundprofile['weight'][2])) + else: + self.weight = (self.last_batchsize,0,self.weight[2]) self.volume = (0,0,self.volume[2]) self.density = (0,self.density[1],1,self.density[3]) # we reset ambient values to the last sampled readings in this session diff --git a/src/artisanlib/events.py b/src/artisanlib/events.py index 887594c23..9fa5e8f30 100644 --- a/src/artisanlib/events.py +++ b/src/artisanlib/events.py @@ -617,7 +617,7 @@ def __init__(self, parent:QWidget, aw:'ApplicationWindow', activeTab:int = 0) -> self.nbuttonsSpinBox = QSpinBox() self.nbuttonsSpinBox.setMaximumWidth(100) self.nbuttonsSpinBox.setAlignment(Qt.AlignmentFlag.AlignCenter) - self.nbuttonsSpinBox.setRange(2,30) + self.nbuttonsSpinBox.setRange(2,50) self.nbuttonsSpinBox.setValue(int(self.aw.buttonlistmaxlen)) self.nbuttonsSpinBox.valueChanged.connect(self.setbuttonlistmaxlen) nbuttonsSizeLabel = QLabel(QApplication.translate('Label','Button Size')) @@ -2978,7 +2978,7 @@ def insertextraeventbuttonSlot(self, _:bool = False) -> None: self.insertextraeventbutton(True) def insertextraeventbutton(self, insert:bool = False) -> None: - if len(self.extraeventstypes) >= self.aw.buttonlistmaxlen * 4: # max 4 rows of buttons of buttonlistmaxlen + if len(self.extraeventstypes) >= self.aw.buttonlistmaxlen * 10: # max 10 rows of buttons of buttonlistmaxlen return try: focusWidget = QApplication.focusWidget() diff --git a/src/artisanlib/main.py b/src/artisanlib/main.py index 5f2826cd5..b99c10280 100644 --- a/src/artisanlib/main.py +++ b/src/artisanlib/main.py @@ -1618,7 +1618,7 @@ def __init__(self, parent:Optional[QWidget] = None, *, locale:str, WebEngineSupp self.segmentresultsanno:Optional[Annotation] = None # Schedule - self.schedule_window:Optional[plus.schedule.ScheduleWindow] = None + self.schedule_window:Optional[plus.schedule.ScheduleWindow] = None # None if scheduler is not active # the uuids of the scheduled items in local custom order on last closing the scheduler # persistet along the app settings self.scheduled_items_uuids:List[str] = [] @@ -5232,13 +5232,6 @@ def newRecentRoast(self, _checked:bool = False) -> None: background_UUID = rr.get('roastUUID', None) self.qmc.resetlinecountcaches() self.loadAndRedrawBackgroundUUID(rr['background'],background_UUID) -# if self.loadbackgroundUUID(rr['background'],background_UUID): -# try: -# self.qmc.background = not self.qmc.hideBgafterprofileload -# self.qmc.timealign(redraw=False) -# self.qmc.redraw() -# except Exception as e: # pylint: disable=broad-except -# _log.exception(e) if alt_modifier: if self.qmc.flagon: self.setRecentRoast(rr) @@ -6353,12 +6346,38 @@ def lastEventValue(self, tp:int) -> Optional[float]: pass return res_last + def orderBackgroundEvents(self) -> None: + nevents = len(self.qmc.backgroundEvents) + packed_events = [] + # pack + for i in range(nevents): + packed_events.append( + (self.qmc.backgroundEvents[i], + self.qmc.backgroundEtypes[i], + self.qmc.backgroundEStrings[i], + self.qmc.backgroundEvalues[i])) + # sort + packed_events.sort(key=lambda tup: tup[0]) + # unpack + for i in range(nevents): + self.qmc.backgroundEvents[i] = packed_events[i][0] + self.qmc.backgroundEtypes[i] = packed_events[i][1] + self.qmc.backgroundEStrings[i] = packed_events[i][2] + self.qmc.backgroundEvalues[i] = packed_events[i][3] + + # order event table by time - def orderEvents(self, lock:bool = True) -> None: + # if force_update is not set, the data structures are only update and the minieditor is only cleared if the order changed + # returns True if order changed or force_update=True, False otherwise + def orderEvents(self, lock:bool = True, force_update:bool = True) -> bool: try: #### lock shared resources ##### if lock: self.qmc.profileDataSemaphore.acquire(1) + + # we remember the current event number selected in the minieditor to re-estabish it after a potentiall reordering + currentevent = self.eNumberSpinBox.value() + nevents = len(self.qmc.specialevents) packed_events = [] # pack @@ -6368,20 +6387,43 @@ def orderEvents(self, lock:bool = True) -> None: self.qmc.specialeventstype[i], self.qmc.specialeventsStrings[i], self.qmc.specialeventsvalue[i])) + + currentevent_tuple:Optional[Tuple[int,int,str,float]] = (packed_events[currentevent-1] if currentevent != 0 and len(packed_events)>currentevent-1 else None) + # sort - packed_events.sort(key=lambda tup: tup[0]) - # unpack - for i in range(nevents): - self.qmc.setEvent(i, - packed_events[i][0], - packed_events[i][1], - packed_events[i][2], - packed_events[i][3]) - # we have to clear the event flag positions as those are now out of order - self.qmc.l_event_flags_dict = {} - self.qmc.l_event_flags_pos_dict = {} - # update minievent editor - self.changeEventNumber(0) + packed_events_sorted = sorted(packed_events, key=lambda tup: tup[0]) + + # check if order changed + same_order = [(e[0] if len(e)>0 else 0) for e in packed_events] == [(e[0] if len(e)>0 else 0) for e in packed_events_sorted] + + if force_update or not same_order: + # in case the order did not change and we are not forced to update, everything can stay the same, + # otherwise we update the custom events and clear the minievent editor + + # unpack + for i in range(nevents): + self.qmc.setEvent(i, + packed_events_sorted[i][0], + packed_events_sorted[i][1], + packed_events_sorted[i][2], + packed_events_sorted[i][3]) + # we have to clear the event flag positions as those are now out of order + self.qmc.l_event_flags_dict = {} + self.qmc.l_event_flags_pos_dict = {} + # update minievent editor + if currentevent_tuple is not None: + try: + new_pos = packed_events_sorted.index(currentevent_tuple) + self.eNumberSpinBox.setValue(new_pos + 1) + except Exception: + # if tuple is not found we also reset the minieditor + self.eNumberSpinBox.setValue(0) + else: + # we reset the minievent editor to 0, the empty event + self.eNumberSpinBox.setValue(0) + self.changeEventNumber(0) + return True + return False finally: if lock and self.qmc.profileDataSemaphore.available() < 1: self.qmc.profileDataSemaphore.release(1) @@ -9694,6 +9736,31 @@ def eventaction_internal(self, action:int, cmd:str, eventtype:Optional[int]) -> self.sendmessage(f'Artisan Command: {cs}') except Exception as e: # pylint: disable=broad-except _log.exception(e) + # quantifier(, ) with from {1,2,3,4} selecting one of the four event types + elif cs.startswith('quantifier(') and cs.endswith(')'): + try: + args = cs[len('quantifier('):-1].split(',') + if len(args) == 2: + event_type = int(args[0]) + state = toBool(eval(args[1])) # pylint: disable=eval-used + if 0 < event_type < 5: + self.eventquantifieractive[event_type - 1] = int(state) + except Exception as e: # pylint: disable=broad-except + _log.exception(e) + # setBatchSize() : if is negative, the batchsize of the background profile is used if any + elif cs.startswith('setBatchSize') and cs.endswith(')'): # in seconds + try: + cmds = eval(cs[len('setBatchSize'):]) # pylint: disable=eval-used + if isinstance(cmds,(float,int)): + # cmd has format "setBatchSize(xx.yy)" + if cmds < 0: + # set batch size from background profile if any is loaded + if self.qmc.backgroundprofile is not None and 'weight' in self.qmc.backgroundprofile: + self.qmc.weight = (float(self.qmc.backgroundprofile['weight'][0]),self.qmc.weight[1],str(self.qmc.backgroundprofile['weight'][2])) + else: + self.qmc.weight = (cmds,self.qmc.weight[1],self.qmc.weight[2]) + except Exception as e: # pylint: disable=broad-except + _log.exception(e) ## visible(,) : sets the visibility of