def handle_response(self, response, commit=True): ''' handle the response from self.presenter.start() in self.start() ''' not_ok_msg = 'Are you sure you want to lose your changes?' self._return = None self.clean_model() if response == gtk.RESPONSE_OK or response in self.ok_responses: try: self._return = self.model if self.presenter.dirty() and commit: self.commit_changes() except DBAPIError, e: msg = _('Error committing changes.\n\n%s') % \ utils.xml_safe(unicode(e.orig)) utils.message_details_dialog(msg, str(e), gtk.MESSAGE_ERROR) self.session.rollback() return False except Exception, e: msg = _('Unknown error when committing changes. See the ' 'details for more information.\n\n%s') %\ utils.xml_safe(e) logger.debug(traceback.format_exc()) utils.message_details_dialog(msg, traceback.format_exc(), gtk.MESSAGE_ERROR) self.session.rollback() return False
def update(self, row): ''' ''' self.current_obj = row acc_code = str(row.accession) plant_code = str(row) head, tail = plant_code[:len(acc_code)], plant_code[len(acc_code):] self.set_widget_value('acc_code_data', '<big>%s</big>' % \ utils.xml_safe(unicode(head)), markup=True) self.set_widget_value('plant_code_data', '<big>%s</big>' % \ utils.xml_safe(unicode(tail)), markup=True) self.set_widget_value('name_data', row.accession.species_str(markup=True), markup=True) self.set_widget_value('location_data', str(row.location)) self.set_widget_value('quantity_data', row.quantity) status_str = _('Alive') if row.quantity <= 0: status_str = _('Dead') self.set_widget_value('status_data', status_str, False) self.set_widget_value('type_data', acc_type_values[row.acc_type], False) image_size = gtk.ICON_SIZE_MENU stock = gtk.STOCK_NO if row.memorial: stock = gtk.STOCK_YES self.widgets.memorial_image.set_from_stock(stock, image_size)
def remove_callback(genera): """ The callback function to remove a genus from the genus context menu. """ genus = genera[0] from bauble.plugins.plants.species_model import Species session = db.Session() nsp = session.query(Species).filter_by(genus_id=genus.id).count() safe_str = utils.xml_safe(str(genus)) if nsp > 0: msg = (_('The genus <i>%(genus)s</i> has %(num_species)s species. ' 'Are you sure you want to remove it?') % dict(genus=safe_str, num_species=nsp)) else: msg = (_("Are you sure you want to remove the genus <i>%s</i>?") % safe_str) if not utils.yes_no_dialog(msg): return try: obj = session.query(Genus).get(genus.id) session.delete(obj) session.commit() except Exception, e: msg = _('Could not delete.\n\n%s') % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def search_view_markup_pair(self): """provide the two lines describing object for SearchView row. """ if self.description is not None: return (utils.xml_safe(str(self)), utils.xml_safe(str(self.description))) else: return utils.xml_safe(str(self))
def remove_callback(families): """ The callback function to remove a family from the family context menu. """ family = families[0] from bauble.plugins.plants.genus import Genus session = db.Session() ngen = session.query(Genus).filter_by(family_id=family.id).count() safe_str = utils.xml_safe(str(family)) if ngen > 0: msg = _('The family <i>%(family)s</i> has %(num_genera)s genera. Are ' 'you sure you want to remove it?') % dict(family=safe_str, num_genera=ngen) else: msg = _("Are you sure you want to remove the family <i>%s</i>?") \ % safe_str if not utils.yes_no_dialog(msg): return try: obj = session.query(Family).get(family.id) session.delete(obj) session.commit() except Exception, e: msg = _('Could not delete.\n\n%s') % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def handle_response(self, response): """ @return: return True if the editor is ready to be closed, False if we want to keep editing, if any changes are committed they are stored in self._committed """ # TODO: need to do a __cleanup_model before the commit to do things # like remove the insfraspecific information that's attached to the # model if the infraspecific rank is None not_ok_msg = 'Are you sure you want to lose your changes?' if response == gtk.RESPONSE_OK or response in self.ok_responses: try: if self.presenter.is_dirty(): self.commit_changes() self._committed.append(self.model) except DBAPIError, e: msg = _('Error committing changes.\n\n%s') % \ utils.xml_safe(e.orig) logger.debug(traceback.format_exc()) utils.message_details_dialog(msg, str(e), gtk.MESSAGE_ERROR) return False except Exception, e: msg = _('Unknown error when committing changes. See the ' 'details for more information.\n\n%s') % \ utils.xml_safe(e) logger.debug(traceback.format_exc()) utils.message_details_dialog(msg, traceback.format_exc(), gtk.MESSAGE_ERROR) return False
def remove_callback(values): """ The callback function to remove a species from the species context menu. """ from bauble.plugins.garden.accession import Accession session = db.Session() species = values[0] if isinstance(species, VernacularName): species = species.species nacc = session.query(Accession).filter_by(species_id=species.id).count() safe_str = utils.xml_safe(str(species)) if nacc > 0: msg = _('The species <i>%(species)s</i> has %(num_accessions)s ' 'accessions. Are you sure you want remove it?') \ % dict(species=safe_str, num_accessions=nacc) else: msg = _("Are you sure you want to remove the species <i>%s</i>?") \ % safe_str if not utils.yes_no_dialog(msg): return try: obj = session.query(Species).get(species.id) session.delete(obj) session.commit() except Exception, e: msg = _('Could not delete.\n\n%s') % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def remove_callback(values): """ The callback function to remove a species from the species context menu. """ from bauble.plugins.garden.accession import Accession session = db.Session() species = values[0] if isinstance(species, VernacularName): species = species.species nacc = session.query(Accession).filter_by(species_id=species.id).count() safe_str = utils.xml_safe(str(species)) if nacc > 0: msg = _( "The species <i>%(species)s</i> has %(num_accessions)s " "accessions. Are you sure you want remove it?" ) % dict(species=safe_str, num_accessions=nacc) else: msg = _("Are you sure you want to remove the species <i>%s</i>?") % safe_str if not utils.yes_no_dialog(msg): return try: obj = session.query(Species).get(species.id) session.delete(obj) session.commit() except Exception, e: msg = _("Could not delete.\n\n%s") % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def search_view_markup_pair(self): '''provide the two lines describing object for SearchView row. ''' if self.description is not None: return (utils.xml_safe(str(self)), utils.xml_safe(str(self.description))) else: return utils.xml_safe(str(self))
def get_Notes(self): if not self.plant.notes: return None notes = [] for note in self.plant.notes: notes.append(dict(date=utils.xml_safe(note.date.isoformat()), user=utils.xml_safe(note.user), category=utils.xml_safe(note.category), note=utils.xml_safe(note.note))) return utils.xml_safe(str(notes))
def get_Notes(self): if not self.accession.notes: return None notes = [] for note in self.accession.notes: notes.append(dict(date=xml_safe(note.date.isoformat()), user=xml_safe(note.user), category=xml_safe(note.category), note=xml_safe(note.note))) return xml_safe(notes)
def get_Notes(self): if not self.plant.notes: return None notes = [] for note in self.plant.notes: notes.append( dict(date=utils.xml_safe(note.date.isoformat()), user=utils.xml_safe(note.user), category=utils.xml_safe(note.category), note=utils.xml_safe(note.note))) return utils.xml_safe(str(notes))
def get_Notes(self): if not self.accession.notes: return None notes = [] for note in self.accession.notes: notes.append( dict(date=xml_safe(note.date.isoformat()), user=xml_safe(note.user), category=xml_safe(note.category), note=xml_safe(note.note))) return xml_safe(notes)
def update(self, row): ''' update the expander :param row: the row to get the values from ''' session = db.Session() self.current_obj = row self.widget_set_value('gen_name_data', '<big>%s</big> %s' % (row, utils.xml_safe(unicode(row.author))), markup=True) self.widget_set_value('gen_fam_data', (utils.xml_safe(unicode(row.family)))) # get the number of species nsp = (session.query(Species). join('genus'). filter_by(id=row.id).count()) self.widget_set_value('gen_nsp_data', nsp) # stop here if no GardenPlugin if 'GardenPlugin' not in pluginmgr.plugins: return from bauble.plugins.garden.accession import Accession from bauble.plugins.garden.plant import Plant # get number of accessions nacc = (session.query(Accession). join('species', 'genus'). filter_by(id=row.id).count()) if nacc == 0: self.widget_set_value('gen_nacc_data', nacc) else: nsp_in_acc = (session.query(Accession.species_id). join('species', 'genus'). filter_by(id=row.id).distinct().count()) self.widget_set_value('gen_nacc_data', '%s in %s species' % (nacc, nsp_in_acc)) # get the number of plants in the genus nplants = (session.query(Plant). join('accession', 'species', 'genus'). filter_by(id=row.id).count()) if nplants == 0: self.widget_set_value('gen_nplants_data', nplants) else: nacc_in_plants = (session.query(Plant.accession_id). join('accession', 'species', 'genus'). filter_by(id=row.id).distinct().count()) self.widget_set_value('gen_nplants_data', '%s in %s accessions' % (nplants, nacc_in_plants)) session.close()
def source_detail_remove_callback(details): detail = details[0] s = "%s: %s" % (detail.__class__.__name__, str(detail)) msg = _("Are you sure you want to remove %s?") % utils.xml_safe(s) if not utils.yes_no_dialog(msg): return try: session = db.Session() obj = session.query(SourceDetail).get(detail.id) session.delete(obj) session.commit() except Exception, e: msg = _("Could not delete.\n\n%s") % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def __export_task(self, path, one_file=True): if not one_file: tableset_el = etree.Element('tableset') for table_name, table in db.metadata.tables.iteritems(): if one_file: tableset_el = etree.Element('tableset') logger.info('exporting %s...' % table_name) table_el = ElementFactory(tableset_el, 'table', attrib={'name': table_name}) results = table.select().execute().fetchall() columns = table.c.keys() try: for row in results: row_el = ElementFactory(table_el, 'row') for col in columns: ElementFactory(row_el, 'column', attrib={'name': col}, text=row[col]) except ValueError, e: utils.message_details_dialog(utils.xml_safe(e), traceback.format_exc(), gtk.MESSAGE_ERROR) return else: if one_file: tree = etree.ElementTree(tableset_el) filename = os.path.join(path, '%s.xml' % table_name) # TODO: can figure out why this keeps crashing tree.write(filename, encoding='utf8', xml_declaration=True)
def on_key_released(self, widget, event): ''' if the user hits the delete key on a selected tag in the tag editor then delete the tag ''' keyname = gtk.gdk.keyval_name(event.keyval) if keyname != "Delete": return model, row_iter = self.tag_tree.get_selection().get_selected() tag_name = model[row_iter][1] msg = _('Are you sure you want to delete the tag "%s"?') % tag_name if not utils.yes_no_dialog(msg): return session = db.Session() try: query = session.query(Tag) tag = query.filter_by(tag=unicode(tag_name)).one() session.delete(tag) session.commit() model.remove(row_iter) _reset_tags_menu() view = bauble.gui.get_view() if hasattr(view, 'update'): view.update() except Exception, e: utils.message_details_dialog(utils.xml_safe(str(e)), traceback.format_exc(), gtk.MESSAGE_ERROR)
def source_detail_remove_callback(details): detail = details[0] s = '%s: %s' % (detail.__class__.__name__, str(detail)) msg = _("Are you sure you want to remove %s?") % utils.xml_safe(s) if not utils.yes_no_dialog(msg): return try: session = db.Session() obj = session.query(SourceDetail).get(detail.id) session.delete(obj) session.commit() except Exception, e: msg = _('Could not delete.\n\n%s') % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def run(self, filenames, metadata, force=False): ''' A generator method for importing filenames into the database. This method periodically yields control so that the GUI can update. :param filenames: :param metadata: :param force: default=False ''' transaction = None connection = None self.__error_exc = BaubleError(_('Unknown Error.')) try: # user a contextual connect in case whoever called this # method called it inside a transaction then we can pick # up the parent connection and the transaction connection = metadata.bind.connect() transaction = connection.begin() except Exception, e: msg = _('Error connecting to database.\n\n%s') % \ utils.xml_safe(e) utils.message_dialog(msg, gtk.MESSAGE_ERROR) return
def on_remove_button_clicked(self, button, data=None): """ Removes the currently selected vernacular name from the view. """ tree = self.view.widgets.vern_treeview path, col = tree.get_cursor() treemodel = tree.get_model() vn = treemodel[path][0] msg = _('Are you sure you want to remove the vernacular ' 'name <b>%s</b>?') % utils.xml_safe(vn.name) if vn.name and not vn in self.session.new and not \ utils.yes_no_dialog(msg, parent=self.view.get_window()): return treemodel.remove(treemodel.get_iter(path)) self.model.vernacular_names.remove(vn) utils.delete_or_expunge(vn) if not self.model.default_vernacular_name: # if there is only one value in the tree then set it as the # default vernacular name first = treemodel.get_iter_first() if first: # self.set_model_attr('default_vernacular_name', # tree_model[first][0]) self.model.default_vernacular_name = treemodel[first][0] self.parent_ref().refresh_sensitivity() self._dirty = True
def on_activate(item, cb): result = False try: # have to get the selected values again here # because for some unknown reason using the # "selected" variable from the parent scope # will give us the objects but they won't be # in an session...maybe it's a thread thing values = self.get_selected_values() result = cb(values) except Exception, e: msg = utils.xml_safe(str(e)) tb = utils.xml_safe(traceback.format_exc()) utils.message_details_dialog( msg, tb, gtk.MESSAGE_ERROR) logger.warning(traceback.format_exc())
def on_activate(item, cb): result = False try: # have to get the selected values again here # because for some unknown reason using the # "selected" variable from the parent scope # will give us the objects but they won't be # in an session...maybe it's a thread thing values = self.get_selected_values() result = cb(values) except Exception, e: msg = utils.xml_safe(str(e)) tb = utils.xml_safe(traceback.format_exc()) utils.message_details_dialog(msg, tb, gtk.MESSAGE_ERROR) logger.warning(traceback.format_exc())
def search_view_markup_pair(self): '''provide the two lines describing object for SearchView row. ''' import inspect logging.debug('entering search_view_markup_pair %s, %s' % (self, str(inspect.stack()[1]))) objects = self.objects classes = set(type(o) for o in objects) if len(classes) == 1: fine_prints = "tagging %(1)s objects of type %(2)s" % { '1': len(objects), '2': classes.pop().__name__ } elif len(classes) == 0: fine_prints = "tagging nothing" else: fine_prints = "tagging %(1)s objects of %(2)s different types" % { '1': len(objects), '2': len(classes) } if len(classes) < 4: fine_prints += ': ' + (', '.join(t.__name__ for t in classes)) first = '%s - <span weight="light">%s</span>' % (utils.xml_safe(self), fine_prints) second = '(%s) - <span weight="light">%s</span>' % ( type(self).__name__, (self.description or '').replace('\n', ' ')[:256]) return first, second
def search_view_markup_pair(self): '''provide the two lines describing object for SearchView row. ''' import inspect logging.debug('entering search_view_markup_pair %s, %s' % ( self, str(inspect.stack()[1]))) objects = self.objects classes = set(type(o) for o in objects) if len(classes) == 1: fine_prints = "tagging %(1)s objects of type %(2)s" % { '1': len(objects), '2': classes.pop().__name__} elif len(classes) == 0: fine_prints = "tagging nothing" else: fine_prints = "tagging %(1)s objects of %(2)s different types" % { '1': len(objects), '2': len(classes)} if len(classes) < 4: fine_prints += ': ' + (', '.join( t.__name__ for t in classes)) first = '%s - <span weight="light">%s</span>' % ( utils.xml_safe(self), fine_prints) second = '(%s) - <span weight="light">%s</span>' % ( type(self).__name__, (self.description or '').replace('\n', ' ')[:256]) return first, second
def init(force=False): """ Initialize the plugin manager. 1. Check for and install any plugins in the plugins dict that aren't in the registry. 2. Call each init() for each plugin the registry in order of dependency 3. Register the command handlers in the plugin's commands[] NOTE: This should be called after after Bauble has established a connection to a database with db.open() """ logger.debug('bauble.pluginmgr.init()') # ****** # NOTE: Be careful not to keep any references to # PluginRegistry open here as it will cause a deadlock if you try # to create a new database. For example, don't query the # PluginRegistry with a session without closing the session. # ****** # search for plugins that are in the plugins dict but not in the registry registered = plugins.values() logger.debug('registered plugins: %s' % plugins) try: # try to access the plugin registry, if the table does not exist # then it might mean that we are opening a pre 0.9 database, in this # case we just assume all the plugins have been installed and # registered, this might be the right thing to do but at least it # allows you to connect to a pre bauble 0.9 database and use it to # upgrade to a >=0.9 database registered_names = PluginRegistry.names() not_installed = [ p for n, p in plugins.iteritems() if n not in registered_names ] if len(not_installed) > 0: msg = _('The following plugins were not found in the plugin ' 'registry:\n\n<b>%s</b>\n\n' '<i>Would you like to install them now?</i>' % ', '.join([p.__class__.__name__ for p in not_installed])) if force or utils.yes_no_dialog(msg): install([p for p in not_installed]) # sort plugins in the registry by their dependencies not_registered = [] for name in PluginRegistry.names(): try: registered.append(plugins[name]) except KeyError, e: logger.debug("could not find '%s' plugin. " "removing from database" % e) not_registered.append(utils.utf8(name)) PluginRegistry.remove(name=name) if not_registered: msg = _('The following plugins are in the registry but ' 'could not be loaded:\n\n%(plugins)s' % {'plugins': utils.utf8(', '.join(sorted(not_registered)))}) utils.message_dialog(utils.xml_safe(msg), type=gtk.MESSAGE_WARNING)
def update(self, row): # from textwrap import TextWrapper # wrapper = TextWrapper(width=50, subsequent_indent=' ') self.set_widget_value("sd_name_data", "<big>%s</big>" % utils.xml_safe(row.name), markup=True) source_type = "" if row.source_type: source_type = utils.xml_safe(row.source_type) self.set_widget_value("sd_type_data", source_type) description = "" if row.description: description = utils.xml_safe(row.description) self.set_widget_value("sd_desc_data", description) source = Source.__table__ nacc = select([source.c.id], source.c.source_detail_id == row.id).count().execute().fetchone()[0] self.set_widget_value("sd_nacc_data", nacc)
def extra_elements(self, unit): bg_unit = ABCDElement(unit, 'BotanicalGardenUnit') ABCDElement(bg_unit, 'AccessionSpecimenNumbers', text=utils.xml_safe(self.plant.quantity)) ABCDElement(bg_unit, 'LocationInGarden', text=utils.xml_safe(str(self.plant.location))) if self.for_labels: if self.species.label_distribution: etree.SubElement(unit, 'distribution').text = \ self.species.label_distribution elif self.species.distribution: etree.SubElement(unit, 'distribution').text = \ self.species.distribution_str() # TODO: AccessionStatus, AccessionMaterialtype, # ProvenanceCategory, AccessionLineage, DonorCategory, # PlantingDate, Propagation super(PlantABCDAdapter, self).extra_elements(unit)
def init(force=False): """ Initialize the plugin manager. 1. Check for and install any plugins in the plugins dict that aren't in the registry. 2. Call each init() for each plugin the registry in order of dependency 3. Register the command handlers in the plugin's commands[] NOTE: This is called after after Ghini has created the GUI and established a connection to a database with db.open() """ logger.debug('bauble.pluginmgr.init()') # ****** # NOTE: Be careful not to keep any references to # PluginRegistry open here as it will cause a deadlock if you try # to create a new database. For example, don't query the # PluginRegistry with a session without closing the session. # ****** # search for plugins that are in the plugins dict but not in the registry registered = plugins.values() logger.debug('registered plugins: %s' % plugins) try: # try to access the plugin registry, if the table does not exist # then it might mean that we are opening a pre 0.9 database, in this # case we just assume all the plugins have been installed and # registered, this might be the right thing to do but at least it # allows you to connect to a pre bauble 0.9 database and use it to # upgrade to a >=0.9 database registered_names = PluginRegistry.names() not_installed = [p for n, p in plugins.iteritems() if n not in registered_names] if len(not_installed) > 0: msg = _('The following plugins were not found in the plugin ' 'registry:\n\n<b>%s</b>\n\n' '<i>Would you like to install them now?</i>') % \ ', '.join([p.__class__.__name__ for p in not_installed]) if force or utils.yes_no_dialog(msg): install([p for p in not_installed]) # sort plugins in the registry by their dependencies not_registered = [] for name in PluginRegistry.names(): try: registered.append(plugins[name]) except KeyError, e: logger.debug("could not find '%s' plugin. " "removing from database" % e) not_registered.append(utils.utf8(name)) PluginRegistry.remove(name=name) if not_registered: msg = _('The following plugins are in the registry but ' 'could not be loaded:\n\n%(plugins)s') % \ {'plugins': utils.utf8(', '.join(sorted(not_registered)))} utils.message_dialog(utils.xml_safe(msg), type=gtk.MESSAGE_WARNING)
def remove_callback(locations): loc = locations[0] s = "%s: %s" % (loc.__class__.__name__, str(loc)) if len(loc.plants) > 0: msg = _("Please remove the plants from <b>%(location)s</b> " "before deleting it.") % {"location": loc} utils.message_dialog(msg, gtk.MESSAGE_WARNING) return msg = _("Are you sure you want to remove %s?") % utils.xml_safe(s) if not utils.yes_no_dialog(msg): return try: session = db.Session() obj = session.query(Location).get(loc.id) session.delete(obj) session.commit() except Exception, e: msg = _("Could not delete.\n\n%s") % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def update(self, row): """ """ from bauble.plugins.garden.plant import Plant self.widget_set_value("loc_name_data", "<big>%s</big>" % utils.xml_safe(str(row)), markup=True) session = object_session(row) nplants = session.query(Plant).filter_by(location_id=row.id).count() self.widget_set_value("loc_nplants_data", nplants)
def remove_callback(tags): """ :param tags: a list of :class:`Tag` objects. """ tag = tags[0] s = '%s: %s' % (tag.__class__.__name__, utils.xml_safe(tag)) msg = _("Are you sure you want to remove %s?") % s if not utils.yes_no_dialog(msg): return session = object_session(tag) try: obj = session.query(Tag).get(tag.id) session.delete(obj) session.commit() except Exception, e: msg = _('Could not delete.\n\n%s') % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def remove_callback(tags): """ :param tags: a list of :class:`Tag` objects. """ tag = tags[0] s = '%s: %s' % (tag.__class__.__name__, utils.xml_safe(tag)) msg = _("Are you sure you want to remove %s?") % s if not utils.yes_no_dialog(msg): return session = db.Session() try: obj = session.query(Tag).get(tag.id) session.delete(obj) session.commit() except Exception, e: msg = _('Could not delete.\n\n%s') % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def on_tools_menu_item_activate(self, widget, tool): """ Start a tool on the Tool menu. """ try: tool.start() except Exception, e: utils.message_details_dialog(utils.xml_safe(str(e)), traceback.format_exc(), gtk.MESSAGE_ERROR) logger.debug(traceback.format_exc())
def update(self, row): ''' ''' from bauble.plugins.garden.plant import Plant self.widget_set_value('loc_name_data', '<big>%s</big>' % utils.xml_safe(str(row)), markup=True) session = object_session(row) nplants = session.query(Plant).filter_by(location_id=row.id).count() self.widget_set_value('loc_nplants_data', nplants)
def syn_cell_data_func(column, renderer, model, iter, data=None): ''' ''' v = model[iter][0] author = None if v.author is None: author = '' else: author = utils.xml_safe(unicode(v.author)) renderer.set_property('markup', '<i>%s</i> %s (<small>%s</small>)' % (Genus.str(v), author, Family.str(v.family)))
def update(self, row): #from textwrap import TextWrapper #wrapper = TextWrapper(width=50, subsequent_indent=' ') self.widget_set_value('sd_name_data', '<big>%s</big>' % utils.xml_safe(row.name), markup=True) source_type = '' if row.source_type: source_type = utils.xml_safe(row.source_type) self.widget_set_value('sd_type_data', source_type) description = '' if row.description: description = utils.xml_safe(row.description) self.widget_set_value('sd_desc_data', description) source = Source.__table__ nacc = select([source.c.id], source.c.source_detail_id == row.id).\ count().execute().fetchone()[0] self.widget_set_value('sd_nacc_data', nacc)
def _syn_data_func(column, cell, model, iter, data=None): v = model[iter][0] syn = v.synonym cell.set_property('markup', '<i>%s</i> %s (<small>%s</small>)' % (Genus.str(syn), utils.xml_safe(unicode(syn.author)), Family.str(syn.family))) # set background color to indicate it's new if v.id is None: cell.set_property('foreground', 'blue') else: cell.set_property('foreground', None)
def cell_data_func(self, col, cell, model, treeiter): path = model.get_path(treeiter) tree_rect = self.results_view.get_visible_rect() cell_rect = self.results_view.get_cell_area(path, col) if cell_rect.y > tree_rect.height: # only update the cells if they're visible...this # drastically speeds up populating the view with large # datasets return value = model[treeiter][0] if isinstance(value, basestring): cell.set_property('markup', value) else: # if the value isn't part of a session then add it to the # view's session so that we can access its child # properties...this usually happens when one of the # ViewMeta's get_children() functions return a list of # object who's session was closed...we add it here for # performance reasons so we only add it once it's visible if not object_session(value): if value in self.session: # expire the object in the session with the same key self.session.expire(value) else: self.session.add(value) try: func = self.view_meta[type(value)].markup_func if func is not None: r = func(value) if isinstance(r, (list, tuple)): main, substr = r else: main = r substr = '(%s)' % type(value).__name__ else: main = utils.xml_safe(str(value)) substr = '(%s)' % type(value).__name__ cell.set_property( 'markup', '%s\n%s' % (_mainstr_tmpl % utils.utf8(main), _substr_tmpl % utils.utf8(substr))) except (saexc.InvalidRequestError, TypeError), e: logger.warning( 'bauble.view.SearchView.cell_data_func(): \n%s' % e) def remove(): model = self.results_view.get_model() self.results_view.set_model(None) # detach model for found in utils.search_tree_model(model, value): model.remove(found) self.results_view.set_model(model) gobject.idle_add(remove)
def _syn_data_func(column, cell, model, iter, data=None): v = model[iter][0] syn = v.synonym cell.set_property( 'markup', '<i>%s</i> %s (<small>%s</small>)' % (Genus.str(syn), utils.xml_safe(unicode( syn.author)), Family.str(syn.family))) # set background color to indicate it's new if v.id is None: cell.set_property('foreground', 'blue') else: cell.set_property('foreground', None)
def handle_response(self, response): """ handle the response from self.presenter.start() in self.start() """ not_ok_msg = _("Are you sure you want to lose your changes?") if response == gtk.RESPONSE_OK or response in self.ok_responses: try: if self.presenter.dirty(): self.commit_changes() self._committed.append(self.model) except DBAPIError, e: msg = _("Error committing changes.\n\n%s" % utils.xml_safe(e.orig)) utils.message_details_dialog(msg, str(e), gtk.MESSAGE_ERROR) return False except Exception, e: msg = _( "Unknown error when committing changes. See the " "details for more information.\n\n%s" % utils.xml_safe(e) ) utils.message_details_dialog(msg, traceback.format_exc(), gtk.MESSAGE_ERROR) return False
def remove_callback(locations): loc = locations[0] s = '%s: %s' % (loc.__class__.__name__, str(loc)) if len(loc.plants) > 0: msg = _('Please remove the plants from <b>%(location)s</b> ' 'before deleting it.') % {'location': loc} utils.message_dialog(msg, gtk.MESSAGE_WARNING) return msg = _("Are you sure you want to remove %s?") % \ utils.xml_safe(s) if not utils.yes_no_dialog(msg): return try: session = db.Session() obj = session.query(Location).get(loc.id) session.delete(obj) session.commit() except Exception, e: msg = _('Could not delete.\n\n%s') % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), type=gtk.MESSAGE_ERROR)
def on_file_menu_new(self, widget, data=None): msg = "If a database already exists at this connection then creating "\ "a new database could destroy your data.\n\n<i>Are you sure "\ "this is what you want to do?</i>" if not utils.yes_no_dialog(msg, yes_delay=2): return #if gui is not None and hasattr(gui, 'insert_menu'): submenu = self.insert_menu.get_submenu() for c in submenu.get_children(): submenu.remove(c) self.insert_menu.show() try: db.create() pluginmgr.init() except Exception, e: msg = _('Could not create a new database.\n\n%s') % \ utils.xml_safe(e) tb = utils.xml_safe(traceback.format_exc()) utils.message_details_dialog(msg, tb, gtk.MESSAGE_ERROR) return
def handle_response(self, response): ''' handle the response from self.presenter.start() in self.start() ''' not_ok_msg = _('Are you sure you want to lose your changes?') if response == gtk.RESPONSE_OK or response in self.ok_responses: try: if self.presenter.dirty(): self.commit_changes() self._committed.append(self.model) except DBAPIError, e: msg = _('Error committing changes.\n\n%s') % \ utils.xml_safe(e.orig) utils.message_details_dialog(msg, str(e), gtk.MESSAGE_ERROR) return False except Exception, e: msg = _('Unknown error when committing changes. See the ' 'details for more information.\n\n%s') % \ utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), gtk.MESSAGE_ERROR) return False
def handle_response(self, response): """ @return: return a list if we want to tell start() to close the editor, the list should either be empty or the list of committed values, return None if we want to keep editing """ not_ok_msg = "Are you sure you want to lose your changes?" if response == gtk.RESPONSE_OK or response in self.ok_responses: try: if self.presenter.dirty(): self.commit_changes() self._committed.append(self.model) except DBAPIError, e: msg = _("Error committing changes.\n\n%s") % utils.xml_safe(e.orig) utils.message_details_dialog(msg, str(e), gtk.MESSAGE_ERROR) return False except Exception, e: msg = _( "Unknown error when committing changes. See the " "details for more information.\n\n%s" ) % utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), gtk.MESSAGE_ERROR) return False
def load(path=None): """ Search the plugin path for modules that provide a plugin. If path is a directory then search the directory for plugins. If path is None then use the default plugins path, bauble.plugins. This method populates the pluginmgr.plugins dict and imports the plugins but doesn't do any plugin initialization. :param path: the path where to look for the plugins :type path: str """ if path is None: if bauble.main_is_frozen(): #path = os.path.join(paths.lib_dir(), 'library.zip') path = os.path.join(paths.main_dir(), 'library.zip') else: path = os.path.join(paths.lib_dir(), 'plugins') logger.debug('pluginmgr.load(%s)' % path) found, errors = _find_plugins(path) logger.debug('found=%s, errors=%s' % (found, errors)) # show error dialog for plugins that couldn't be loaded...we only # give details for the first error and assume the others are the # same...and if not then it doesn't really help anyways if errors: name = ', '.join(sorted(errors.keys())) exc_info = errors.values()[0] exc_str = utils.xml_safe(exc_info[1]) tb_str = ''.join(traceback.format_tb(exc_info[2])) utils.message_details_dialog('Could not load plugin: ' '\n\n<i>%s</i>\n\n%s' % (name, exc_str), tb_str, type=gtk.MESSAGE_ERROR) if len(found) == 0: logger.debug('No plugins found at path: %s' % path) for plugin in found: # issue #27: should we include the module name of the plugin to # allow for plugin namespaces or just assume that the plugin class # name is unique? if isinstance(plugin, (type, types.ClassType)): plugins[plugin.__name__] = plugin logger.debug("registering plugin %s: %s" % (plugin.__name__, plugin)) else: plugins[plugin.__class__.__name__] = plugin logger.debug("registering plugin %s: %s" % (plugin.__class__.__name__, plugin))
def handle_response(self, response): ''' @return: return a list if we want to tell start() to close the editor, the list should either be empty or the list of committed values, return None if we want to keep editing ''' not_ok_msg = 'Are you sure you want to lose your changes?' if response == gtk.RESPONSE_OK or response in self.ok_responses: try: if self.presenter.dirty(): self.commit_changes() self._committed.append(self.model) except DBAPIError, e: msg = _('Error committing changes.\n\n%s') % \ utils.xml_safe(e.orig) utils.message_details_dialog(msg, str(e), gtk.MESSAGE_ERROR) return False except Exception, e: msg = _('Unknown error when committing changes. See the ' 'details for more information.\n\n%s') % \ utils.xml_safe(e) utils.message_details_dialog(msg, traceback.format_exc(), gtk.MESSAGE_ERROR) return False