mirror of
https://git.lyx.org/repos/lyx.git
synced 2025-01-08 18:19:42 +00:00
change iterators ctors, implement backwardPos
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8562 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
5005bf0441
commit
610e905ed3
@ -311,7 +311,7 @@ void BufferView::setCursorFromRow(int row)
|
|||||||
|
|
||||||
void BufferView::gotoLabel(string const & label)
|
void BufferView::gotoLabel(string const & label)
|
||||||
{
|
{
|
||||||
for (InsetIterator it(buffer()->inset()); it; ++it) {
|
for (InsetIterator it = inset_iterator_begin(buffer()->inset()); it; ++it) {
|
||||||
vector<string> labels;
|
vector<string> labels;
|
||||||
it->getLabelList(*buffer(), labels);
|
it->getLabelList(*buffer(), labels);
|
||||||
if (find(labels.begin(),labels.end(),label) != labels.end()) {
|
if (find(labels.begin(),labels.end(),label) != labels.end()) {
|
||||||
|
@ -723,7 +723,7 @@ InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code /*code*/)
|
|||||||
#warning FIXME
|
#warning FIXME
|
||||||
#if 0
|
#if 0
|
||||||
Buffer * buf = bv_->buffer();
|
Buffer * buf = bv_->buffer();
|
||||||
InsetIterator beg(buf->inset());
|
InsetIterator beg = inset_iterator_begin(buf->inset());
|
||||||
|
|
||||||
bool cursor_par_seen = false;
|
bool cursor_par_seen = false;
|
||||||
|
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
|
||||||
|
2004-03-30 Alfredo Braunstein <abraunst@lyx.org>
|
||||||
|
|
||||||
|
* dociterator.[Ch]: add an inset_ member
|
||||||
|
(backwardPos): implemented
|
||||||
|
(backwardPos, forwardPos): use inset_ when the stack is empty.
|
||||||
|
(doc_iterator_begin, doc_iterator_end): implemented
|
||||||
|
* pariterator.[Ch]: adjust, add begin, end
|
||||||
|
* insetiterator.[Ch]: adjust, add begin, end
|
||||||
|
* cursor.C:
|
||||||
|
* document.C:
|
||||||
|
* BufferView.C:
|
||||||
|
* BufferView_pimpl.C:
|
||||||
|
* CutAndPaste.C: adjust
|
||||||
|
|
||||||
2004-03-29 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
|
2004-03-29 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
|
||||||
|
|
||||||
* buffer.C: increment file format to 232.
|
* buffer.C: increment file format to 232.
|
||||||
|
@ -85,8 +85,8 @@ int SwitchLayoutsBetweenClasses(textclass_type c1, textclass_type c2,
|
|||||||
InsetText in;
|
InsetText in;
|
||||||
std::swap(in.paragraphs(), pars);
|
std::swap(in.paragraphs(), pars);
|
||||||
|
|
||||||
ParIterator end = ParIterator(DocumentIterator());
|
ParIterator end = par_iterator_end(in);
|
||||||
for (ParIterator it = ParIterator(in, 0); it != end; ++it) {
|
for (ParIterator it = par_iterator_begin(in); it != end; ++it) {
|
||||||
string const name = it->layout()->name();
|
string const name = it->layout()->name();
|
||||||
bool hasLayout = tclass2.hasLayout(name);
|
bool hasLayout = tclass2.hasLayout(name);
|
||||||
|
|
||||||
@ -309,8 +309,8 @@ pasteSelection(Buffer const & buffer, ParagraphList & pars,
|
|||||||
InsetText in;
|
InsetText in;
|
||||||
std::swap(in.paragraphs(), insertion);
|
std::swap(in.paragraphs(), insertion);
|
||||||
|
|
||||||
ParIterator fpit = ParIterator(in, 0);
|
ParIterator fpit = par_iterator_begin(in);
|
||||||
ParIterator fend = ParIterator(DocumentIterator());
|
ParIterator fend = par_iterator_end(in);
|
||||||
|
|
||||||
for (; fpit != fend; ++fpit) {
|
for (; fpit != fend; ++fpit) {
|
||||||
InsetList::iterator lit = fpit->insetlist.begin();
|
InsetList::iterator lit = fpit->insetlist.begin();
|
||||||
|
18
src/buffer.C
18
src/buffer.C
@ -1192,7 +1192,7 @@ void Buffer::getLabelList(std::vector<string> & list) const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (InsetIterator it(inset()); it; ++it)
|
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it)
|
||||||
it.nextInset()->getLabelList(*this, list);
|
it.nextInset()->getLabelList(*this, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1210,7 +1210,7 @@ void Buffer::fillWithBibKeys(std::vector<std::pair<string, string> > & keys)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (InsetIterator it(inset()); it; ++it) {
|
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
|
||||||
if (it->lyxCode() == InsetOld::BIBTEX_CODE) {
|
if (it->lyxCode() == InsetOld::BIBTEX_CODE) {
|
||||||
InsetBibtex const & inset =
|
InsetBibtex const & inset =
|
||||||
dynamic_cast<InsetBibtex const &>(*it);
|
dynamic_cast<InsetBibtex const &>(*it);
|
||||||
@ -1304,11 +1304,9 @@ bool Buffer::isMultiLingual() const
|
|||||||
|
|
||||||
ParIterator Buffer::getParFromID(int id) const
|
ParIterator Buffer::getParFromID(int id) const
|
||||||
{
|
{
|
||||||
#warning FIXME: const correctness! (Andre)
|
ParConstIterator it = par_iterator_begin();
|
||||||
ParIterator it = const_cast<Buffer*>(this)->par_iterator_begin();
|
ParConstIterator end = par_iterator_end();
|
||||||
ParIterator end = const_cast<Buffer*>(this)->par_iterator_end();
|
|
||||||
|
|
||||||
#warning FIXME, perhaps this func should return a ParIterator? (Lgb)
|
|
||||||
if (id < 0) {
|
if (id < 0) {
|
||||||
// John says this is called with id == -1 from undo
|
// John says this is called with id == -1 from undo
|
||||||
lyxerr << "getParFromID(), id: " << id << endl;
|
lyxerr << "getParFromID(), id: " << id << endl;
|
||||||
@ -1344,25 +1342,25 @@ bool Buffer::hasParWithID(int id) const
|
|||||||
|
|
||||||
ParIterator Buffer::par_iterator_begin()
|
ParIterator Buffer::par_iterator_begin()
|
||||||
{
|
{
|
||||||
return ParIterator(inset(), 0);
|
return ::par_iterator_begin(inset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ParIterator Buffer::par_iterator_end()
|
ParIterator Buffer::par_iterator_end()
|
||||||
{
|
{
|
||||||
return ParIterator(DocumentIterator());
|
return ::par_iterator_end(inset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ParConstIterator Buffer::par_iterator_begin() const
|
ParConstIterator Buffer::par_iterator_begin() const
|
||||||
{
|
{
|
||||||
return ParConstIterator(inset(), 0);
|
return ::par_const_iterator_begin(inset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ParConstIterator Buffer::par_iterator_end() const
|
ParConstIterator Buffer::par_iterator_end() const
|
||||||
{
|
{
|
||||||
return ParConstIterator(DocumentIterator());
|
return ::par_const_iterator_end(inset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
11
src/cursor.C
11
src/cursor.C
@ -84,8 +84,9 @@ void region(CursorSlice const & i1, CursorSlice const & i2,
|
|||||||
|
|
||||||
|
|
||||||
LCursor::LCursor(BufferView & bv)
|
LCursor::LCursor(BufferView & bv)
|
||||||
: DocumentIterator(), bv_(&bv), anchor_(),
|
: DocumentIterator(), bv_(&bv),
|
||||||
cached_y_(0), x_target_(-1), selection_(false), mark_(false)
|
anchor_(), cached_y_(0), x_target_(-1),
|
||||||
|
selection_(false), mark_(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -93,7 +94,7 @@ void LCursor::reset(InsetBase & inset)
|
|||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
push_back(CursorSlice(inset));
|
push_back(CursorSlice(inset));
|
||||||
anchor_.clear();
|
anchor_ = DocumentIterator(inset);
|
||||||
cached_y_ = 0;
|
cached_y_ = 0;
|
||||||
clearTargetX();
|
clearTargetX();
|
||||||
selection_ = false;
|
selection_ = false;
|
||||||
@ -1117,8 +1118,8 @@ bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh)
|
|||||||
BOOST_ASSERT(text);
|
BOOST_ASSERT(text);
|
||||||
getParsInRange(text->paragraphs(), ylow, yhigh, beg, end);
|
getParsInRange(text->paragraphs(), ylow, yhigh, beg, end);
|
||||||
|
|
||||||
DocumentIterator it(bv().buffer()->inset());
|
DocumentIterator it = doc_iterator_begin(bv().buffer()->inset());
|
||||||
DocumentIterator et;
|
DocumentIterator et = doc_iterator_end(bv().buffer()->inset());
|
||||||
//lyxerr << "x: " << x << " y: " << y << endl;
|
//lyxerr << "x: " << x << " y: " << y << endl;
|
||||||
//lyxerr << "xlow: " << xlow << " ylow: " << ylow << endl;
|
//lyxerr << "xlow: " << xlow << " ylow: " << ylow << endl;
|
||||||
//lyxerr << "xhigh: " << xhigh << " yhigh: " << yhigh << endl;
|
//lyxerr << "xhigh: " << xhigh << " yhigh: " << yhigh << endl;
|
||||||
|
@ -14,16 +14,30 @@
|
|||||||
using std::endl;
|
using std::endl;
|
||||||
|
|
||||||
|
|
||||||
DocumentIterator::DocumentIterator()
|
//we could be able to get rid of this if only every BufferView were
|
||||||
|
//associated to a buffer on construction
|
||||||
|
DocumentIterator::DocumentIterator() : inset_(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
DocumentIterator::DocumentIterator(InsetBase & inset)
|
DocumentIterator doc_iterator_begin(InsetBase & inset)
|
||||||
{
|
{
|
||||||
push_back(CursorSlice(inset));
|
DocumentIterator dit(inset);
|
||||||
|
dit.forwardPos();
|
||||||
|
return dit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DocumentIterator doc_iterator_end(InsetBase & inset)
|
||||||
|
{
|
||||||
|
return DocumentIterator(inset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DocumentIterator::DocumentIterator(InsetBase & inset) : inset_(&inset)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
InsetBase * DocumentIterator::nextInset()
|
InsetBase * DocumentIterator::nextInset()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!empty());
|
BOOST_ASSERT(!empty());
|
||||||
@ -234,6 +248,12 @@ InsetBase * DocumentIterator::innerInsetOfType(int code) const
|
|||||||
|
|
||||||
void DocumentIterator::forwardPos()
|
void DocumentIterator::forwardPos()
|
||||||
{
|
{
|
||||||
|
//this dog bites his tail
|
||||||
|
if (empty()) {
|
||||||
|
push_back(CursorSlice(*inset_));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CursorSlice & top = back();
|
CursorSlice & top = back();
|
||||||
//lyxerr << "XXX\n" << *this << endl;
|
//lyxerr << "XXX\n" << *this << endl;
|
||||||
|
|
||||||
@ -320,8 +340,57 @@ void DocumentIterator::forwardInset()
|
|||||||
|
|
||||||
void DocumentIterator::backwardChar()
|
void DocumentIterator::backwardChar()
|
||||||
{
|
{
|
||||||
lyxerr << "not implemented" << endl;
|
backwardPos();
|
||||||
BOOST_ASSERT(false);
|
while (size() != 0 && pos() == lastpos())
|
||||||
|
backwardPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DocumentIterator::backwardPos()
|
||||||
|
{
|
||||||
|
//this dog bites his tail
|
||||||
|
if (empty()) {
|
||||||
|
push_back(CursorSlice(*inset_));
|
||||||
|
back().idx() = lastidx();
|
||||||
|
back().par() = lastpar();
|
||||||
|
back().pos() = lastpos();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorSlice & top = back();
|
||||||
|
|
||||||
|
if (top.pos() != 0) {
|
||||||
|
--top.pos();
|
||||||
|
} else if (top.par() != 0) {
|
||||||
|
--top.par();
|
||||||
|
top.pos() = lastpos();
|
||||||
|
return;
|
||||||
|
} else if (top.idx() != 0) {
|
||||||
|
--top.idx();
|
||||||
|
top.par() = lastpar();
|
||||||
|
top.pos() = lastpos();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move into an inset to the left if possible
|
||||||
|
InsetBase * n = 0;
|
||||||
|
|
||||||
|
if (inMathed()) {
|
||||||
|
n = (top.cell().begin() + top.pos())->nucleus();
|
||||||
|
} else {
|
||||||
|
if (paragraph().isInset(top.pos()))
|
||||||
|
n = paragraph().getInset(top.pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n && n->isActive()) {
|
||||||
|
push_back(CursorSlice(*n));
|
||||||
|
back().idx() = lastidx();
|
||||||
|
back().par() = lastpar();
|
||||||
|
back().pos() = lastpos();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -349,7 +418,7 @@ StableDocumentIterator::asDocumentIterator(InsetBase * inset) const
|
|||||||
{
|
{
|
||||||
// this function re-creates the cache of inset pointers
|
// this function re-creates the cache of inset pointers
|
||||||
//lyxerr << "converting:\n" << *this << endl;
|
//lyxerr << "converting:\n" << *this << endl;
|
||||||
DocumentIterator dit;
|
DocumentIterator dit = DocumentIterator(*inset);
|
||||||
for (size_t i = 0, n = data_.size(); i != n; ++i) {
|
for (size_t i = 0, n = data_.size(); i != n; ++i) {
|
||||||
dit.push_back(data_[i]);
|
dit.push_back(data_[i]);
|
||||||
dit.back().inset_ = inset;
|
dit.back().inset_ = inset;
|
||||||
|
@ -188,9 +188,15 @@ public:
|
|||||||
/// output
|
/// output
|
||||||
friend std::ostream &
|
friend std::ostream &
|
||||||
operator<<(std::ostream & os, DocumentIterator const & cur);
|
operator<<(std::ostream & os, DocumentIterator const & cur);
|
||||||
|
private:
|
||||||
|
InsetBase * inset_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DocumentIterator doc_iterator_begin(InsetBase & inset);
|
||||||
|
DocumentIterator doc_iterator_end(InsetBase & inset);
|
||||||
|
|
||||||
|
|
||||||
// The difference to a ('non stable') DocumentIterator is the removed
|
// The difference to a ('non stable') DocumentIterator is the removed
|
||||||
// (overwritte by 0...) part of the CursorSlice data items. So this thing
|
// (overwritte by 0...) part of the CursorSlice data items. So this thing
|
||||||
// is suitable for external storage, but not for iteration as such.
|
// is suitable for external storage, but not for iteration as such.
|
||||||
|
@ -7,6 +7,18 @@
|
|||||||
InsetIterator::InsetIterator(InsetBase & inset)
|
InsetIterator::InsetIterator(InsetBase & inset)
|
||||||
: DocumentIterator(inset)
|
: DocumentIterator(inset)
|
||||||
{
|
{
|
||||||
if (size() && !nextInset())
|
}
|
||||||
forwardInset();
|
|
||||||
|
|
||||||
|
InsetIterator inset_iterator_begin(InsetBase & inset)
|
||||||
|
{
|
||||||
|
InsetIterator it = InsetIterator(inset);
|
||||||
|
it.forwardInset();
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InsetIterator inset_iterator_end(InsetBase & inset)
|
||||||
|
{
|
||||||
|
return InsetIterator(inset);
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
class InsetIterator : public DocumentIterator
|
class InsetIterator : public DocumentIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
|
||||||
InsetIterator() {}
|
|
||||||
///
|
///
|
||||||
explicit InsetIterator(InsetBase & inset);
|
explicit InsetIterator(InsetBase & inset);
|
||||||
///
|
///
|
||||||
@ -32,4 +30,9 @@ public:
|
|||||||
InsetBase & operator*() { return *nextInset(); }
|
InsetBase & operator*() { return *nextInset(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
InsetIterator inset_iterator_begin(InsetBase & inset);
|
||||||
|
|
||||||
|
InsetIterator inset_iterator_end(InsetBase & inset);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
|
||||||
|
2004-03-30 Alfredo Braunstein <abraunst@lyx.org>
|
||||||
|
|
||||||
|
* insetfloat.C (addToToc): use par_const_iterator_begin and
|
||||||
|
par_const_iterator_end.
|
||||||
|
|
||||||
2004-03-29 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
|
2004-03-29 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
|
||||||
|
|
||||||
* insetbibtex.[Ch]: bibtopic support.
|
* insetbibtex.[Ch]: bibtopic support.
|
||||||
|
@ -419,8 +419,8 @@ void InsetFloat::sideways(bool s, BufferParams const & bp)
|
|||||||
|
|
||||||
void InsetFloat::addToToc(lyx::toc::TocList & toclist, Buffer const & buf) const
|
void InsetFloat::addToToc(lyx::toc::TocList & toclist, Buffer const & buf) const
|
||||||
{
|
{
|
||||||
ParConstIterator pit(*this, 0);
|
ParConstIterator pit = par_const_iterator_begin(*this);
|
||||||
ParConstIterator end = ParConstIterator(DocumentIterator());
|
ParConstIterator end = par_const_iterator_end(*this);
|
||||||
|
|
||||||
// Find a caption layout in one of the (child inset's) pars
|
// Find a caption layout in one of the (child inset's) pars
|
||||||
for (; pit != end; ++pit) {
|
for (; pit != end; ++pit) {
|
||||||
|
@ -30,9 +30,15 @@ ParIterator::ParIterator(DocumentIterator const & cur) : DocumentIterator(cur)
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
ParIterator::ParIterator(InsetBase & in, par_type pit) : DocumentIterator(in)
|
ParIterator par_iterator_begin(InsetBase & inset)
|
||||||
{
|
{
|
||||||
par() = pit;
|
return ParIterator(doc_iterator_begin(inset));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ParIterator par_iterator_end(InsetBase & inset)
|
||||||
|
{
|
||||||
|
return ParIterator(doc_iterator_end(inset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,13 +115,6 @@ makeDocumentIterator(ParIterator const & par, lyx::pos_type pos)
|
|||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
ParConstIterator::ParConstIterator(InsetBase const & in, par_type pit)
|
|
||||||
: DocumentIterator(const_cast<InsetBase &>(in))
|
|
||||||
{
|
|
||||||
par() = pit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ParConstIterator::ParConstIterator(DocumentIterator const & dit)
|
ParConstIterator::ParConstIterator(DocumentIterator const & dit)
|
||||||
: DocumentIterator(dit)
|
: DocumentIterator(dit)
|
||||||
{}
|
{}
|
||||||
@ -161,3 +160,17 @@ bool operator!=(ParConstIterator const & iter1, ParConstIterator const & iter2)
|
|||||||
{
|
{
|
||||||
return !(iter1 == iter2);
|
return !(iter1 == iter2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#warning const correctness!
|
||||||
|
|
||||||
|
ParConstIterator par_const_iterator_begin(InsetBase const & inset)
|
||||||
|
{
|
||||||
|
return ParConstIterator(doc_iterator_begin(const_cast<InsetBase &>(inset)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ParConstIterator par_const_iterator_end(InsetBase const & inset)
|
||||||
|
{
|
||||||
|
return ParConstIterator(doc_iterator_end(const_cast<InsetBase &>(inset)));
|
||||||
|
}
|
||||||
|
@ -59,7 +59,9 @@ public:
|
|||||||
|
|
||||||
DocumentIterator makeDocumentIterator(ParIterator const &, lyx::pos_type);
|
DocumentIterator makeDocumentIterator(ParIterator const &, lyx::pos_type);
|
||||||
|
|
||||||
|
ParIterator par_iterator_begin(InsetBase & inset);
|
||||||
|
|
||||||
|
ParIterator par_iterator_end(InsetBase & inset);
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -74,8 +76,6 @@ class ParConstIterator : public std::iterator<std::forward_iterator_tag,
|
|||||||
public DocumentIterator
|
public DocumentIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
|
||||||
ParConstIterator(InsetBase const &, lyx::par_type pit);
|
|
||||||
///
|
///
|
||||||
ParConstIterator(ParConstIterator const &);
|
ParConstIterator(ParConstIterator const &);
|
||||||
///
|
///
|
||||||
@ -99,4 +99,10 @@ bool operator==(ParConstIterator const & iter1,
|
|||||||
bool operator!=(ParConstIterator const & iter1,
|
bool operator!=(ParConstIterator const & iter1,
|
||||||
ParConstIterator const & iter2);
|
ParConstIterator const & iter2);
|
||||||
|
|
||||||
|
|
||||||
|
ParConstIterator par_const_iterator_begin(InsetBase const & inset);
|
||||||
|
|
||||||
|
ParConstIterator par_const_iterator_end(InsetBase const & inset);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user