def reInit(self): """Re-inits the parts of the GUI that can be changed at runtime.""" self.setTheme() self.setupUi() self.noteProvider = [] if getConfig(u'noteProvider') == u'gnote': from libzotero._noteProvider.gnoteProvider import GnoteProvider print(u"qnotero.reInit(): using GnoteProvider") self.noteProvider = GnoteProvider(self) self.zotero = LibZotero(getConfig(u"zoteroPath"), self.noteProvider) if hasattr(self, u"sysTray"): self.sysTray.setIcon(self.theme.icon(u"qnotero"))
def reInit(self): """Re-init the parts of the GUI that can be changed at runtime""" self.setTheme() self.setupUi() if getConfig("noteProvider") == "gnote": from libzotero._noteProvider.gnoteProvider import GnoteProvider print "qnotero.reInit(): using GnoteProvider" self.noteProvider = GnoteProvider() else: self.noteProvider = None self.zotero = LibZotero(getConfig("zoteroPath"), self.noteProvider) if hasattr(self, "sysTray"): self.sysTray.setIcon(self.theme.icon("qnotero"))
def reInit(self): """Re-inits the parts of the GUI that can be changed at runtime.""" self.setTheme() self.setupUi() self.noteProvider = [] self.noResults() self.ui.listWidgetResults.clear() self.ui.textAbstract.setText(u'') self.ui.lineEditQuery.clear() if getConfig(u'noteProvider') == u'gnote': from libzotero._noteProvider.gnoteProvider import GnoteProvider print(u"qnotero.reInit(): using GnoteProvider") self.noteProvider = GnoteProvider(self) self.zotero = LibZotero(getConfig(u"zoteroPath"), self.noteProvider) if hasattr(self, u"sysTray"): self.sysTray.setIcon(self.theme.icon("qnotero", ".png"))
class Qnotero(QMainWindow): """The main class of the Qnotero GUI""" version = "0.48" def __init__(self, systray=True, debug=False, reset=False, parent=None): """ Constructor Keyword arguments: systray -- enables the system tray icon (default=True) debug -- enable debugging output (default=False) reset -- reset preferences (default=False) parent -- parent QWidget (default=None) """ QMainWindow.__init__(self, parent) self.ui = Ui_Qnotero() self.ui.setupUi(self) if not reset: self.restoreState() self.debug = debug self.reInit() self.noResults() if systray: self.sysTray = SysTray(self) self.sysTray.show() self.minimizeOnClose = True else: self.minimizeOnClose = False if getConfig("firstRun"): self.preferences(firstRun=True) if getConfig("autoUpdateCheck"): self.updateCheck() def close(self): """Exit the program""" self.minimizeOnClose = False QMainWindow.close(self) def closeEvent(self, e): """ Close or minimze to tray, depending on when the function is called Arguments: e -- a QCloseEvent """ if self.minimizeOnClose: self.popDown() e.ignore() else: e.accept() self.listener.alive = False sys.exit() def hideNoteHint(self): """Hide the note available message""" self.ui.labelNoteAvailable.hide() def leaveEvent(self, e): """Hide the Window when the mouse is lost""" self.popDown() def openNote(self): """Open the active note""" self.activeNote.open() def noResults(self, query=None): """ Displays the no results message Keyword arguments: query -- a query (default=None) """ if query != None: self.showResultMsg("No results for %s" % query) else: self.showResultMsg("Please enter a search term") def popDown(self): """Minimize to the tray""" self.hide() def popUp(self): """Popup from the tray""" # Reposition the window r = QDesktopWidget().availableGeometry() s = self.size() pos = getConfig("pos") if pos == "Top right": x = r.left() + r.width() - s.width() y = r.top() elif pos == "Top left": x = r.left() y = r.top() elif pos == "Bottom right": x = r.left() + r.width() - s.width() y = r.top() + r.height() - s.height() elif pos == "Bottom left": x = r.left() y = r.top() + r.height() - s.height() else: x = r.left() + r.width() / 2 - s.width() / 2 y = r.top() + r.height() / 2 - s.height() / 2 self.move(x, y) # Show it self.show() QCoreApplication.processEvents() self.raise_() self.activateWindow() # Focus the search box self.ui.lineEditQuery.selectAll() self.ui.lineEditQuery.setFocus() def preferences(self, firstRun=False): """ Show the preferences dialog Keyword arguments: firstRun -- indicates if the first run message should be shown (default=False) """ from libqnotero.preferences import Preferences Preferences(self, firstRun=firstRun).exec_() def previewNote(self, note): """ Show the note preview Arguments: note -- the Note to preview """ self.activeNote = note self.ui.labelNote.setText(note.preview) self.hideNoteHint() self.ui.widgetNote.show() self.ui.listWidgetResults.hide() def reInit(self): """Re-init the parts of the GUI that can be changed at runtime""" self.setTheme() self.setupUi() if getConfig("noteProvider") == "gnote": from libzotero._noteProvider.gnoteProvider import GnoteProvider print "qnotero.reInit(): using GnoteProvider" self.noteProvider = GnoteProvider() else: self.noteProvider = None self.zotero = LibZotero(getConfig("zoteroPath"), self.noteProvider) if hasattr(self, "sysTray"): self.sysTray.setIcon(self.theme.icon("qnotero")) def restoreState(self): """Restore the settings""" settings = QSettings("cogscinl", "qnotero") settings.beginGroup("Qnotero") restoreConfig(settings) settings.endGroup() def runResult(self, listWidgetItem): """Handle clicks on a result""" if listWidgetItem.zoteroItem.fulltext == None: return pdf = listWidgetItem.zoteroItem.fulltext.encode("latin-1") if os.name == "nt": os.startfile(pdf) else: pid = subprocess.Popen([getConfig("pdfReader"), pdf]) self.popDown() def saveState(self): """Save the settings""" settings = QSettings("cogscinl", "qnotero") settings.beginGroup("Qnotero") saveConfig(settings) settings.endGroup() def search(self, setFocus=False): """ Execute a search Keyword arguments: setFocus -- indicates whether the listWidgetResults needs to receive focus (default=False) """ self.ui.labelNoteAvailable.hide() self.ui.widgetNote.hide() self.ui.listWidgetResults.show() self.ui.listWidgetResults.clear() self.ui.lineEditQuery.needUpdate = False self.ui.lineEditQuery.timer.stop() query = unicode(self.ui.lineEditQuery.text()) if len(query) < getConfig("minQueryLength"): self.noResults() return zoteroItemList = self.zotero.search(query) if len(zoteroItemList) == 0: self.noResults(query) return self.showResultMsg("%d results for %s" % (len(zoteroItemList), query)) for zoteroItem in zoteroItemList: qnoteroItem = QnoteroItem(self, zoteroItem, \ self.ui.listWidgetResults) self.ui.listWidgetResults.addItem(qnoteroItem) if setFocus: self.ui.listWidgetResults.setFocus() def setSize(self, size): """ Set the window size Arguments: size -- a QSize """ self.setMinimumSize(size) self.setMaximumSize(size) def setTheme(self): """Load a theme""" theme = getConfig("theme") exec("from libqnotero._themes.%s import %s as Theme" % (theme.lower(), \ theme.capitalize())) self.theme = Theme(self) def setupUi(self): """Setup the GUI""" self.ui.pushButtonSearch.setIcon(self.theme.icon("search")) self.ui.pushButtonSearch.clicked.connect(self.search) self.ui.lineEditQuery.qnotero = self self.ui.listWidgetResults.qnotero = self self.ui.listWidgetResults.setItemDelegate(QnoteroItemDelegate(self)) self.ui.listWidgetResults.itemActivated.connect(self.runResult) self.ui.widgetNote.hide() self.ui.labelNoteAvailable.hide() self.ui.pushButtonOpenNote.clicked.connect(self.openNote) def showNoteHint(self): """Indicate that a note is available""" self.ui.labelNoteAvailable.show() def showResultMsg(self, msg): """ Show a status message Arguments: msg -- a message """ self.ui.labelResultMsg.setText("<small><i>%s</i></small>" % msg) def updateCheck(self): """Check for updates if update checking is on""" if not getConfig("autoUpdateCheck"): return True import urllib print "qnotero.updateCheck(): opening %s" % getConfig("updateUrl") try: fd = urllib.urlopen(getConfig("updateUrl")) mrv = float(fd.read().strip()) except: print "qnotero.updateCheck(): failed to check for update" return print "qnotero.updateCheck(): most recent version is %.2f" % mrv if mrv > self.version: QMessageBox.information(self, "Update found", \ "A new version of Qnotero %s is available! Please visit http://www.cogsci.nl/ for more information." % mrv)
class Qnotero(QMainWindow, UiLoader): """The main class of the Qnotero GUI""" version = '1.0.0' def __init__(self, systray=True, debug=False, reset=False, parent=None): """ Constructor. Keyword arguments: systray -- Enables the system tray icon (default=True) debug -- Enable debugging output (default=False) reset -- Reset preferences (default=False) parent -- Parent QWidget (default=None) """ QMainWindow.__init__(self, parent) self.loadUi('qnotero') if not reset: self.restoreState() self.debug = debug self.reInit() self.noResults() if systray: self.sysTray = SysTray(self) self.sysTray.show() self.minimizeOnClose = True else: self.minimizeOnClose = False if getConfig(u"firstRun") or not os.path.exists(getConfig('zoteroPath')): self.preferences(firstRun=True) if getConfig(u"autoUpdateCheck"): self.updateCheck() def close(self): """Exits the program.""" self.minimizeOnClose = False QMainWindow.close(self) def closeEvent(self, e): """ Close or minimze to tray, depending on when the function is called Arguments: e -- a QCloseEvent """ if self.minimizeOnClose: self.popDown() e.ignore() else: e.accept() if self.listener != None: self.listener.alive = False sys.exit() def hideNoteHint(self): """Hide the note available message""" self.ui.labelNoteAvailable.hide() def leaveEvent(self, e): """Hide the Window when the mouse is lost""" self.popDown() def openNote(self): """Open the active note""" self.activeNote.open() def noResults(self, query=None): """ Displays the no results message Keyword arguments: query -- a query (default=None) """ if query != None: self.showResultMsg(u"No results for %s" % query) else: self.showResultMsg(u"Please enter a search term") def popDown(self): """Minimize to the tray""" if self.minimizeOnClose: self.hide() else: self.close() def popUp(self): """Popup from the tray""" # Reposition the window r = QDesktopWidget().availableGeometry() s = self.size() pos = getConfig(u"pos") if pos == u"Top right": x = r.left() + r.width()-s.width() y = r.top() elif pos == u"Top left": x = r.left() y = r.top() elif pos == u"Bottom right": x = r.left() + r.width()-s.width() y = r.top() + r.height()-s.height() elif pos == u"Bottom left": x = r.left() y = r.top() + r.height()-s.height() else: x = r.left() + r.width()/2 - s.width()/2 y = r.top() + r.height()/2 - s.height()/2 self.move(x, y) # Show it self.show() QCoreApplication.processEvents() self.raise_() self.activateWindow() # Focus the search box self.ui.lineEditQuery.selectAll() self.ui.lineEditQuery.setFocus() def preferences(self, firstRun=False): """ Show the preferences dialog Keyword arguments: firstRun -- indicates if the first run message should be shown (default=False) """ from libqnotero.preferences import Preferences Preferences(self, firstRun=firstRun).exec_() def previewNote(self, note): """ Show the note preview Arguments: note -- the Note to preview """ self.activeNote = note self.ui.labelNote.setText(note.preview) self.hideNoteHint() self.ui.widgetNote.show() self.ui.listWidgetResults.hide() def reInit(self): """Re-inits the parts of the GUI that can be changed at runtime.""" self.setTheme() self.setupUi() self.noteProvider = [] if getConfig(u'noteProvider') == u'gnote': from libzotero._noteProvider.gnoteProvider import GnoteProvider print(u"qnotero.reInit(): using GnoteProvider") self.noteProvider = GnoteProvider(self) self.zotero = LibZotero(getConfig(u"zoteroPath"), self.noteProvider) if hasattr(self, u"sysTray"): self.sysTray.setIcon(self.theme.icon(u"qnotero")) def restoreState(self): """Restore the settings""" settings = QSettings(u"cogscinl", u"qnotero") settings.beginGroup(u"Qnotero"); restoreConfig(settings) settings.endGroup() def runResult(self, listWidgetItem): """Handle clicks on a result""" if listWidgetItem.zoteroItem.fulltext == None: return pdf = listWidgetItem.zoteroItem.fulltext if os.name == 'nt': os.startfile(pdf) else: # For some reason, the file must be encoded with latin-1, despite # the fact that it's a utf-8 encoded database and filesystem! reader = getConfig('pdfReader').encode(sys.getfilesystemencoding()) pid = subprocess.Popen([reader, pdf]) self.popDown() def saveState(self): """Save the settings""" settings = QSettings(u"cogscinl", u"qnotero") settings.beginGroup(u"Qnotero") saveConfig(settings) settings.endGroup() def search(self, setFocus=False): """ Execute a search Keyword arguments: setFocus -- indicates whether the listWidgetResults needs to receive focus (default=False) """ self.ui.labelNoteAvailable.hide() self.ui.widgetNote.hide() self.ui.listWidgetResults.show() self.ui.listWidgetResults.clear() self.ui.lineEditQuery.needUpdate = False self.ui.lineEditQuery.timer.stop() query = self.ui.lineEditQuery.text() if len(query) < getConfig(u"minQueryLength"): self.noResults() return zoteroItemList = self.zotero.search(query) if len(zoteroItemList) == 0: self.noResults(query) return self.showResultMsg(u"%d results for %s" % (len(zoteroItemList), query)) for zoteroItem in zoteroItemList: qnoteroItem = QnoteroItem(self, zoteroItem, \ self.ui.listWidgetResults) self.ui.listWidgetResults.addItem(qnoteroItem) if setFocus: self.ui.listWidgetResults.setFocus() def setSize(self, size): """ Set the window size Arguments: size -- a QSize """ self.setMinimumSize(size) self.setMaximumSize(size) def setTheme(self): """Load a theme""" theme = getConfig(u'theme') mod = __import__(u'libqnotero._themes.%s' % theme.lower(), fromlist= \ [u'dummy']) cls = getattr(mod, theme.capitalize()) self.theme = cls(self) def setupUi(self): """Setup the GUI""" self.ui.pushButtonSearch.setIcon(self.theme.icon(u"search")) self.ui.pushButtonSearch.clicked.connect(self.search) self.ui.lineEditQuery.qnotero = self self.ui.listWidgetResults.qnotero = self self.ui.listWidgetResults.setItemDelegate(QnoteroItemDelegate(self)) self.ui.listWidgetResults.itemActivated.connect(self.runResult) self.ui.widgetNote.hide() self.ui.labelNoteAvailable.hide() self.ui.pushButtonOpenNote.clicked.connect(self.openNote) def showNoteHint(self): """Indicate that a note is available""" self.ui.labelNoteAvailable.show() def showResultMsg(self, msg): """ Shows a status message. Arguments: msg -- A message. """ self.ui.labelResultMsg.setText(u"<small><i>%s</i></small>" % msg) def updateCheck(self): """Checks for updates if update checking is on.""" if not getConfig(u"autoUpdateCheck"): return True import urllib.request from distutils.version import LooseVersion print(u"qnotero.updateCheck(): opening %s" % getConfig(u"updateUrl")) try: fd = urllib.request.urlopen(getConfig(u"updateUrl")) mrv = fd.read().decode('utf-8').strip() except: print('qnotero.updateCheck(): failed to check for update') return print("qnotero.updateCheck(): most recent = %s, current = %s" \ % (mrv, self.version)) if LooseVersion(mrv) > LooseVersion(self.version): QMessageBox.information(self, 'Update found', ('A new version of Qnotero is available! Please visit ' 'http://www.cogsci.nl/qnotero for more information.'))
class Qnotero(QMainWindow, UiLoader): """The main class of the Qnotero GUI""" version = '2.1.1' def __init__(self, systray=True, debug=False, reset=False, parent=None): """ Constructor. Keyword arguments: systray -- Enables the system tray icon (default=True) debug -- Enable debugging output (default=False) reset -- Reset preferences (default=False) parent -- Parent QWidget (default=None) """ QMainWindow.__init__(self, parent) self.loadUi('qnotero') if not reset: self.restoreState() self.debug = debug self.reInit() self.noResults() if systray: self.sysTray = SysTray(self) self.sysTray.show() self.minimizeOnClose = True else: self.minimizeOnClose = False if getConfig(u"firstRun") or not os.path.exists( getConfig('zoteroPath')): self.preferences(firstRun=True) if getConfig(u"autoUpdateCheck"): self.updateCheck() def close(self): """Exits the program.""" self.minimizeOnClose = False QMainWindow.close(self) def closeEvent(self, e): """ Close or minimze to tray, depending on when the function is called Arguments: e -- a QCloseEvent """ if self.minimizeOnClose: self.popDown() e.ignore() else: e.accept() if self.listener != None: self.listener.alive = False sys.exit() def hideNoteHint(self): """Hide the note available message""" self.ui.labelNoteAvailable.hide() def leaveEvent(self, e): """Hide the Window when the mouse is lost""" self.popDown() def openNote(self): """Open the active note""" self.activeNote.open() def noResults(self, query=None): """ Displays the no results message Keyword arguments: query -- a query (default=None) """ if query != None: self.showResultMsg(u"No results for %s" % query) else: self.showResultMsg(u"Please enter a search term") def popDown(self): """Minimize to the tray""" if self.minimizeOnClose: self.hide() else: self.close() def popUp(self): """Popup from the tray""" # Reposition the window r = QDesktopWidget().availableGeometry() s = self.size() pos = getConfig(u"pos") if pos == u"Top right": x = r.left() + r.width() - s.width() y = r.top() elif pos == u"Top left": x = r.left() y = r.top() elif pos == u"Bottom right": x = r.left() + r.width() - s.width() y = r.top() + r.height() - s.height() elif pos == u"Bottom left": x = r.left() y = r.top() + r.height() - s.height() else: x = r.left() + r.width() / 2 - s.width() / 2 y = r.top() + r.height() / 2 - s.height() / 2 self.move(x, y) # Show it self.show() QCoreApplication.processEvents() self.raise_() self.activateWindow() # Focus the search box self.ui.lineEditQuery.selectAll() self.ui.lineEditQuery.setFocus() def preferences(self, firstRun=False): """ Show the preferences dialog Keyword arguments: firstRun -- indicates if the first run message should be shown (default=False) """ from libqnotero.preferences import Preferences Preferences(self, firstRun=firstRun).exec_() def previewNote(self, note): """ Show the note preview Arguments: note -- the Note to preview """ self.activeNote = note self.ui.labelNote.setText(note.preview) self.hideNoteHint() self.ui.widgetNote.show() self.ui.listWidgetResults.hide() def reInit(self): """Re-inits the parts of the GUI that can be changed at runtime.""" self.setTheme() self.setupUi() self.noteProvider = [] if getConfig(u'noteProvider') == u'gnote': from libzotero._noteProvider.gnoteProvider import GnoteProvider print(u"qnotero.reInit(): using GnoteProvider") self.noteProvider = GnoteProvider(self) self.zotero = LibZotero(getConfig(u"zoteroPath"), self.noteProvider) if hasattr(self, u"sysTray"): self.sysTray.updateIcon() def restoreState(self): """Restore the settings""" settings = QSettings(u"cogscinl", u"qnotero") settings.beginGroup(u"Qnotero") restoreConfig(settings) settings.endGroup() def runResult(self, listWidgetItem): """Handle clicks on a result""" if listWidgetItem.zoteroItem.fulltext == None: return pdf = listWidgetItem.zoteroItem.fulltext if os.name == 'nt': os.startfile(pdf) else: # For some reason, the file must be encoded with latin-1, despite # the fact that it's a utf-8 encoded database and filesystem! reader = getConfig('pdfReader').encode(sys.getfilesystemencoding()) pid = subprocess.Popen([reader, pdf]) self.popDown() def saveState(self): """Save the settings""" settings = QSettings(u"cogscinl", u"qnotero") settings.beginGroup(u"Qnotero") saveConfig(settings) settings.endGroup() def search(self, setFocus=False): """ Execute a search Keyword arguments: setFocus -- indicates whether the listWidgetResults needs to receive focus (default=False) """ self.ui.labelNoteAvailable.hide() self.ui.widgetNote.hide() self.ui.listWidgetResults.show() self.ui.listWidgetResults.clear() self.ui.lineEditQuery.needUpdate = False self.ui.lineEditQuery.timer.stop() query = self.ui.lineEditQuery.text() if len(query) < getConfig(u"minQueryLength"): self.noResults() return zoteroItemList = self.zotero.search(query) if len(zoteroItemList) == 0: self.noResults(query) return self.showResultMsg(u"%d results for %s" % (len(zoteroItemList), query)) for zoteroItem in zoteroItemList: qnoteroItem = QnoteroItem(self, zoteroItem, \ self.ui.listWidgetResults) self.ui.listWidgetResults.addItem(qnoteroItem) if setFocus: self.ui.listWidgetResults.setFocus() def setSize(self, size): """ Set the window size Arguments: size -- a QSize """ self.setMinimumSize(size) self.setMaximumSize(size) def setTheme(self): """Load a theme""" theme = getConfig(u'theme') iconOverride = getConfig(u'iconOverride') if iconOverride: self.isThemeIcon = False self.iconName = u'../' + iconOverride else: self.isThemeIcon = True self.iconName = u'qnotero' mod = __import__(u'libqnotero._themes.%s' % theme.lower(), fromlist= \ [u'dummy']) cls = getattr(mod, theme.capitalize()) self.theme = cls(self) def setupUi(self): """Setup the GUI""" self.ui.pushButtonSearch.setIcon(self.theme.icon(u"search")) self.ui.pushButtonSearch.clicked.connect(self.search) self.ui.lineEditQuery.qnotero = self self.ui.listWidgetResults.qnotero = self self.ui.listWidgetResults.setItemDelegate(QnoteroItemDelegate(self)) self.ui.listWidgetResults.itemActivated.connect(self.runResult) self.ui.widgetNote.hide() self.ui.labelNoteAvailable.hide() self.ui.pushButtonOpenNote.clicked.connect(self.openNote) def showNoteHint(self): """Indicate that a note is available""" self.ui.labelNoteAvailable.show() def showResultMsg(self, msg): """ Shows a status message. Arguments: msg -- A message. """ self.ui.labelResultMsg.setText(u"<small><i>%s</i></small>" % msg) def updateCheck(self): """Checks for updates if update checking is on.""" if not getConfig(u"autoUpdateCheck"): return True import urllib.request from distutils.version import LooseVersion print(u"qnotero.updateCheck(): opening %s" % getConfig(u"updateUrl")) try: fd = urllib.request.urlopen(getConfig(u"updateUrl")) mrv = fd.read().decode('utf-8').strip() except: print('qnotero.updateCheck(): failed to check for update') return print("qnotero.updateCheck(): most recent = %s, current = %s" \ % (mrv, self.version)) if LooseVersion(mrv) > LooseVersion(self.version): QMessageBox.information( self, 'Update found', ('A new version of Qnotero is available! Please visit ' 'http://www.cogsci.nl/qnotero for more information.'))
class Qnotero(QMainWindow): """The main class of the Qnotero GUI""" version = "0.48" def __init__(self, systray=True, debug=False, reset=False, parent=None): """ Constructor Keyword arguments: systray -- enables the system tray icon (default=True) debug -- enable debugging output (default=False) reset -- reset preferences (default=False) parent -- parent QWidget (default=None) """ QMainWindow.__init__(self, parent) self.ui = Ui_Qnotero() self.ui.setupUi(self) if not reset: self.restoreState() self.debug = debug self.reInit() self.noResults() if systray: self.sysTray = SysTray(self) self.sysTray.show() self.minimizeOnClose = True else: self.minimizeOnClose = False if getConfig("firstRun"): self.preferences(firstRun=True) if getConfig("autoUpdateCheck"): self.updateCheck() def close(self): """Exit the program""" self.minimizeOnClose = False QMainWindow.close(self) def closeEvent(self, e): """ Close or minimze to tray, depending on when the function is called Arguments: e -- a QCloseEvent """ if self.minimizeOnClose: self.popDown() e.ignore() else: e.accept() self.listener.alive = False sys.exit() def hideNoteHint(self): """Hide the note available message""" self.ui.labelNoteAvailable.hide() def leaveEvent(self, e): """Hide the Window when the mouse is lost""" self.popDown() def openNote(self): """Open the active note""" self.activeNote.open() def noResults(self, query=None): """ Displays the no results message Keyword arguments: query -- a query (default=None) """ if query != None: self.showResultMsg("No results for %s" % query) else: self.showResultMsg("Please enter a search term") def popDown(self): """Minimize to the tray""" self.hide() def popUp(self): """Popup from the tray""" # Reposition the window r = QDesktopWidget().availableGeometry() s = self.size() pos = getConfig("pos") if pos == "Top right": x = r.left() + r.width()-s.width() y = r.top() elif pos == "Top left": x = r.left() y = r.top() elif pos == "Bottom right": x = r.left() + r.width()-s.width() y = r.top() + r.height()-s.height() elif pos == "Bottom left": x = r.left() y = r.top() + r.height()-s.height() else: x = r.left() + r.width()/2 - s.width()/2 y = r.top() + r.height()/2 - s.height()/2 self.move(x, y) # Show it self.show() QCoreApplication.processEvents() self.raise_() self.activateWindow() # Focus the search box self.ui.lineEditQuery.selectAll() self.ui.lineEditQuery.setFocus() def preferences(self, firstRun=False): """ Show the preferences dialog Keyword arguments: firstRun -- indicates if the first run message should be shown (default=False) """ from libqnotero.preferences import Preferences Preferences(self, firstRun=firstRun).exec_() def previewNote(self, note): """ Show the note preview Arguments: note -- the Note to preview """ self.activeNote = note self.ui.labelNote.setText(note.preview) self.hideNoteHint() self.ui.widgetNote.show() self.ui.listWidgetResults.hide() def reInit(self): """Re-init the parts of the GUI that can be changed at runtime""" self.setTheme() self.setupUi() if getConfig("noteProvider") == "gnote": from libzotero._noteProvider.gnoteProvider import GnoteProvider print "qnotero.reInit(): using GnoteProvider" self.noteProvider = GnoteProvider() else: self.noteProvider = None self.zotero = LibZotero(getConfig("zoteroPath"), self.noteProvider) if hasattr(self, "sysTray"): self.sysTray.setIcon(self.theme.icon("qnotero")) def restoreState(self): """Restore the settings""" settings = QSettings("cogscinl", "qnotero") settings.beginGroup("Qnotero"); restoreConfig(settings) settings.endGroup() def runResult(self, listWidgetItem): """Handle clicks on a result""" if listWidgetItem.zoteroItem.fulltext == None: return pdf = listWidgetItem.zoteroItem.fulltext.encode("latin-1") if os.name == "nt": os.startfile(pdf) else: pid = subprocess.Popen([getConfig("pdfReader"), pdf]) self.popDown() def saveState(self): """Save the settings""" settings = QSettings("cogscinl", "qnotero") settings.beginGroup("Qnotero") saveConfig(settings) settings.endGroup() def search(self, setFocus=False): """ Execute a search Keyword arguments: setFocus -- indicates whether the listWidgetResults needs to receive focus (default=False) """ self.ui.labelNoteAvailable.hide() self.ui.widgetNote.hide() self.ui.listWidgetResults.show() self.ui.listWidgetResults.clear() self.ui.lineEditQuery.needUpdate = False self.ui.lineEditQuery.timer.stop() query = unicode(self.ui.lineEditQuery.text()) if len(query) < getConfig("minQueryLength"): self.noResults() return zoteroItemList = self.zotero.search(query) if len(zoteroItemList) == 0: self.noResults(query) return self.showResultMsg("%d results for %s" % (len(zoteroItemList), query)) for zoteroItem in zoteroItemList: qnoteroItem = QnoteroItem(self, zoteroItem, \ self.ui.listWidgetResults) self.ui.listWidgetResults.addItem(qnoteroItem) if setFocus: self.ui.listWidgetResults.setFocus() def setSize(self, size): """ Set the window size Arguments: size -- a QSize """ self.setMinimumSize(size) self.setMaximumSize(size) def setTheme(self): """Load a theme""" theme = getConfig("theme") exec("from libqnotero._themes.%s import %s as Theme" % (theme.lower(), \ theme.capitalize())) self.theme = Theme(self) def setupUi(self): """Setup the GUI""" self.ui.pushButtonSearch.setIcon(self.theme.icon("search")) self.ui.pushButtonSearch.clicked.connect(self.search) self.ui.lineEditQuery.qnotero = self self.ui.listWidgetResults.qnotero = self self.ui.listWidgetResults.setItemDelegate(QnoteroItemDelegate(self)) self.ui.listWidgetResults.itemActivated.connect(self.runResult) self.ui.widgetNote.hide() self.ui.labelNoteAvailable.hide() self.ui.pushButtonOpenNote.clicked.connect(self.openNote) def showNoteHint(self): """Indicate that a note is available""" self.ui.labelNoteAvailable.show() def showResultMsg(self, msg): """ Show a status message Arguments: msg -- a message """ self.ui.labelResultMsg.setText("<small><i>%s</i></small>" % msg) def updateCheck(self): """Check for updates if update checking is on""" if not getConfig("autoUpdateCheck"): return True import urllib print "qnotero.updateCheck(): opening %s" % getConfig("updateUrl") try: fd = urllib.urlopen(getConfig("updateUrl")) mrv = float(fd.read().strip()) except: print "qnotero.updateCheck(): failed to check for update" return print "qnotero.updateCheck(): most recent version is %.2f" % mrv if mrv > self.version: QMessageBox.information(self, "Update found", \ "A new version of Qnotero %s is available! Please visit http://www.cogsci.nl/ for more information." % mrv)
class Qnotero(QMainWindow, UiLoader): """The main class of the Qnotero GUI""" version = '2.3.0' def __init__(self, app=None, systray=True, debug=False, reset=False, parent=None): """ Constructor. Keyword arguments: systray -- Enables the system tray icon (default=True) debug -- Enable debugging output (default=False) reset -- Reset preferences (default=False) parent -- Parent QWidget (default=None) """ QMainWindow.__init__(self, parent) self.app = app self.loadUi('qnotero') if not reset: self.restoreState() self.debug = debug self.reInit() self.noResults() if systray: self.sysTray = SysTray(self) self.sysTray.show() self.minimizeOnClose = True else: self.minimizeOnClose = False if getConfig(u"firstRun") or not os.path.exists(getConfig('zoteroPath')): self.preferences(firstRun=True) if getConfig(u"autoUpdateCheck"): self.updateCheck() def close(self): """Exits the program.""" self.minimizeOnClose = False QMainWindow.close(self) def closeEvent(self, e): """ Close or minimze to tray, depending on when the function is called Arguments: e -- a QCloseEvent """ if self.minimizeOnClose and not e.spontaneous(): self.popDown() e.ignore() print(u'qnotero.closeEvent(): Hiding to system tray') else: e.accept() if self.listener is not None: self.listener.alive = False print(u'qnotero.closeEvent(): Exiting Qnotero, bye...') sys.exit() def hideNoteHint(self): """Hide the note available message""" self.ui.labelNoteAvailable.hide() def openNote(self): """Open the active note""" self.activeNote.open() def noResults(self, query=None): """ Displays the no results message Keyword arguments: query -- a query (default=None) """ if query is not None: self.showResultMsg(u"No results for %s" % query) else: self.showResultMsg(u"Please enter a search term") self.ui.textAbstract.setText(None) def popDown(self): """Minimize to the tray""" if self.minimizeOnClose: self.hide() else: self.close() def popUp(self): """Popup from the tray""" # Reposition the window # TODO: Add code to identify the screen to show the main window r = QDesktopWidget().availableGeometry() s = self.size() pos = getConfig(u"pos") if pos == u"Top right": x = r.left() + r.width() - s.width() - 10 y = r.top() elif pos == u"Top left": x = r.left() + 10 y = r.top() elif pos == u"Bottom right": x = r.left() + r.width() - s.width() - 10 y = r.top() + r.height() - s.height() elif pos == u"Bottom left": x = r.left() + 10 y = r.top() + r.height() - s.height() else: x = r.left() + r.width() / 2 - s.width() / 2 y = r.top() + r.height() / 2 - s.height() / 2 self.move(x, y) # Show it self.show() QCoreApplication.processEvents() self.raise_() self.activateWindow() # Focus the search box self.ui.lineEditQuery.selectAll() self.ui.lineEditQuery.setFocus() def preferences(self, firstRun=False): """ Show the preferences dialog Keyword arguments: firstRun -- indicates if the first run message should be shown (default=False) """ from libqnotero.preferences import Preferences Preferences(self, firstRun=firstRun).exec_() def previewNote(self, note): """ Show the note preview Arguments: note -- the Note to preview """ self.activeNote = note self.ui.labelNote.setText(note.preview) self.hideNoteHint() self.ui.widgetNote.show() self.ui.listWidgetResults.hide() def reInit(self): """Re-inits the parts of the GUI that can be changed at runtime.""" self.setTheme() self.setupUi() self.noteProvider = [] self.noResults() self.ui.listWidgetResults.clear() self.ui.textAbstract.setText(u'') self.ui.lineEditQuery.clear() self.ui.listWidgetResults.installEventFilter(self) if getConfig(u'noteProvider') == u'gnote': from libzotero._noteProvider.gnoteProvider import GnoteProvider print(u"qnotero.reInit(): using GnoteProvider") self.noteProvider = GnoteProvider(self) self.zotero = LibZotero(getConfig(u"zoteroPath"), self.noteProvider) if hasattr(self, u"sysTray"): self.sysTray.setIcon(self.theme.icon("qnotero", ".png")) def restoreState(self): """Restore the settings""" settings = QSettings(u"Qnotero", u"qnotero") settings.beginGroup(u"Qnotero") restoreConfig(settings) settings.endGroup() def saveState(self): """Save the settings""" settings = QSettings(u"Qnotero", u"qnotero") settings.beginGroup(u"Qnotero") saveConfig(settings) settings.endGroup() def search(self, setFocus=False): """ Execute a search Keyword arguments: setFocus -- indicates whether the listWidgetResults needs to receive focus (default=False) """ self.ui.labelNoteAvailable.hide() self.ui.listWidgetResults.show() self.ui.listWidgetResults.clear() self.ui.lineEditQuery.needUpdate = False self.ui.lineEditQuery.timer.stop() query = self.ui.lineEditQuery.text() if len(query) < getConfig(u"minQueryLength"): self.noResults() return zoteroItemList = self.zotero.search(query) if len(zoteroItemList) == 0: self.noResults(query) return self.showResultMsg(u"%d results for %s" % (len(zoteroItemList), query)) for zoteroItem in zoteroItemList: qnoteroItem = QnoteroItem(self, zoteroItem, self.ui.listWidgetResults) self.ui.listWidgetResults.addItem(qnoteroItem) if setFocus: self.ui.listWidgetResults.setFocus() def setSize(self, size): """ Set the window size Arguments: size -- a QSize """ self.setMinimumSize(size) self.setMaximumSize(size) def setTheme(self): """Load a theme""" theme = getConfig(u'theme') self.app.setStyle(getConfig(u'appStyle')) mod = __import__(u'libqnotero._themes.%s' % theme.lower(), fromlist=[u'dummy']) cls = getattr(mod, theme.capitalize()) self.theme = cls(self) def setupUi(self): """Setup the GUI""" self.ui.pushButtonSearch.setIcon(self.theme.icon(u"search")) self.ui.pushButtonSearch.clicked.connect(self.search) self.ui.lineEditQuery.qnotero = self self.ui.listWidgetResults.qnotero = self self.ui.listWidgetResults.setItemDelegate(QnoteroItemDelegate(self)) self.ui.pushButtonOpenNote.hide() self.ui.pushButtonReturnFromNote.hide() self.ui.labelNoteAvailable.hide() self.ui.labelNote.hide() self.ui.pushButtonOpenNote.clicked.connect(self.openNote) if getConfig(u'showAbstract'): self.ui.textAbstract.show() self.ui.labelAbstract.show() self.ui.textAbstract.setFixedHeight(200) else: self.ui.textAbstract.hide() self.ui.labelAbstract.hide() def showNoteHint(self): """Indicate that a note is available""" self.ui.labelNoteAvailable.show() def showResultMsg(self, msg): """ Shows a status message. Arguments: msg -- A message. """ self.ui.labelResultMsg.setText(u"<small><i>%s</i></small>" % msg) def eventFilter(self, source: 'QObject', e: 'QEvent') -> bool: if (e.type() == QtCore.QEvent.ContextMenu and source is self.ui.listWidgetResults): contextMenu = QMenu(self) actCopyAuthordate = contextMenu.addAction(u"Copy author(s) and year") actCopyDOI = contextMenu.addAction(u"Copy DOI") actCopyTitle = contextMenu.addAction(u"Copy title") actCopyAbs = contextMenu.addAction(u"Copy abstract") actCopyRef = contextMenu.addAction(u"Copy Reference") action = contextMenu.exec_(self.mapToGlobal(e.pos())) item = source.itemAt(e.pos()) if (action is None) or (item is None): return True clipboard = QtGui.QApplication.clipboard() clipboard.clear(mode=clipboard.Clipboard) if action is actCopyAuthordate: clipboard.setText(item.zoteroItem.author_date_format(), mode=clipboard.Clipboard) return True elif action is actCopyDOI: if item.zoteroItem.doi is not None: clipboard.setText(item.zoteroItem.doi, mode=clipboard.Clipboard) return True elif action is actCopyTitle: title = item.zoteroItem.format_title() if title is not None: clipboard.setText(title, mode=clipboard.Clipboard) return True elif action is actCopyAbs: if item.zoteroItem.abstract is not None: clipboard.setText(item.zoteroItem.abstract, mode=clipboard.Clipboard) return True elif action is actCopyRef: clipboard.setText(item.zoteroItem.full_format(), mode=clipboard.Clipboard) return True return QMainWindow.eventFilter(self, source, e) def updateCheck(self): """Checks for updates if update checking is on.""" if not getConfig(u"autoUpdateCheck"): return True import urllib.request from distutils.version import LooseVersion print(u"qnotero.updateCheck(): opening %s" % getConfig(u"updateUrl")) try: fd = urllib.request.urlopen(getConfig(u"updateUrl")) mrv = fd.read().decode('utf-8').strip() except: print('qnotero.updateCheck(): failed to check for update') return print("qnotero.updateCheck(): most recent = %s, current = %s" \ % (mrv, self.version)) if LooseVersion(mrv) > LooseVersion(self.version): QMessageBox.information(self, 'Update found', ('A new version of Qnotero is available! Please visit ' 'http://www.cogsci.nl/qnotero for more information.'))