GEP 18: Deprecate EditCitation
svn: r22486
This commit is contained in:
@@ -137,8 +137,7 @@ class BackRefList(EmbeddedList):
|
|||||||
def edit_button_clicked(self, obj):
|
def edit_button_clicked(self, obj):
|
||||||
|
|
||||||
from .. import EditEvent, EditPerson, EditFamily, EditSource, \
|
from .. import EditEvent, EditPerson, EditFamily, EditSource, \
|
||||||
EditPlace, EditMedia, EditRepository, \
|
EditPlace, EditMedia, EditRepository
|
||||||
EditCitation
|
|
||||||
|
|
||||||
(reftype, ref) = self.find_node()
|
(reftype, ref) = self.find_node()
|
||||||
if reftype == 'Person':
|
if reftype == 'Person':
|
||||||
@@ -162,7 +161,9 @@ class BackRefList(EmbeddedList):
|
|||||||
elif reftype == 'Citation':
|
elif reftype == 'Citation':
|
||||||
try:
|
try:
|
||||||
citation = self.dbstate.db.get_citation_from_handle(ref)
|
citation = self.dbstate.db.get_citation_from_handle(ref)
|
||||||
EditCitation(self.dbstate, self.uistate, [], citation)
|
EditSource(self.dbstate, self.uistate, [],
|
||||||
|
self.dbstate.db.get_source_from_handle(
|
||||||
|
citation.get_reference_handle()), citation)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
"""
|
"""
|
||||||
Return the text used when citation cannot be edited
|
Return the text used when citation cannot be edited
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
|
|||||||
|
|
||||||
def add_button_clicked(self, obj):
|
def add_button_clicked(self, obj):
|
||||||
"""
|
"""
|
||||||
Create a new Citation instance and call the EditCitation editor with
|
Create a new Citation instance and call the EditSource editor with
|
||||||
the new citation.
|
the new citation.
|
||||||
|
|
||||||
Called when the Add button is clicked.
|
Called when the Add button is clicked.
|
||||||
@@ -136,9 +136,9 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
|
|||||||
This prevents the dialog from coming up twice on the same object.
|
This prevents the dialog from coming up twice on the same object.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
from .. import EditCitation
|
from .. import EditSource
|
||||||
EditCitation(self.dbstate, self.uistate, self.track,
|
EditSource(self.dbstate, self.uistate, self.track,
|
||||||
Citation(), Source(),
|
Source(), Citation(),
|
||||||
self.add_callback, self.callertitle)
|
self.add_callback, self.callertitle)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
pass
|
pass
|
||||||
@@ -164,9 +164,9 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
|
|||||||
if object:
|
if object:
|
||||||
if isinstance(object, Source):
|
if isinstance(object, Source):
|
||||||
try:
|
try:
|
||||||
from .. import EditCitation
|
from .. import EditSource
|
||||||
EditCitation(self.dbstate, self.uistate, self.track,
|
EditSource(self.dbstate, self.uistate, self.track,
|
||||||
Citation(), object,
|
object, Citation(),
|
||||||
callback=self.add_callback,
|
callback=self.add_callback,
|
||||||
callertitle=self.callertitle)
|
callertitle=self.callertitle)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
@@ -175,10 +175,12 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
|
|||||||
self.__blocked_text())
|
self.__blocked_text())
|
||||||
elif isinstance(object, Citation):
|
elif isinstance(object, Citation):
|
||||||
try:
|
try:
|
||||||
from .. import EditCitation
|
from .. import EditSource
|
||||||
EditCitation(self.dbstate, self.uistate, self.track,
|
EditSource(self.dbstate, self.uistate, self.track,
|
||||||
object, callback=self.add_callback,
|
self.dbstate.db.get_source_from_handle(
|
||||||
callertitle=self.callertitle)
|
object.get_reference_handle()), object,
|
||||||
|
callback=self.add_callback,
|
||||||
|
callertitle=self.callertitle)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
from ...dialog import WarningDialog
|
from ...dialog import WarningDialog
|
||||||
WarningDialog(_("Cannot share this reference"),
|
WarningDialog(_("Cannot share this reference"),
|
||||||
@@ -198,7 +200,7 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
|
|||||||
|
|
||||||
def edit_button_clicked(self, obj):
|
def edit_button_clicked(self, obj):
|
||||||
"""
|
"""
|
||||||
Get the selected Citation instance and call the EditCitation editor
|
Get the selected Citation instance and call the EditSource editor
|
||||||
with the citation.
|
with the citation.
|
||||||
|
|
||||||
Called when the Edit button is clicked.
|
Called when the Edit button is clicked.
|
||||||
@@ -209,9 +211,11 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
|
|||||||
if handle:
|
if handle:
|
||||||
citation = self.dbstate.db.get_citation_from_handle(handle)
|
citation = self.dbstate.db.get_citation_from_handle(handle)
|
||||||
try:
|
try:
|
||||||
from .. import EditCitation
|
from .. import EditSource
|
||||||
EditCitation(self.dbstate, self.uistate, self.track, citation,
|
EditSource(self.dbstate, self.uistate, self.track,
|
||||||
callertitle = self.callertitle)
|
self.dbstate.db.get_source_from_handle(
|
||||||
|
citation.get_reference_handle()), citation,
|
||||||
|
callertitle = self.callertitle)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -248,10 +252,12 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
|
|||||||
object = self.dbstate.db.get_citation_from_handle(handle)
|
object = self.dbstate.db.get_citation_from_handle(handle)
|
||||||
if isinstance(object, Citation):
|
if isinstance(object, Citation):
|
||||||
try:
|
try:
|
||||||
from .. import EditCitation
|
from .. import EditSource
|
||||||
EditCitation(self.dbstate, self.uistate, self.track,
|
EditSource(self.dbstate, self.uistate, self.track,
|
||||||
object, callback=self.add_callback,
|
self.dbstate.db.get_source_from_handle(
|
||||||
callertitle=self.callertitle)
|
object.get_reference_handle()),
|
||||||
|
object, callback=self.add_callback,
|
||||||
|
callertitle=self.callertitle)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
from ...dialog import WarningDialog
|
from ...dialog import WarningDialog
|
||||||
WarningDialog(_("Cannot share this reference"),
|
WarningDialog(_("Cannot share this reference"),
|
||||||
@@ -267,11 +273,11 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
|
|||||||
object = self.dbstate.db.get_source_from_handle(handle)
|
object = self.dbstate.db.get_source_from_handle(handle)
|
||||||
if isinstance(object, Source):
|
if isinstance(object, Source):
|
||||||
try:
|
try:
|
||||||
from .. import EditCitation
|
from .. import EditSource
|
||||||
EditCitation(self.dbstate, self.uistate, self.track,
|
EditSource(self.dbstate, self.uistate, self.track,
|
||||||
Citation(), object,
|
object, Citation(),
|
||||||
callback=self.add_callback,
|
callback=self.add_callback,
|
||||||
callertitle=self.callertitle)
|
callertitle=self.callertitle)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
from ...dialog import WarningDialog
|
from ...dialog import WarningDialog
|
||||||
WarningDialog(_("Cannot share this reference"),
|
WarningDialog(_("Cannot share this reference"),
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ class CitedInTab(GrampsTab):
|
|||||||
return
|
return
|
||||||
|
|
||||||
from .. import (EditEvent, EditPerson, EditFamily, EditPlace,
|
from .. import (EditEvent, EditPerson, EditFamily, EditPlace,
|
||||||
EditMedia, EditRepository, EditCitation)
|
EditMedia, EditRepository)
|
||||||
|
|
||||||
if reftype == 'Person':
|
if reftype == 'Person':
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -101,6 +101,12 @@ class SrcTemplateTab(GrampsTab):
|
|||||||
self.setup_interface(self.glade.get_object('scrolledtemplates'))
|
self.setup_interface(self.glade.get_object('scrolledtemplates'))
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
|
def make_active(self):
|
||||||
|
"""
|
||||||
|
Called by using editor to focus on correct field in the tab
|
||||||
|
"""
|
||||||
|
self.temp_tv.grab_focus()
|
||||||
|
|
||||||
def is_empty(self):
|
def is_empty(self):
|
||||||
"""
|
"""
|
||||||
Override base class
|
Override base class
|
||||||
|
|||||||
@@ -58,8 +58,31 @@ from ..glade import Glade
|
|||||||
# EditCitationclass
|
# EditCitationclass
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
class EditCitation(EditPrimary):
|
class EditCitation(EditPrimary):
|
||||||
|
"""
|
||||||
|
Create an Editor for Citation object. This actually opens the source!
|
||||||
|
|
||||||
|
This class is called both to edit the Citation Primary object
|
||||||
|
and to edit references from other objects to citations.
|
||||||
|
|
||||||
|
@param callertitle: Text passed by calling object to add to title
|
||||||
|
@type callertitle: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, dbstate, uistate, track, citation, callback=None,
|
||||||
|
callertitle = None):
|
||||||
|
from .editsource import EditSource
|
||||||
|
if citation.handle:
|
||||||
|
EditSource(dbstate, uistate, track, dbstate.db.get_source_from_handle(
|
||||||
|
citation.get_reference_handle()), citation,
|
||||||
|
callback, callertitle)
|
||||||
|
else:
|
||||||
|
#we don't allow this, caller should be changed to call EditSource
|
||||||
|
#directly !
|
||||||
|
raise NotImplementedError("Depracated call")
|
||||||
|
|
||||||
|
|
||||||
|
class EditCitationOld(EditPrimary):
|
||||||
"""
|
"""
|
||||||
Create an EditCitation window. Associate a citation with the window.
|
Create an EditCitation window. Associate a citation with the window.
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,21 @@ class EditSource(EditPrimary):
|
|||||||
self.unload_citation()
|
self.unload_citation()
|
||||||
|
|
||||||
self.load_source_image()
|
self.load_source_image()
|
||||||
self.title.grab_focus()
|
if not self.obj.handle:
|
||||||
|
#new source, open on template view, and focus there.
|
||||||
|
self.notebook_src.set_current_pate(self.template_page_nr)
|
||||||
|
self.template_tab.make_active()
|
||||||
|
elif self.citation:
|
||||||
|
#there is a citation!
|
||||||
|
if self.citation.handle:
|
||||||
|
#existing citation!
|
||||||
|
self.notebook_ref.grab_focus()
|
||||||
|
else:
|
||||||
|
#new citation!
|
||||||
|
self.notebook_ref.grab_focus()
|
||||||
|
else:
|
||||||
|
#existing source, no citation
|
||||||
|
self.title.grab_focus()
|
||||||
|
|
||||||
def load_source_image(self):
|
def load_source_image(self):
|
||||||
"""
|
"""
|
||||||
@@ -363,7 +377,8 @@ class EditSource(EditPrimary):
|
|||||||
self.source_text.get_buffer().set_text(ref_text)
|
self.source_text.get_buffer().set_text(ref_text)
|
||||||
|
|
||||||
def _create_tabbed_pages(self):
|
def _create_tabbed_pages(self):
|
||||||
notebook = self.glade.get_object('notebook')
|
self.notebook_src = self.glade.get_object('notebook')
|
||||||
|
notebook = self.notebook_src
|
||||||
gridsrc = self.glade.get_object('gridsrc')
|
gridsrc = self.glade.get_object('gridsrc')
|
||||||
#recreate start page as GrampsTab
|
#recreate start page as GrampsTab
|
||||||
notebook.remove_page(1)
|
notebook.remove_page(1)
|
||||||
@@ -373,6 +388,7 @@ class EditSource(EditPrimary):
|
|||||||
self._add_tab(notebook, self.overviewtab)
|
self._add_tab(notebook, self.overviewtab)
|
||||||
|
|
||||||
#recreate second page as GrampsTab
|
#recreate second page as GrampsTab
|
||||||
|
self.template_page_nr = 1
|
||||||
self.template_tab = SrcTemplateTab(self.dbstate, self.uistate,
|
self.template_tab = SrcTemplateTab(self.dbstate, self.uistate,
|
||||||
self.track, self.obj, self.glade,
|
self.track, self.obj, self.glade,
|
||||||
self.update_template_data
|
self.update_template_data
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ from gramps.gen.errors import WindowActiveError
|
|||||||
from ...widgets.multitreeview import MultiTreeView
|
from ...widgets.multitreeview import MultiTreeView
|
||||||
from ...ddtargets import DdTargets
|
from ...ddtargets import DdTargets
|
||||||
from ..quick import run_quick_report_by_name
|
from ..quick import run_quick_report_by_name
|
||||||
from ...editors import (EditPerson, EditEvent, EditFamily, EditCitation,
|
from ...editors import (EditPerson, EditEvent, EditFamily,
|
||||||
EditSource, EditPlace, EditRepository, EditNote,
|
EditSource, EditPlace, EditRepository, EditNote,
|
||||||
EditMedia)
|
EditMedia)
|
||||||
|
|
||||||
@@ -216,9 +216,11 @@ class QuickTable(SimpleTable):
|
|||||||
elif objclass == 'Citation':
|
elif objclass == 'Citation':
|
||||||
ref = self.access.dbase.get_citation_from_handle(handle)
|
ref = self.access.dbase.get_citation_from_handle(handle)
|
||||||
if ref:
|
if ref:
|
||||||
|
dbstate = self.simpledoc.doc.dbstate
|
||||||
try:
|
try:
|
||||||
EditCitation(self.simpledoc.doc.dbstate,
|
EditSource(dbstate, self.simpledoc.doc.uistate, [],
|
||||||
self.simpledoc.doc.uistate, [], ref)
|
dbstate.db.get_source_from_handle(
|
||||||
|
ref.get_reference_handle()), ref)
|
||||||
return True # handled event
|
return True # handled event
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -304,6 +304,13 @@ class ListView(NavigationView):
|
|||||||
NavigationView.set_inactive(self)
|
NavigationView.set_inactive(self)
|
||||||
self.uistate.viewmanager.tags.tag_disable()
|
self.uistate.viewmanager.tags.tag_disable()
|
||||||
|
|
||||||
|
def grab_focus(self):
|
||||||
|
"""
|
||||||
|
Inherit this method to indicate where to put focus if there is no
|
||||||
|
specific handle in focus
|
||||||
|
"""
|
||||||
|
self.list.grab_focus()
|
||||||
|
|
||||||
def __build_tree(self):
|
def __build_tree(self):
|
||||||
profile(self._build_tree)
|
profile(self._build_tree)
|
||||||
|
|
||||||
|
|||||||
@@ -196,11 +196,21 @@ class NavigationView(PageView):
|
|||||||
self.navigation_group())
|
self.navigation_group())
|
||||||
if active_handle:
|
if active_handle:
|
||||||
self.goto_handle(active_handle)
|
self.goto_handle(active_handle)
|
||||||
|
else:
|
||||||
|
#make the pageview the object with focus, so moving arrow works
|
||||||
|
self.grab_focus()
|
||||||
|
|
||||||
hobj = self.get_history()
|
hobj = self.get_history()
|
||||||
self.fwd_action.set_sensitive(not hobj.at_end())
|
self.fwd_action.set_sensitive(not hobj.at_end())
|
||||||
self.back_action.set_sensitive(not hobj.at_front())
|
self.back_action.set_sensitive(not hobj.at_front())
|
||||||
|
|
||||||
|
def grab_focus(self):
|
||||||
|
"""
|
||||||
|
Inherit this method to indicate where to put focus if there is no
|
||||||
|
specific handle in focus
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def get_active(self):
|
def get_active(self):
|
||||||
"""
|
"""
|
||||||
Return the handle of the active object.
|
Return the handle of the active object.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
|
|
||||||
from gramps.gui.editors import EditSource, EditCitation
|
from gramps.gui.editors import EditSource
|
||||||
from gramps.gui.listmodel import ListModel, NOSORT
|
from gramps.gui.listmodel import ListModel, NOSORT
|
||||||
from gramps.gen.plug import Gramplet
|
from gramps.gen.plug import Gramplet
|
||||||
from gramps.gui.dbguielement import DbGUIElement
|
from gramps.gui.dbguielement import DbGUIElement
|
||||||
@@ -268,7 +268,7 @@ class Citations(Gramplet, DbGUIElement):
|
|||||||
citation = self.dbstate.db.get_citation_from_handle(handle)
|
citation = self.dbstate.db.get_citation_from_handle(handle)
|
||||||
source_handle = citation.get_reference_handle()
|
source_handle = citation.get_reference_handle()
|
||||||
source = self.dbstate.db.get_source_from_handle(source_handle)
|
source = self.dbstate.db.get_source_from_handle(source_handle)
|
||||||
EditCitation(self.dbstate, self.uistate, [], citation, source)
|
EditSource(self.dbstate, self.uistate, [], source, citation)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ from gramps.gui.views.bookmarks import CitationBookmarks
|
|||||||
from gramps.gen.errors import WindowActiveError
|
from gramps.gen.errors import WindowActiveError
|
||||||
from gramps.gui.ddtargets import DdTargets
|
from gramps.gui.ddtargets import DdTargets
|
||||||
from gramps.gui.dialog import ErrorDialog
|
from gramps.gui.dialog import ErrorDialog
|
||||||
from gramps.gui.editors import EditCitation, DeleteCitationQuery
|
from gramps.gui.editors import EditSource, DeleteCitationQuery
|
||||||
from gramps.gui.filters.sidebar import CitationSidebarFilter
|
from gramps.gui.filters.sidebar import CitationSidebarFilter
|
||||||
from gramps.gui.merge import MergeCitation
|
from gramps.gui.merge import MergeCitation
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ class CitationListView(ListView):
|
|||||||
citation to an existing source)
|
citation to an existing source)
|
||||||
|
|
||||||
Create a new Source instance and Citation instance and call the
|
Create a new Source instance and Citation instance and call the
|
||||||
EditCitation editor with the new source and new citation.
|
EditSource editor with the new source and new citation.
|
||||||
|
|
||||||
Called when the Add button is clicked.
|
Called when the Add button is clicked.
|
||||||
If the window already exists (WindowActiveError), we ignore it.
|
If the window already exists (WindowActiveError), we ignore it.
|
||||||
@@ -266,8 +266,7 @@ class CitationListView(ListView):
|
|||||||
window to already exist, so this is just an extra safety measure.
|
window to already exist, so this is just an extra safety measure.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
EditCitation(self.dbstate, self.uistate, [], Citation(),
|
EditSource(self.dbstate, self.uistate, [], Source(), Citation())
|
||||||
Source())
|
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -289,7 +288,9 @@ class CitationListView(ListView):
|
|||||||
for handle in self.selected_handles():
|
for handle in self.selected_handles():
|
||||||
citation = self.dbstate.db.get_citation_from_handle(handle)
|
citation = self.dbstate.db.get_citation_from_handle(handle)
|
||||||
try:
|
try:
|
||||||
EditCitation(self.dbstate, self.uistate, [], citation)
|
EditSource(self.dbstate, self.uistate, [],
|
||||||
|
self.dbstate.db.get_source_from_handle(
|
||||||
|
citation.get_reference_handle()), citation)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ from gramps.gui.views.bookmarks import CitationBookmarks
|
|||||||
from gramps.gen.errors import WindowActiveError
|
from gramps.gen.errors import WindowActiveError
|
||||||
from gramps.gui.ddtargets import DdTargets
|
from gramps.gui.ddtargets import DdTargets
|
||||||
from gramps.gui.dialog import ErrorDialog
|
from gramps.gui.dialog import ErrorDialog
|
||||||
from gramps.gui.editors import EditCitation, DeleteCitationQuery, EditSource, \
|
from gramps.gui.editors import (DeleteCitationQuery, EditSource,
|
||||||
DeleteSrcQuery
|
DeleteSrcQuery)
|
||||||
from gramps.gui.filters.sidebar import SourceSidebarFilter
|
from gramps.gui.filters.sidebar import SourceSidebarFilter
|
||||||
from gramps.gui.merge import MergeCitation, MergeSource
|
from gramps.gui.merge import MergeCitation, MergeSource
|
||||||
|
|
||||||
@@ -400,8 +400,7 @@ class CitationTreeView(ListView):
|
|||||||
window to already exist, so this is just an extra safety measure.
|
window to already exist, so this is just an extra safety measure.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
EditCitation(self.dbstate, self.uistate, [], Citation(),
|
EditSource(self.dbstate, self.uistate, [], Source(), Citation())
|
||||||
Source())
|
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -418,8 +417,8 @@ class CitationTreeView(ListView):
|
|||||||
raise ValueError("selection must be either source or citation")
|
raise ValueError("selection must be either source or citation")
|
||||||
if source:
|
if source:
|
||||||
try:
|
try:
|
||||||
EditCitation(self.dbstate, self.uistate, [],
|
EditSource(self.dbstate, self.uistate, [], source,
|
||||||
Citation(), source)
|
Citation())
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
from gramps.gui.dialog import WarningDialog
|
from gramps.gui.dialog import WarningDialog
|
||||||
WarningDialog(_("Cannot share this reference"),
|
WarningDialog(_("Cannot share this reference"),
|
||||||
@@ -469,7 +468,9 @@ class CitationTreeView(ListView):
|
|||||||
raise ValueError("selection must be either source or citation")
|
raise ValueError("selection must be either source or citation")
|
||||||
if citation:
|
if citation:
|
||||||
try:
|
try:
|
||||||
EditCitation(self.dbstate, self.uistate, [], citation)
|
EditSource(self.dbstate, self.uistate, [],
|
||||||
|
self.dbstate.db.get_source_from_handle(
|
||||||
|
citation.get_reference_handle()), citation)
|
||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
pass
|
pass
|
||||||
else: # FIXME need try block here
|
else: # FIXME need try block here
|
||||||
|
|||||||
Reference in New Issue
Block a user