number of ui changes (see full log)

- use default theme on linux
- add active tag browser
- allow custom toolbar icon sizes
- add plugins menu (enable/disable/etc)
- force plastique for progress bars
This commit is contained in:
Damien Elmes 2008-10-12 00:21:54 +09:00
parent b6e3f8386e
commit d17098b8ce
11 changed files with 370 additions and 67 deletions

View file

@ -40,7 +40,7 @@ def run():
pass
app = QApplication(sys.argv)
if not sys.platform.startswith("darwin"):
if sys.platform.startswith("win32"):
app.setStyle("plastique")
# setup paths for forms, icons

View file

@ -28,6 +28,7 @@ class Config(dict):
def defaults(self):
fields = {
'iconSize': 32,
'syncOnLoad': False,
'syncOnClose': False,
'checkForUpdates': True,

View file

@ -25,6 +25,7 @@ def importAll():
import facteditor
import tagedit
import tray
import activetags
class DialogManager(object):

59
ankiqt/ui/activetags.py Normal file
View file

@ -0,0 +1,59 @@
# Copyright: Damien Elmes <anki@ichi2.net>
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import ankiqt
from anki.utils import parseTags, joinTags
class ActiveTagsChooser(QDialog):
def __init__(self, parent):
QDialog.__init__(self, parent)
self.parent = parent
self.dialog = ankiqt.forms.activetags.Ui_Dialog()
self.dialog.setupUi(self)
self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"),
self.onHelp)
self.rebuildTagList()
def rebuildTagList(self):
self.tags = self.parent.deck.allTags()
self.tags.sort()
self.items = []
self.suspended = {}
for t in parseTags(self.parent.deck.suspended):
self.suspended[t] = 1
for t in self.tags:
item = QListWidgetItem(t, self.dialog.list)
self.dialog.list.addItem(item)
self.items.append(item)
idx = self.dialog.list.indexFromItem(item)
if t in self.suspended:
mode = QItemSelectionModel.Deselect
else:
mode = QItemSelectionModel.Select
self.dialog.list.selectionModel().select(idx, mode)
def accept(self):
n = 0
suspended = []
for item in self.items:
idx = self.dialog.list.indexFromItem(item)
if not self.dialog.list.selectionModel().isSelected(idx):
suspended.append(self.tags[n])
n += 1
self.parent.deck.suspended = joinTags(suspended + ["Suspended"])
self.parent.deck.setModified()
self.parent.reset()
QDialog.accept(self)
def onHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki +
"ActiveTags"))
def show(parent):
at = ActiveTagsChooser(parent)
at.exec_()

View file

@ -8,7 +8,7 @@ from PyQt4.QtCore import *
# fixme: sample files read only, need to copy
import os, sys, re, types, gettext, stat, traceback
import copy, shutil, time
import copy, shutil, time, glob
from PyQt4.QtCore import *
from PyQt4.QtGui import *
@ -39,9 +39,10 @@ class AnkiQt(QMainWindow):
self.setupFonts()
self.setupBackupDir()
self.setupHooks()
self.loadUserCustomisations()
self.loadPlugins()
self.mainWin = ankiqt.forms.main.Ui_MainWindow()
self.mainWin.setupUi(self)
self.rebuildPluginsMenu()
self.alterShortcuts()
self.help = ui.help.HelpArea(self.mainWin.helpFrame, self.config, self)
self.trayIcon = ui.tray.AnkiTrayIcon( self )
@ -72,8 +73,8 @@ class AnkiQt(QMainWindow):
try:
self.runHook('init')
except:
print _("Error running initHook. Broken plugin?")
traceback.print_exc()
ui.utils.showWarning(_("Broken plugin:\n\n%s") %
traceback.format_exc())
# check for updates
self.setupAutoUpdate()
@ -798,13 +799,13 @@ class AnkiQt(QMainWindow):
##########################################################################
def setupToolbar(self):
mw = self.mainWin
if not self.config['showToolbar']:
self.removeToolBar(self.mainWin.toolBar)
self.mainWin.toolBar.hide()
if self.config['simpleToolbar']:
mw = self.mainWin
self.removeToolBar(mw.toolBar)
self.mainWin.toolBar.hide()
mw.toolBar.hide()
if self.config['simpleToolbar']:
self.removeToolBar(mw.toolBar)
mw.toolBar.hide()
mw.toolBar = QToolBar(self)
mw.toolBar.addAction(mw.actionAddcards)
mw.toolBar.addAction(mw.actionEditdeck)
@ -813,6 +814,8 @@ class AnkiQt(QMainWindow):
mw.toolBar.addAction(mw.actionGraphs)
mw.toolBar.addAction(mw.actionDisplayProperties)
self.addToolBar(Qt.TopToolBarArea, mw.toolBar)
mw.toolBar.setIconSize(QSize(self.config['iconSize'],
self.config['iconSize']))
# Tools - looking up words in the dictionary
##########################################################################
@ -979,6 +982,9 @@ class AnkiQt(QMainWindow):
def onAbout(self):
ui.about.show(self)
def onActiveTags(self):
ui.activetags.show(self)
# Importing & exporting
##########################################################################
@ -1223,6 +1229,11 @@ class AnkiQt(QMainWindow):
self.connect(m.actionMergeModels, s, self.onMergeModels)
self.connect(m.actionCheckMediaDatabase, s, self.onCheckMediaDB)
self.connect(m.actionCram, s, self.onCram)
self.connect(m.actionGetPlugins, s, self.onGetPlugins)
self.connect(m.actionOpenPluginFolder, s, self.onOpenPluginFolder)
self.connect(m.actionEnableAllPlugins, s, self.onEnableAllPlugins)
self.connect(m.actionDisableAllPlugins, s, self.onDisableAllPlugins)
self.connect(m.actionActiveTags, s, self.onActiveTags)
def enableDeckMenuItems(self, enabled=True):
"setEnabled deck-related items."
@ -1316,32 +1327,89 @@ class AnkiQt(QMainWindow):
"type": ret }
)
# User customisations
# Plugins
##########################################################################
def loadUserCustomisations(self):
# look for config file
def pluginsFolder(self):
dir = self.config.configPath
file = os.path.join(dir, "custom.py")
plugdir = os.path.join(dir, "plugins")
sys.path.insert(0, dir)
if os.path.exists(file):
try:
import custom
except:
print "Error in custom.py"
print traceback.print_exc()
return os.path.join(dir, "plugins")
def loadPlugins(self):
plugdir = self.pluginsFolder()
sys.path.insert(0, plugdir)
import glob
plugins = [f.replace(".py", "") for f in os.listdir(plugdir) \
if f.endswith(".py")]
plugins = self.enabledPlugins()
plugins.sort()
for plugin in plugins:
try:
__import__(plugin)
nopy = plugin.replace(".py", "")
__import__(nopy)
except:
print "Error in %s.py" % plugin
print traceback.print_exc()
print "Error in %s" % plugin
traceback.print_exc()
def rebuildPluginsMenu(self):
if getattr(self, "pluginActions", None) is None:
self.pluginActions = []
for action in self.pluginActions:
self.mainWin.menuStartup.removeAction(action)
all = self.allPlugins()
all.sort()
for fname in all:
enabled = fname.endswith(".py")
p = re.sub("\.py(\.off)?", "", fname)
a = QAction(p, self)
a.setCheckable(True)
a.setChecked(enabled)
self.connect(a, SIGNAL("triggered()"),
lambda fname=fname: self.togglePlugin(fname))
self.mainWin.menuStartup.addAction(a)
self.pluginActions.append(a)
def enabledPlugins(self):
return [p for p in os.listdir(self.pluginsFolder())
if p.endswith(".py")]
def disabledPlugins(self):
return [p for p in os.listdir(self.pluginsFolder())
if p.endswith(".py.off")]
def allPlugins(self):
return [p for p in os.listdir(self.pluginsFolder())
if p.endswith(".py.off") or p.endswith(".py")]
def onOpenPluginFolder(self):
QDesktopServices.openUrl(QUrl("file://" + self.pluginsFolder()))
def onGetPlugins(self):
QDesktopServices.openUrl(QUrl("http://ichi2.net/anki/wiki/Plugins"))
def enablePlugin(self, p):
pd = self.pluginsFolder()
os.rename(os.path.join(pd, p),
os.path.join(pd, p.replace(".off", "")))
def disablePlugin(self, p):
pd = self.pluginsFolder()
os.rename(os.path.join(pd, p),
os.path.join(pd, p.replace(".py", ".py.off")))
def onEnableAllPlugins(self):
for p in self.disabledPlugins():
self.enablePlugin(p)
self.rebuildPluginsMenu()
def onDisableAllPlugins(self):
for p in self.enabledPlugins():
self.disablePlugin(p)
self.rebuildPluginsMenu()
def togglePlugin(self, plugin):
if plugin.endswith(".py"):
self.disablePlugin(plugin)
else:
self.enablePlugin(plugin)
self.rebuildPluginsMenu()
# Font localisation
##########################################################################

View file

@ -172,6 +172,7 @@ class Preferences(QDialog):
self.dialog.showTray.setChecked(self.config['showTrayIcon'])
self.dialog.showTimer.setChecked(self.config['showTimer'])
self.dialog.simpleToolbar.setChecked(self.config['simpleToolbar'])
self.dialog.toolbarIconSize.setText(str(self.config['iconSize']))
def updateAdvanced(self):
self.config['showToolbar'] = self.dialog.showToolbar.isChecked()
@ -186,6 +187,12 @@ class Preferences(QDialog):
self.config['showTimer'] = self.dialog.showTimer.isChecked()
self.config['suppressEstimates'] = self.dialog.suppressEstimates.isChecked()
self.config['simpleToolbar'] = self.dialog.simpleToolbar.isChecked()
i = 32
try:
i = int(self.dialog.toolbarIconSize.text())
except:
pass
self.config['iconSize'] = i
def codeToIndex(self, code):
n = 0

View file

@ -99,12 +99,9 @@ class StatusView(object):
if sys.platform.startswith("darwin"):
self.timer.setFixedWidth(40)
self.addWidget(self.timer)
# mac
if sys.platform.startswith("darwin"):
# we don't want non-coloured, throbbing widgets
self.plastiqueStyle = QStyleFactory.create("plastique")
self.progressBar.setStyle(self.plastiqueStyle)
self.retentionBar.setStyle(self.plastiqueStyle)
self.plastiqueStyle = QStyleFactory.create("plastique")
self.progressBar.setStyle(self.plastiqueStyle)
self.retentionBar.setStyle(self.plastiqueStyle)
self.optionsButton = QPushButton()
self.optionsButton.setIcon(QIcon(":/icons/configure.png"))
self.optionsButton.setFixedSize(20, 20)

77
designer/activetags.ui Normal file
View file

@ -0,0 +1,77 @@
<ui version="4.0" >
<class>Dialog</class>
<widget class="QDialog" name="Dialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>202</width>
<height>265</height>
</rect>
</property>
<property name="windowTitle" >
<string>Active Tags</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QLabel" name="label" >
<property name="text" >
<string>&lt;h1>Select Active Tags&lt;/h1></string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="list" >
<property name="selectionMode" >
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -8,7 +8,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>366</width>
<width>388</width>
<height>408</height>
</rect>
</property>
@ -29,7 +29,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<width>372</width>
<height>342</height>
</rect>
</property>
@ -143,7 +143,7 @@ p, li { white-space: pre-wrap; }
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<width>372</width>
<height>342</height>
</rect>
</property>
@ -340,7 +340,7 @@ p, li { white-space: pre-wrap; }
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<width>372</width>
<height>342</height>
</rect>
</property>
@ -405,7 +405,7 @@ p, li { white-space: pre-wrap; }
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<width>372</width>
<height>342</height>
</rect>
</property>
@ -446,7 +446,7 @@ p, li { white-space: pre-wrap; }
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<width>372</width>
<height>342</height>
</rect>
</property>
@ -551,12 +551,6 @@ p, li { white-space: pre-wrap; }
</item>
<item row="3" column="0" >
<widget class="QLabel" name="label_2" >
<property name="minimumSize" >
<size>
<width>220</width>
<height>0</height>
</size>
</property>
<property name="text" >
<string>&lt;b>2: Initial Hard Interval&lt;/b></string>
</property>

View file

@ -6,7 +6,7 @@
<x>0</x>
<y>0</y>
<width>543</width>
<height>285</height>
<height>301</height>
</rect>
</property>
<property name="sizePolicy" >
@ -26,7 +26,7 @@
<property name="geometry" >
<rect>
<x>0</x>
<y>53</y>
<y>69</y>
<width>543</width>
<height>212</height>
</rect>
@ -345,6 +345,8 @@
</widget>
</item>
</layout>
<zorder>help</zorder>
<zorder>mainTextFrame</zorder>
</widget>
</item>
</layout>
@ -383,12 +385,13 @@
<addaction name="actionAddcards" />
<addaction name="actionEditdeck" />
<addaction name="separator" />
<addaction name="actionActiveTags" />
<addaction name="separator" />
<addaction name="actionDisplayProperties" />
<addaction name="actionModelProperties" />
<addaction name="actionDeckProperties" />
<addaction name="separator" />
<addaction name="actionPreferences" />
<addaction name="separator" />
</widget>
<widget class="QMenu" name="menuDeck" >
<property name="title" >
@ -465,9 +468,27 @@
<addaction name="actionCheckDatabaseIntegrity" />
<addaction name="actionOptimizeDatabase" />
</widget>
<widget class="QMenu" name="menuPlugins" >
<property name="title" >
<string>&amp;Plugins</string>
</property>
<widget class="QMenu" name="menuStartup" >
<property name="title" >
<string>Startup</string>
</property>
<addaction name="actionEnableAllPlugins" />
<addaction name="actionDisableAllPlugins" />
<addaction name="separator" />
</widget>
<addaction name="actionGetPlugins" />
<addaction name="actionOpenPluginFolder" />
<addaction name="separator" />
<addaction name="menuStartup" />
</widget>
<addaction name="menuDeck" />
<addaction name="menuEdit" />
<addaction name="menuTools" />
<addaction name="menuPlugins" />
<addaction name="menuAdvanced" />
<addaction name="menuHelp" />
</widget>
@ -475,7 +496,7 @@
<property name="geometry" >
<rect>
<x>0</x>
<y>265</y>
<y>281</y>
<width>543</width>
<height>20</height>
</rect>
@ -490,12 +511,18 @@
<x>0</x>
<y>23</y>
<width>543</width>
<height>30</height>
<height>46</height>
</rect>
</property>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="iconSize" >
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<attribute name="toolBarArea" >
<enum>TopToolBarArea</enum>
</attribute>
@ -945,6 +972,36 @@
<string>Release Notes..</string>
</property>
</action>
<action name="actionGetPlugins" >
<property name="text" >
<string>&amp;Get Plugins..</string>
</property>
</action>
<action name="actionOpenPluginFolder" >
<property name="text" >
<string>&amp;Open Plugin Folder..</string>
</property>
</action>
<action name="actionEnableAllPlugins" >
<property name="text" >
<string>&amp;Enable All Plugins</string>
</property>
</action>
<action name="actionDisableAllPlugins" >
<property name="text" >
<string>&amp;Disable All Plugins</string>
</property>
</action>
<action name="actionA" >
<property name="text" >
<string>a</string>
</property>
</action>
<action name="actionActiveTags" >
<property name="text" >
<string>Active &amp;Tags..</string>
</property>
</action>
</widget>
<resources>
<include location="../icons.qrc" />

View file

@ -462,6 +462,13 @@
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QCheckBox" name="simpleToolbar" >
<property name="text" >
<string>Simple toolbar</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QCheckBox" name="showTimer" >
<property name="text" >
@ -511,13 +518,33 @@
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QCheckBox" name="simpleToolbar" >
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<widget class="QLabel" name="label_11" >
<property name="text" >
<string>Simple toolbar</string>
<string>Toolbar icon size</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="toolbarIconSize" />
</item>
</layout>
</item>
<item>
@ -548,8 +575,6 @@
</widget>
</item>
</layout>
<zorder>buttonBox</zorder>
<zorder>tabWidget</zorder>
</widget>
<tabstops>
<tabstop>tabWidget</tabstop>
@ -581,6 +606,7 @@
<tabstop>showToolbar</tabstop>
<tabstop>tallButtons</tabstop>
<tabstop>showTray</tabstop>
<tabstop>toolbarIconSize</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
@ -592,8 +618,8 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>266</x>
<y>476</y>
<x>270</x>
<y>412</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
@ -608,8 +634,8 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>334</x>
<y>476</y>
<x>317</x>
<y>412</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
@ -624,12 +650,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>94</x>
<y>157</y>
<x>105</x>
<y>133</y>
</hint>
<hint type="destinationlabel" >
<x>235</x>
<y>160</y>
<x>227</x>
<y>134</y>
</hint>
</hints>
</connection>
@ -640,12 +666,28 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>80</x>
<y>178</y>
<x>91</x>
<y>164</y>
</hint>
<hint type="destinationlabel" >
<x>174</x>
<y>176</y>
<x>227</x>
<y>165</y>
</hint>
</hints>
</connection>
<connection>
<sender>simpleToolbar</sender>
<signal>toggled(bool)</signal>
<receiver>toolbarIconSize</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>116</x>
<y>115</y>
</hint>
<hint type="destinationlabel" >
<x>308</x>
<y>335</y>
</hint>
</hints>
</connection>