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 __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 __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 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 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 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 keyPressEvent(self, e): """ Handle key presses Arguments: e -- a QKeyEvent """ if e.key() == Qt.Key_Return: self.qnotero.search(setFocus=False) return if e.key() == Qt.Key_Down: if self.needUpdate: self.qnotero.search(setFocus=True) elif self.qnotero.ui.listWidgetResults.count() > 0: self.qnotero.ui.listWidgetResults.setFocus() self.qnotero.ui.listWidgetResults.setCurrentItem( \ self.qnotero.ui.listWidgetResults.item(0)) return QLineEdit.keyPressEvent(self, e) self.timer.stop() self.timer = QTimer(self) self.timer.setSingleShot(True) self.timer.setInterval(getConfig("autoFire")) self.timer.timeout.connect(self.search) self.timer.start()
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 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 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 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 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 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"))
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 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)
def __init__(self, qnotero, firstRun=False): """ Constructor Arguments: qnotero -- a Qnotero instance Keyword arguments: firstRun -- indicates if the first run message should be shown (default=False) """ QDialog.__init__(self) self.qnotero = qnotero self.loadUi('preferences') self.ui.labelLocatePath.hide() if not firstRun: self.ui.labelFirstRun.hide() self.ui.labelTitleMsg.setText(self.ui.labelTitleMsg.text().replace( u"[version]", self.qnotero.version)) self.ui.pushButtonZoteroPathAutoDetect.clicked.connect( self.zoteroPathAutoDetect) self.ui.pushButtonZoteroPathBrowse.clicked.connect( self.zoteroPathBrowse) self.ui.checkBoxAutoUpdateCheck.setChecked( getConfig(u"autoUpdateCheck")) self.ui.checkBoxShowAbstract.setChecked(getConfig(u'showAbstract')) self.ui.lineEditZoteroPath.setText(getConfig(u"zoteroPath")) i = 0 pos = getConfig(u'pos') while True: self.ui.comboBoxPos.setCurrentIndex(i) if self.ui.comboBoxPos.currentText() == pos: break i += 1 i = 0 import libqnotero._themes themePath = os.path.dirname(libqnotero._themes.__file__) if platform.system() == 'Darwin' and hasattr(sys, 'frozen'): themePath = os.path.join(os.path.dirname(sys.executable), u'themes') for dirname in next(os.walk(themePath))[1]: self.ui.comboBoxTheme.addItem(dirname) if dirname == getConfig(u"theme").lower(): self.ui.comboBoxTheme.setCurrentIndex(i) i += 1 else: for _, theme, _ in pkgutil.iter_modules([themePath]): self.ui.comboBoxTheme.addItem(theme) if theme == getConfig(u"theme").lower(): self.ui.comboBoxTheme.setCurrentIndex(i) i += 1 i = 0 for style in QStyleFactory.keys(): self.ui.comboBoxStyle.addItem(style) if style == getConfig(u'appStyle'): self.ui.comboBoxStyle.setCurrentIndex(i) i += 1 self.adjustSize()
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 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.'))
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.'))
def __init__(self, qnotero, firstRun=False): """ Constructor Arguments: qnotero -- a Qnotero instance Keyword arguments: firstRun -- indicates if the first run message should be shown (default=False) """ QDialog.__init__(self) self.qnotero = qnotero self.loadUi('preferences') self.ui.labelLocatePath.hide() if not firstRun: self.ui.labelFirstRun.hide() self.ui.labelTitleMsg.setText(self.ui.labelTitleMsg.text().replace( u"[version]", self.qnotero.version)) self.ui.pushButtonZoteroPathAutoDetect.clicked.connect( self.zoteroPathAutoDetect) self.ui.pushButtonZoteroPathBrowse.clicked.connect( self.zoteroPathBrowse) self.ui.checkBoxAutoUpdateCheck.setChecked( getConfig(u"autoUpdateCheck")) self.ui.lineEditZoteroPath.setText(getConfig(u"zoteroPath")) i = 0 import libqnotero._themes themePath = os.path.dirname(libqnotero._themes.__file__) for _, theme, _ in pkgutil.iter_modules([themePath]): self.ui.comboBoxTheme.addItem(theme) if theme == getConfig(u"theme").lower(): self.ui.comboBoxTheme.setCurrentIndex(i) i += 1 icon = getConfig(u"iconOverride") self.ui.comboBoxIcon.setCurrentIndex( icons.index(icon) if icon in icons else 0) self.setStyleSheet(self.qnotero.styleSheet()) self.adjustSize()
def __init__(self, qnotero, firstRun=False): """ Constructor Arguments: qnotero -- a Qnotero instance Keyword arguments: firstRun -- indicates if the first run message should be shown (default=False) """ QDialog.__init__(self) self.qnotero = qnotero self.ui = Ui_Preferences() self.ui.setupUi(self) self.ui.labelLocatePath.hide() if not firstRun: self.ui.labelFirstRun.hide() self.ui.labelTitleMsg.setText( \ self.ui.labelTitleMsg.text().replace("[version]", \ self.qnotero.version)) self.ui.pushButtonZoteroPathAutoDetect.clicked.connect( \ self.zoteroPathAutoDetect) self.ui.pushButtonZoteroPathBrowse.clicked.connect( \ self.zoteroPathBrowse) self.ui.checkBoxAutoUpdateCheck.setChecked(getConfig("autoUpdateCheck")) self.ui.lineEditZoteroPath.setText(getConfig("zoteroPath")) i = 0 import libqnotero._themes themePath = os.path.dirname(libqnotero._themes.__file__) for _, theme, _ in pkgutil.iter_modules([themePath]): self.ui.comboBoxTheme.addItem(theme) if theme == getConfig("theme").lower(): self.ui.comboBoxTheme.setCurrentIndex(i) i += 1 self.setStyleSheet(self.qnotero.styleSheet()) self.adjustSize()
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 __init__(self, qnotero=None): """ Constructor Arguments: qnotero -- a Qnotero instance """ self.port = getConfig("listenerPort") self.qnotero = qnotero self.alive = True Thread.__init__(self) self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(("", self.port)) self.sock.settimeout(0.5)
def __init__(self, qnotero=None): """ Constructor Arguments: qnotero -- a Qnotero instance """ self.port = getConfig("listenerPort") self.qnotero = qnotero self.alive = True Thread.__init__(self) self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(("", self.port)) self.sock.settimeout(1.)
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 update(self, force=False): """ Checks if the local copy of the zotero database is up to date. If not, the data is also indexed. Arguments: force -- Indicates that the data should also be indexed, even if the local copy is up to date. (default=False) """ try: stats = os.stat(self.zotero_database) except Exception as e: print(u"libzotero.update(): %s" % e) return False # Only update if necessary if force or self.last_update is None or stats[8] > self.last_update: t = time.time() self.last_update = stats[8] self.index = {} self.collection_index = [] self.search_cache = {} # Copy the zotero database to the gnotero copy shutil.copyfile(self.zotero_database, self.gnotero_database) self.conn = sqlite3.connect(self.gnotero_database) self.cur = self.conn.cursor() # First create a list of deleted items, so we can ignore those later # TODO: Also get retracted items to ignore them too deleted = [] self.cur.execute(self.deleted_query) for item in self.cur.fetchall(): deleted.append(item[0]) # Retrieve information about date, publication, volume, issue, DOI, # title, and abstract if the option is selected if getConfig(u'showAbstract'): query = self.abs_info_query else: query = self.info_query self.cur.execute(query) for item in self.cur.fetchall(): item_id = item[0] key = item[3] if item_id not in deleted: item_name = item[1] # Parse date fields, because we only want a year or a # # 'special' date if item_name == u"date": item_value = None for sd in self.special_dates: if sd in item[2].lower(): item_value = sd break item_value = item[2][0:4] else: item_value = item[2] if item_id not in self.index: self.index[item_id] = zotero_item( item_id, noteProvider=self.noteProvider) self.index[item_id].key = key if item_name == u"publicationTitle": self.index[item_id].publication = str(item_value) elif item_name == u"date": self.index[item_id].date = item_value elif item_name == u"volume": self.index[item_id].volume = item_value elif item_name == u"issue": self.index[item_id].issue = item_value elif item_name == u"DOI": self.index[item_id].doi = item_value elif item_name == u"title": self.index[item_id].title = str(item_value) elif item_name == u'url': self.index[item_id].url = item_value elif item_name == u'abstractNote': self.index[item_id].abstract = item_value # Retrieve author or editor information self.cur.execute(self.author_query) for item in self.cur.fetchall(): item_id = item[0] if item_id not in deleted: item_author = item[1].title() if item_id not in self.index: self.index[item_id] = zotero_item(item_id) self.index[item_id].authors.append(item_author) # Retrieve collection information self.cur.execute(self.collection_query) for item in self.cur.fetchall(): item_id = item[0] if item_id not in deleted: item_collection = item[1] if item_id not in self.index: self.index[item_id] = zotero_item(item_id) self.index[item_id].collections.append(item_collection) if item_collection not in self.collection_index: self.collection_index.append(item_collection) # Retrieve tag information self.cur.execute(self.tag_query) for item in self.cur.fetchall(): item_id = item[0] if item_id not in deleted: item_tag = item[1] if item_id not in self.index: self.index[item_id] = zotero_item(item_id) self.index[item_id].tags.append(item_tag) if item_tag not in self.tag_index: self.tag_index.append(item_tag) # Retrieve attachments self.cur.execute(self.attachment_query) for item in self.cur.fetchall(): item_id = item[0] if item_id not in deleted: if item[1] is not None: att = item[1] # If the attachment is stored in the Zotero folder, it is preceded # by "storage:" if att[:8] == u"storage:": item_attachment = att[8:] attachment_id = item[2] if item_attachment[-4:].lower() in \ self.attachment_ext: if item_id not in self.index: self.index[item_id] = zotero_item(item_id) self.cur.execute( u"select items.key from items where itemID = %d" % attachment_id) key = self.cur.fetchone()[0] self.index[item_id].fulltext.append( os.path.join(self.storage_path, key, item_attachment)) # If the attachment is linked, it is simply the full # path to the attachment else: self.index[item_id].fulltext.append(att) self.cur.close() print(u"libzotero.update(): indexing completed in %.3fs" % (time.time() - t)) return True