This repository has been archived on 2020-08-22. You can view files and clone it, but cannot push or open issues or pull requests.
pyaudviz/src/gui/presetmanager.py

362 lines
13 KiB
Python
Raw Normal View History

'''
Preset manager object handles all interactions with presets, including
the context menu accessed from MainWindow.
'''
2017-06-23 23:00:24 -04:00
from PyQt5 import QtCore, QtWidgets
import string
import os
import logging
from toolkit import badName
from core import Core
from gui.actions import *
log = logging.getLogger('AVP.Gui.PresetManager')
2017-06-23 18:38:05 -04:00
class PresetManager(QtWidgets.QDialog):
def __init__(self, window, parent):
super().__init__(parent.window)
self.parent = parent
2017-06-08 22:56:33 -04:00
self.core = parent.core
self.settings = parent.settings
self.presetDir = parent.presetDir
if not self.settings.value('presetDir'):
self.settings.setValue(
"presetDir",
os.path.join(parent.dataDir, 'projects'))
self.findPresets()
# window
self.lastFilter = '*'
2017-06-23 23:00:24 -04:00
self.presetRows = [] # list of (comp, vers, name) tuples
self.window = window
self.window.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
# connect button signals
2017-06-23 23:00:24 -04:00
self.window.pushButton_delete.clicked.connect(
2017-06-23 17:14:39 -04:00
self.openDeletePresetDialog
)
2017-06-23 23:00:24 -04:00
self.window.pushButton_rename.clicked.connect(
2017-06-23 17:14:39 -04:00
self.openRenamePresetDialog
)
self.window.pushButton_import.clicked.connect(
self.openImportDialog
)
self.window.pushButton_export.clicked.connect(
self.openExportDialog
)
self.window.pushButton_close.clicked.connect(
self.window.close
)
# create filter box and preset list
self.drawFilterList()
self.window.comboBox_filter.currentIndexChanged.connect(
lambda: self.drawPresetList(
2017-06-23 23:00:24 -04:00
self.window.comboBox_filter.currentText(),
self.window.lineEdit_search.text()
)
)
# make auto-completion for search bar
2017-06-23 18:38:05 -04:00
self.autocomplete = QtCore.QStringListModel()
completer = QtWidgets.QCompleter()
completer.setModel(self.autocomplete)
self.window.lineEdit_search.setCompleter(completer)
self.window.lineEdit_search.textChanged.connect(
lambda: self.drawPresetList(
2017-06-23 23:00:24 -04:00
self.window.comboBox_filter.currentText(),
self.window.lineEdit_search.text()
)
)
self.drawPresetList('*')
def show(self):
'''Open a new preset manager window from the mainwindow'''
self.findPresets()
self.drawFilterList()
self.drawPresetList('*')
self.window.show()
def findPresets(self):
parseList = []
for dirpath, dirnames, filenames in os.walk(self.presetDir):
# anything without a subdirectory must be a preset folder
if dirnames:
continue
for preset in filenames:
compName = os.path.basename(os.path.dirname(dirpath))
if compName not in self.core.compNames:
continue
compVers = os.path.basename(dirpath)
try:
parseList.append((compName, int(compVers), preset))
except ValueError:
continue
2017-06-23 23:00:24 -04:00
self.presets = {
compName: [
(vers, preset)
for name, vers, preset in parseList
if name == compName
]
for compName, _, __ in parseList
}
def drawPresetList(self, compFilter=None, presetFilter=''):
self.window.listWidget_presets.clear()
if compFilter:
self.lastFilter = str(compFilter)
else:
compFilter = str(self.lastFilter)
self.presetRows = []
presetNames = []
for component, presets in self.presets.items():
if compFilter != '*' and component != compFilter:
continue
for vers, preset in presets:
if not presetFilter or presetFilter in preset:
2017-06-23 23:00:24 -04:00
self.window.listWidget_presets.addItem(
2017-06-23 17:14:39 -04:00
'%s: %s' % (component, preset)
)
self.presetRows.append((component, vers, preset))
if preset not in presetNames:
presetNames.append(preset)
self.autocomplete.setStringList(presetNames)
def drawFilterList(self):
self.window.comboBox_filter.clear()
self.window.comboBox_filter.addItem('*')
for component in self.presets:
self.window.comboBox_filter.addItem(component)
def clearPreset(self, compI=None):
'''Functions on mainwindow level from the context menu'''
compI = self.parent.window.listWidget_componentList.currentRow()
action = ClearPreset(self.parent, compI)
self.parent.undoStack.push(action)
def openSavePresetDialog(self):
'''Functions on mainwindow level from the context menu'''
window = self.parent.window
selectedComponents = self.core.selectedComponents
componentList = self.parent.window.listWidget_componentList
if componentList.currentRow() == -1:
return
while True:
index = componentList.currentRow()
currentPreset = selectedComponents[index].currentPreset
2017-06-23 23:00:24 -04:00
newName, OK = QtWidgets.QInputDialog.getText(
self.parent.window,
'Audio Visualizer',
'New Preset Name:',
2017-06-23 23:00:24 -04:00
QtWidgets.QLineEdit.Normal,
currentPreset
)
if OK:
if badName(newName):
self.warnMessage(self.parent.window)
continue
if newName:
if index != -1:
selectedComponents[index].currentPreset = newName
saveValueStore = \
selectedComponents[index].savePreset()
saveValueStore['preset'] = newName
componentName = str(selectedComponents[index]).strip()
vers = selectedComponents[index].version
self.createNewPreset(
componentName, vers, newName,
saveValueStore, window=self.parent.window)
self.findPresets()
self.drawPresetList()
self.openPreset(newName, index)
break
def createNewPreset(
2017-06-23 23:00:24 -04:00
self, compName, vers, filename, saveValueStore, **kwargs):
path = os.path.join(self.presetDir, compName, str(vers), filename)
if self.presetExists(path, **kwargs):
return
self.core.createPresetFile(compName, vers, filename, saveValueStore)
def presetExists(self, path, **kwargs):
if os.path.exists(path):
window = self.window \
if 'window' not in kwargs else kwargs['window']
ch = self.parent.showMessage(
msg="%s already exists! Overwrite it?" %
os.path.basename(path),
showCancel=True,
icon='Warning',
parent=window)
if not ch:
# user clicked cancel
return True
return False
def openPreset(self, presetName, compPos=None):
componentList = self.parent.window.listWidget_componentList
index = compPos if compPos is not None else componentList.currentRow()
if index == -1:
return
action = OpenPreset(self, presetName, index)
self.parent.undoStack.push(action)
def _openPreset(self, presetName, index):
selectedComponents = self.core.selectedComponents
2017-08-19 20:45:44 -04:00
componentName = selectedComponents[index].name.strip()
version = selectedComponents[index].version
dirname = os.path.join(self.presetDir, componentName, str(version))
filepath = os.path.join(dirname, presetName)
self.core.openPreset(filepath, index, presetName)
self.parent.updateComponentTitle(index)
self.parent.drawPreview()
def openDeletePresetDialog(self):
row = self.getPresetRow()
if row == -1:
return
comp, vers, name = self.presetRows[row]
ch = self.parent.showMessage(
msg='Really delete %s?' % name,
showCancel=True,
icon='Warning',
parent=self.window
)
if not ch:
return
self.deletePreset(comp, vers, name)
def deletePreset(self, comp, vers, name):
action = DeletePreset(self, comp, vers, name)
self.parent.undoStack.push(action)
def warnMessage(self, window=None):
self.parent.showMessage(
msg='Preset names must contain only letters, '
'numbers, and spaces.',
parent=window if window else self.window)
def getPresetRow(self):
row = self.window.listWidget_presets.currentRow()
if row > -1:
return row
# check if component selected in MainWindow has preset loaded
componentList = self.parent.window.listWidget_componentList
compIndex = componentList.currentRow()
if compIndex == -1:
return compIndex
preset = self.core.selectedComponents[compIndex].currentPreset
if preset is None:
return -1
else:
rowTuple = (
self.core.selectedComponents[compIndex].name,
self.core.selectedComponents[compIndex].version,
preset
)
for i, tup in enumerate(self.presetRows):
if rowTuple == tup:
index = i
break
else:
return -1
return index
def openRenamePresetDialog(self):
presetList = self.window.listWidget_presets
index = self.getPresetRow()
if index == -1:
return
while True:
2017-06-23 23:00:24 -04:00
newName, OK = QtWidgets.QInputDialog.getText(
self.window,
'Preset Manager',
'Rename Preset:',
2017-06-23 23:00:24 -04:00
QtWidgets.QLineEdit.Normal,
self.presetRows[index][2]
)
if OK:
if badName(newName):
self.warnMessage()
continue
if newName:
comp, vers, oldName = self.presetRows[index]
path = os.path.join(
self.presetDir, comp, str(vers))
newPath = os.path.join(path, newName)
if self.presetExists(newPath):
return
action = RenamePreset(self, path, oldName, newName)
self.parent.undoStack.push(action)
break
2017-06-08 22:56:33 -04:00
def renamePreset(self, path, oldName, newName):
oldPath = os.path.join(path, oldName)
newPath = os.path.join(path, newName)
if os.path.exists(newPath):
os.remove(newPath)
os.rename(oldPath, newPath)
self.findPresets()
self.drawPresetList()
path = os.path.dirname(newPath)
for i, comp in enumerate(self.core.selectedComponents):
if self.core.getPresetDir(comp) == path \
and comp.currentPreset == oldName:
self.core.openPreset(newPath, i, newName)
self.parent.updateComponentTitle(i, False)
self.parent.drawPreview()
2017-06-08 22:56:33 -04:00
def openImportDialog(self):
2017-06-23 23:00:24 -04:00
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
2017-06-08 22:56:33 -04:00
self.window, "Import Preset File",
self.settings.value("presetDir"),
2017-06-08 22:56:33 -04:00
"Preset Files (*.avl)")
if filename:
# get installed path & ask user to overwrite if needed
path = ''
while True:
if path:
if self.presetExists(path):
break
else:
if os.path.exists(path):
os.remove(path)
success, path = self.core.importPreset(filename)
if success:
break
self.findPresets()
self.drawPresetList()
self.settings.setValue("presetDir", os.path.dirname(filename))
2017-06-08 22:56:33 -04:00
def openExportDialog(self):
index = self.getPresetRow()
if index == -1:
return
2017-06-23 23:00:24 -04:00
filename, _ = QtWidgets.QFileDialog.getSaveFileName(
2017-06-08 22:56:33 -04:00
self.window, "Export Preset",
self.settings.value("presetDir"),
2017-06-08 22:56:33 -04:00
"Preset Files (*.avl)")
if filename:
comp, vers, name = self.presetRows[index]
if not self.core.exportPreset(filename, comp, vers, name):
self.parent.showMessage(
msg='Couldn\'t export %s.' % filename,
parent=self.window
)
self.settings.setValue("presetDir", os.path.dirname(filename))
def clearPresetListSelection(self):
self.window.listWidget_presets.setCurrentRow(-1)