Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions music21/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1290,6 +1290,27 @@ def _askFillEmptyList(self, default=None, force=None):
break

return post

def _getMuseScorePNGPathFromApp(self, musicxmlPath: str) -> str:
'''
Given the path to a MuseScore application bundle (macOS) or executable,
return the path suitable for headless PNG generation
(`musescoreDirectPNGPath`).
'''
platform = common.getPlatform()
if platform == 'darwin' and musicxmlPath.endswith('.app'):
possible_names = ['mscore', 'MuseScore', 'MuseScore4', 'MuseScore3']
for name in possible_names:
exe = os.path.join(musicxmlPath, 'Contents', 'MacOS', name)
if os.path.isfile(exe):
return exe
# If nothing matches, fall back to the app path itself (best effort).
environLocal.printDebug(
f'Could not find MuseScore executable inside {musicxmlPath}; '
f'using app bundle path as fallback.')
return musicxmlPath
# On Windows the discovered path is already the .exe, on Linux it's the executable.
return musicxmlPath

def _performAction(self, simulate=False):
'''
Expand All @@ -1304,6 +1325,16 @@ def _performAction(self, simulate=False):
environment.set('musicxmlPath', result)
musicXmlNew = environment.get('musicxmlPath')
self._writeToUser([f'MusicXML Reader set to: {musicXmlNew}', ' '])
# If the chosen reader is MuseScore, also set the PNG generation path
# to avoid stale/broken values.
if 'MuseScore' in result:
pngPath = self._getMuseScorePNGPathFromApp(result)
environment.set('musescoreDirectPNGPath', pngPath)
pngPathCheck = environment.get('musescoreDirectPNGPath')
self._writeToUser([
f'MuseScore PNG generator set to: {pngPathCheck}',
' '
])


# ------------------------------------------------------------------------------
Expand Down
Loading