diff --git a/aqt/addons.py b/aqt/addons.py index e345a7b8b..30d91ae0b 100644 --- a/aqt/addons.py +++ b/aqt/addons.py @@ -5,7 +5,8 @@ import sys, os, re, traceback, time from cStringIO import StringIO from aqt.qt import * -from aqt.utils import showInfo, showWarning, openFolder, isWin, openLink +from aqt.utils import showInfo, showWarning, openFolder, isWin, openLink, \ + askUser from anki.hooks import runHook, addHook, remHook from aqt.webview import AnkiWebView from zipfile import ZipFile @@ -14,6 +15,9 @@ import aqt from anki.sync import httpCon import aqt.sync # monkey-patches httplib2 +# in the future, it would be nice to save the addon id and unzippped file list +# to the config so that we can clear up all files and check for updates + class AddonManager(object): def __init__(self, mw): @@ -21,6 +25,7 @@ class AddonManager(object): f = self.mw.form; s = SIGNAL("triggered()") self.mw.connect(f.actionOpenPluginFolder, s, self.onOpenAddonFolder) self.mw.connect(f.actionDownloadSharedPlugin, s, self.onGetAddons) + self._menus = [] if isWin: self.clearAddonCache() sys.path.insert(0, self.addonsFolder()) @@ -36,6 +41,7 @@ class AddonManager(object): __import__(file.replace(".py", "")) except: traceback.print_exc() + self.rebuildAddonsMenu() # Menus ###################################################################### @@ -45,6 +51,44 @@ class AddonManager(object): path = self.addonsFolder() openFolder(path) + def rebuildAddonsMenu(self): + for m in self._menus: + self.mw.form.menuPlugins.removeAction(m.menuAction()) + for file in self.files(): + m = self.mw.form.menuPlugins.addMenu( + os.path.splitext(file)[0]) + self._menus.append(m) + a = QAction(_("Edit..."), self.mw) + p = os.path.join(self.addonsFolder(), file) + self.mw.connect(a, SIGNAL("triggered()"), + lambda p=p: self.onEdit(p)) + m.addAction(a) + a = QAction(_("Delete..."), self.mw) + self.mw.connect(a, SIGNAL("triggered()"), + lambda p=p: self.onRem(p)) + m.addAction(a) + + def onEdit(self, path): + d = QDialog(self.mw) + frm = aqt.forms.editaddon.Ui_Dialog() + frm.setupUi(d) + d.setWindowTitle(os.path.basename(path)) + frm.text.setPlainText(open(path).read()) + d.connect(frm.buttonBox, SIGNAL("accepted()"), + lambda: self.onAcceptEdit(path, frm)) + d.exec_() + + def onAcceptEdit(self, path, frm): + open(path, "w").write(frm.text.toPlainText()) + showInfo(_("Edits saved. Please restart Anki.")) + + def onRem(self, path): + if not askUser(_("Delete %s?") % os.path.basename(path)): + return + os.unlink(path) + self.rebuildAddonsMenu() + showInfo(_("Deleted. Please restart Anki.")) + # Tools ###################################################################### diff --git a/designer/editaddon.ui b/designer/editaddon.ui new file mode 100644 index 000000000..86075166d --- /dev/null +++ b/designer/editaddon.ui @@ -0,0 +1,67 @@ + + + Dialog + + + + 0 + 0 + 606 + 473 + + + + Dialog + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Save + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/designer/main.ui b/designer/main.ui index 4971784e2..d8bbf7dcb 100644 --- a/designer/main.ui +++ b/designer/main.ui @@ -89,6 +89,7 @@ +