Import/Export changes
This commit is contained in:
parent
2dd873368e
commit
3e261ca152
@ -30,6 +30,9 @@ namespace Novell.CASA.GUI
|
||||
[Glade.Widget]
|
||||
Gtk.CheckButton checkbuttonNoEncrypt;
|
||||
|
||||
[Glade.Widget]
|
||||
Gtk.Button buttonNewFolder;
|
||||
|
||||
public ExportSecrets(Config config)
|
||||
{
|
||||
m_config = config;
|
||||
@ -91,7 +94,11 @@ namespace Novell.CASA.GUI
|
||||
if (sFileName != null)
|
||||
{
|
||||
//Store off this location for next export
|
||||
|
||||
int iLastSlash = sFileName.LastIndexOf("/");
|
||||
if (Common.IS_WINDOWS)
|
||||
iLastSlash = sFileName.LastIndexOf("\\");
|
||||
|
||||
if (iLastSlash > 0)
|
||||
{
|
||||
sHintFile = sFileName.Substring(iLastSlash + 1);
|
||||
@ -115,7 +122,7 @@ namespace Novell.CASA.GUI
|
||||
fs.Flush();
|
||||
fs.Close();
|
||||
|
||||
CommonGUI.DisplayMessage(MessageType.Info, "Secrets saved to: \r\n" + sFileName.Substring(8));
|
||||
CommonGUI.DisplayMessage(MessageType.Info, "Secrets saved to: \r\n" + sFileName);
|
||||
|
||||
}
|
||||
}
|
||||
@ -137,7 +144,7 @@ namespace Novell.CASA.GUI
|
||||
private string GetStorageFileName(string sHintDir, string sHintFile)
|
||||
{
|
||||
|
||||
FileChooser fc = new FileChooser();
|
||||
FileChooser fc = new FileChooser(FileChooser.ACTION_SAVE);
|
||||
String sFileName = fc.GetFile(sHintDir, sHintFile);
|
||||
|
||||
/*
|
||||
|
@ -21,13 +21,19 @@ namespace Novell.CASA.GUI
|
||||
|
||||
private string m_pathSeparator = "/";
|
||||
|
||||
// actions
|
||||
private int m_iAction = 1;
|
||||
public const int ACTION_OPEN = 1;
|
||||
public const int ACTION_SAVE = 2;
|
||||
|
||||
Thread tChooserThread = null;
|
||||
|
||||
|
||||
#region Glade Widgets
|
||||
|
||||
[Glade.Widget]
|
||||
Gtk.Dialog dialogFileChooser;
|
||||
Gtk.Dialog dialogFileChooser,
|
||||
dialogNewFolder;
|
||||
|
||||
[Glade.Widget]
|
||||
Gtk.TreeView treeviewFavorites,
|
||||
@ -35,17 +41,23 @@ namespace Novell.CASA.GUI
|
||||
|
||||
[Glade.Widget]
|
||||
Gtk.Entry entrySelectedFile,
|
||||
entryCurrentDir;
|
||||
entryCurrentDir,
|
||||
entryNewFolder;
|
||||
|
||||
[Glade.Widget]
|
||||
Gtk.Button buttonUP;
|
||||
Gtk.Button buttonUP,
|
||||
buttonNewFolder;
|
||||
|
||||
[Glade.Widget]
|
||||
Gtk.Menu menuDeleteDirFile;
|
||||
|
||||
#endregion
|
||||
|
||||
public FileChooser()
|
||||
public FileChooser(int action)
|
||||
{
|
||||
|
||||
m_iAction = action;
|
||||
|
||||
if (Common.IS_WINDOWS)
|
||||
m_pathSeparator = "\\";
|
||||
|
||||
@ -81,7 +93,11 @@ namespace Novell.CASA.GUI
|
||||
}
|
||||
|
||||
DoWork();
|
||||
return m_currentDirectory + m_pathSeparator + m_sFileSelected;
|
||||
|
||||
if (m_sFileSelected != null)
|
||||
return m_currentDirectory + m_pathSeparator + m_sFileSelected;
|
||||
else
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@ -124,6 +140,18 @@ namespace Novell.CASA.GUI
|
||||
Glade.XML gxmlTemp = new Glade.XML(Common.GladeFile, "dialogFileChooser", null);
|
||||
gxmlTemp.Autoconnect(this);
|
||||
|
||||
if (m_iAction == ACTION_OPEN)
|
||||
{
|
||||
buttonNewFolder.Visible = false;
|
||||
entrySelectedFile.Sensitive = false;
|
||||
dialogFileChooser.Title = "Select the file to open";
|
||||
}
|
||||
else
|
||||
{
|
||||
dialogFileChooser.Title = "Save secrets to ....";
|
||||
}
|
||||
|
||||
|
||||
// show logical drives
|
||||
string[] drives = Directory.GetLogicalDrives();
|
||||
for (int i=0; i<drives.Length; i++)
|
||||
@ -133,7 +161,7 @@ namespace Novell.CASA.GUI
|
||||
treeviewFavorites.AppendColumn("Drive", new CellRendererText(), "text", 0);
|
||||
treeviewFavorites.Model = tsDrives;
|
||||
|
||||
treeviewFavorites.RowActivated += new RowActivatedHandler(treeviewFavorites_RowActivated);
|
||||
treeviewFavorites.RowActivated += new RowActivatedHandler(treeviewFavorites_RowActivated);
|
||||
|
||||
// FILE LISTING
|
||||
// hook up the model
|
||||
@ -146,7 +174,9 @@ namespace Novell.CASA.GUI
|
||||
|
||||
// hook up the events
|
||||
treeviewListing.RowActivated +=new RowActivatedHandler(treeviewListing_RowActivated);
|
||||
|
||||
treeviewListing.MoveCursor +=new MoveCursorHandler(treeviewListing_MoveCursor);
|
||||
treeviewListing.ButtonReleaseEvent +=new ButtonReleaseEventHandler(treeviewListing_ButtonReleaseEvent);
|
||||
|
||||
DisplayDirectory();
|
||||
DisplayFileListing();
|
||||
|
||||
@ -195,24 +225,38 @@ namespace Novell.CASA.GUI
|
||||
|
||||
private void treeviewListing_RowActivated(object o, RowActivatedArgs args)
|
||||
{
|
||||
ProcessSelection();
|
||||
}
|
||||
|
||||
private void ProcessSelection()
|
||||
{
|
||||
TreeModel model;
|
||||
TreeIter iter;
|
||||
string selected;
|
||||
|
||||
// trim any trailing \
|
||||
if (m_currentDirectory.EndsWith("\\"))
|
||||
if (m_currentDirectory.EndsWith(m_pathSeparator))
|
||||
m_currentDirectory = m_currentDirectory.Substring(0, m_currentDirectory.Length - 1);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if( treeviewListing.Selection.GetSelected (out model, out iter) )
|
||||
//if( treeviewListing.Selection.GetSelected (out model, out iter) )
|
||||
{
|
||||
selected = (string) model.GetValue(iter, 1);
|
||||
//selected = (string) model.GetValue(iter, 1);
|
||||
selected = entrySelectedFile.Text;
|
||||
|
||||
if (Directory.Exists(m_currentDirectory + "/" + selected))
|
||||
if (Directory.Exists(m_currentDirectory + m_pathSeparator + selected))
|
||||
{
|
||||
SetCurrentDirectory(m_currentDirectory + "/" + selected);
|
||||
// if we are at root
|
||||
if (m_currentDirectory.Equals("/"))
|
||||
{
|
||||
SetCurrentDirectory(m_currentDirectory + selected);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCurrentDirectory(m_currentDirectory + m_pathSeparator + selected);
|
||||
}
|
||||
|
||||
// clear current view
|
||||
ts.Clear();
|
||||
@ -223,6 +267,7 @@ namespace Novell.CASA.GUI
|
||||
// file selected
|
||||
entrySelectedFile.Text = selected;
|
||||
m_sFileSelected = selected;
|
||||
|
||||
// destroy dialog
|
||||
dialogFileChooser.Destroy();
|
||||
m_bFileChoosing = false;
|
||||
@ -233,7 +278,8 @@ namespace Novell.CASA.GUI
|
||||
{
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void treeviewFavorites_RowActivated(object o, RowActivatedArgs args)
|
||||
@ -258,6 +304,12 @@ namespace Novell.CASA.GUI
|
||||
}
|
||||
}
|
||||
|
||||
public void on_btnOkFileChooser_clicked(object obj, EventArgs args)
|
||||
{
|
||||
ProcessSelection();
|
||||
}
|
||||
|
||||
|
||||
public void on_btnCancelFileChooser_clicked(object obj, EventArgs args)
|
||||
{
|
||||
m_bFileChoosing = false;
|
||||
@ -275,8 +327,12 @@ namespace Novell.CASA.GUI
|
||||
|
||||
public void on_buttonUP_clicked(object o, EventArgs args)
|
||||
{
|
||||
int iSlashIndex = m_currentDirectory.LastIndexOf(m_pathSeparator);
|
||||
// remove trailing slash if there is one
|
||||
if (m_currentDirectory.EndsWith(m_pathSeparator))
|
||||
m_currentDirectory = m_currentDirectory.Substring(0, m_currentDirectory.Length - 1);
|
||||
|
||||
// back up one directory
|
||||
int iSlashIndex = m_currentDirectory.LastIndexOf(m_pathSeparator);
|
||||
if (iSlashIndex > 1)
|
||||
{
|
||||
// if windows drive letter, keep the slash
|
||||
@ -292,6 +348,123 @@ namespace Novell.CASA.GUI
|
||||
private void imageUp_ButtonPressEvent(object o, ButtonPressEventArgs args)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void treeviewListing_MoveCursor(object o, MoveCursorArgs args)
|
||||
{
|
||||
//Console.WriteLine("Cursor moved");
|
||||
DisplaySelectedFile();
|
||||
}
|
||||
|
||||
private void treeviewListing_ButtonReleaseEvent(object o, ButtonReleaseEventArgs args)
|
||||
{
|
||||
|
||||
//Console.WriteLine("Button released");
|
||||
DisplaySelectedFile();
|
||||
|
||||
if( 3 == args.Event.Button )
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.DbgLog("GUI:MiCasa.OnRightClicked() - Context menu opened.");
|
||||
Glade.XML gxmlTemp = new Glade.XML (Common.GladeFile, "menuDeleteDirFile", null);
|
||||
gxmlTemp.Autoconnect (this);
|
||||
menuDeleteDirFile.Popup(null, null, null, IntPtr.Zero, 3, Gtk.Global.CurrentEventTime);
|
||||
}
|
||||
catch(Exception exp)
|
||||
{
|
||||
Logger.DbgLog("GUI:MiCasa.OnRightClicked() - EXCEPTION:" + exp.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onDeleteDirFile(object obj, EventArgs args)
|
||||
{
|
||||
string sDirFile = entrySelectedFile.Text;
|
||||
if (sDirFile != null)
|
||||
{
|
||||
if (Directory.Exists(m_currentDirectory + m_pathSeparator + sDirFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(m_currentDirectory + m_pathSeparator + sDirFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CommonGUI.DisplayMessage(Gtk.MessageType.Error, e.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Delete(m_currentDirectory + m_pathSeparator + sDirFile);
|
||||
}
|
||||
|
||||
DisplayFileListing();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplaySelectedFile()
|
||||
{
|
||||
TreeModel model;
|
||||
TreeIter iter;
|
||||
string selected;
|
||||
|
||||
try
|
||||
{
|
||||
if( treeviewListing.Selection.GetSelected (out model, out iter) )
|
||||
{
|
||||
selected = (string) model.GetValue(iter, 1);
|
||||
entrySelectedFile.Text = selected;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// new folder handler
|
||||
public void on_buttonNewFolder_clicked(object obj, EventArgs args)
|
||||
{
|
||||
//prompt for new folder name
|
||||
// load and connect handlers
|
||||
Glade.XML gxmlTemp = new Glade.XML(Common.GladeFile, "dialogNewFolder", null);
|
||||
gxmlTemp.Autoconnect(this);
|
||||
|
||||
dialogNewFolder.SetPosition(Gtk.WindowPosition.CenterOnParent);
|
||||
}
|
||||
|
||||
public void on_okbuttonNewFolder_clicked(object obj, EventArgs args)
|
||||
{
|
||||
// create the new folder
|
||||
string sNewFolder = entryNewFolder.Text;
|
||||
if (sNewFolder != null)
|
||||
{
|
||||
// create folder in currentdir
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(m_currentDirectory + m_pathSeparator + sNewFolder);
|
||||
if (dialogNewFolder != null)
|
||||
{
|
||||
dialogNewFolder.Destroy();
|
||||
}
|
||||
|
||||
DisplayFileListing();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void on_cancelbuttonNewFolder_clicked(object obj, EventArgs args)
|
||||
{
|
||||
if (dialogNewFolder != null)
|
||||
{
|
||||
dialogNewFolder.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ namespace Novell.CASA.GUI
|
||||
String sHintFilename = m_config.GetConfigSetting(CommonGUI.HINT_FILENAME, null);
|
||||
string sFile = null;
|
||||
|
||||
FileChooser fc = new FileChooser();
|
||||
FileChooser fc = new FileChooser(FileChooser.ACTION_OPEN);
|
||||
sFile = fc.GetFile(sHintDir, sHintFilename);
|
||||
|
||||
//fc.Show(sHintDir, sHintFilename);
|
||||
|
@ -12357,7 +12357,7 @@ in clear text. </property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label266">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Export miCASA Secrets</b></property>
|
||||
<property name="label" translatable="yes"><b>Import miCASA Secrets</b></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
@ -12531,6 +12531,7 @@ to encrypt this file</property>
|
||||
<property name="default_height">525</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="icon">CASAicons.ico</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
@ -12576,6 +12577,7 @@ to encrypt this file</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
<signal name="clicked" handler="on_btnOkFileChooser_clicked" last_modification_time="Mon, 21 Aug 2006 18:02:11 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
@ -12602,10 +12604,10 @@ to encrypt this file</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label270">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Look in:</property>
|
||||
<property name="label" translatable="yes">Location:</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="justify">GTK_JUSTIFY_RIGHT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
@ -12719,6 +12721,23 @@ to encrypt this file</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="buttonNewFolder">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">New Folder</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_buttonNewFolder_clicked" last_modification_time="Mon, 21 Aug 2006 19:41:27 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
@ -12831,4 +12850,153 @@ to encrypt this file</property>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkDialog" id="dialogNewFolder">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">New Folder</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">True</property>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox11">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area11">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancelbuttonNewFolder">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
<signal name="clicked" handler="on_cancelbuttonNewFolder_clicked" last_modification_time="Mon, 21 Aug 2006 19:55:14 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="okbuttonNewFolder">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
<signal name="clicked" handler="on_okbuttonNewFolder_clicked" last_modification_time="Mon, 21 Aug 2006 19:55:20 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox158">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label271">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Enter folder name</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entryNewFolder">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="visibility">True</property>
|
||||
<property name="max_length">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
<property name="has_frame">True</property>
|
||||
<property name="invisible_char">*</property>
|
||||
<property name="activates_default">False</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkMenu" id="menuDeleteDirFile">
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="imagemenuitem6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Delete</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="onDeleteDirFile" last_modification_time="Mon, 21 Aug 2006 20:35:18 GMT"/>
|
||||
<accelerator key="Delete" modifiers="0" signal="activate"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image3934">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-delete</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
||||
|
Loading…
Reference in New Issue
Block a user