implements visual improvements
This commit is contained in:
parent
3890a87a8c
commit
dc4798b8ba
@ -91,6 +91,7 @@ import com.minres.scviewer.database.ui.IWaveformView;
|
||||
import com.minres.scviewer.database.ui.IWaveformZoom;
|
||||
import com.minres.scviewer.database.ui.IWaveformviewEventListener;
|
||||
import com.minres.scviewer.database.ui.TrackEntry;
|
||||
import com.minres.scviewer.database.ui.TrackEntry.HierState;
|
||||
import com.minres.scviewer.database.ui.swt.internal.slider.ZoomBar;
|
||||
|
||||
public class WaveformView implements IWaveformView {
|
||||
@ -155,11 +156,13 @@ public class WaveformView implements IWaveformView {
|
||||
setSelection(new StructuredSelection(entry.getValue()), false, false);
|
||||
lastClickedEntry = entry.getValue();
|
||||
} else {
|
||||
StructuredSelection structuredSelection = (StructuredSelection) sel;
|
||||
if(structuredSelection.size()== 1 && structuredSelection.getFirstElement() instanceof TrackEntry) {
|
||||
@SuppressWarnings("unchecked")
|
||||
long c = ((IStructuredSelection)sel).toList().stream().filter(x -> x instanceof TrackEntry).count();
|
||||
if(c==1) {
|
||||
Entry<Integer, TrackEntry> entry = trackVerticalOffset.floorEntry(e.y);
|
||||
TrackEntry selEntry = (TrackEntry) structuredSelection.getFirstElement();
|
||||
if(!entry.getValue().equals(selEntry)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<TrackEntry> o = ((IStructuredSelection)sel).toList().stream().filter(x -> x instanceof TrackEntry).findFirst();
|
||||
if(!entry.getValue().equals(o.get())) {
|
||||
setSelection(new StructuredSelection(entry.getValue()), false, false);
|
||||
lastClickedEntry = entry.getValue();
|
||||
}
|
||||
@ -347,9 +350,7 @@ public class WaveformView implements IWaveformView {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected WaveformMouseListener waveformMouseListener = new WaveformMouseListener();
|
||||
@ -588,7 +589,7 @@ public class WaveformView implements IWaveformView {
|
||||
TextLayout tl = new TextLayout(waveformCanvas.getDisplay());
|
||||
tl.setFont(styleProvider.getNameFont());
|
||||
for (TrackEntry streamEntry : streams) {
|
||||
if(streamEntry.hierState == TrackEntry.HierState.OPENED) {
|
||||
if(streamEntry.hierState == HierState.OPENED) {
|
||||
for (TrackEntry trackEntry : streamEntry.waveforms) {
|
||||
addPainter(even, trackEntry);
|
||||
trackVerticalOffset.put(tracksVerticalHeight, trackEntry);
|
||||
@ -1161,16 +1162,13 @@ public class WaveformView implements IWaveformView {
|
||||
if (lastKey.equals(firstKey)) {
|
||||
TrackEntry trackEntry = trackVerticalOffset.get(firstKey);
|
||||
IWaveform w = trackEntry.waveform;
|
||||
if (w.getType() == WaveformType.TRANSACTION)
|
||||
subArea.height *= w.getRowCount();
|
||||
subArea.height = w.getRowCount() * styleProvider.getTrackHeight();
|
||||
drawValue(gc, subArea, firstKey, trackEntry.currentValue, trackEntry.selected);
|
||||
} else {
|
||||
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
|
||||
.entrySet()) {
|
||||
IWaveform w = entry.getValue().waveform;
|
||||
subArea.height = styleProvider.getTrackHeight();
|
||||
if (w.getType() == WaveformType.TRANSACTION)
|
||||
subArea.height *= w.getRowCount();
|
||||
subArea.height = w.getRowCount() * styleProvider.getTrackHeight();
|
||||
drawValue(gc, subArea, entry.getKey(), entry.getValue().currentValue,
|
||||
entry.getValue().selected);
|
||||
}
|
||||
@ -1180,10 +1178,9 @@ public class WaveformView implements IWaveformView {
|
||||
}
|
||||
}
|
||||
|
||||
private void drawName(GC gc, Rectangle subArea, Integer firstKey, TrackEntry entry) {
|
||||
protected void drawName(GC gc, Rectangle subArea, Integer firstKey, TrackEntry entry) {
|
||||
IWaveform w = entry.waveform;
|
||||
if (w.getType() == WaveformType.TRANSACTION)
|
||||
subArea.height *= w.getRowCount();
|
||||
subArea.height = w.getRowCount() * styleProvider.getTrackHeight();
|
||||
drawTextFormat(gc, subArea, firstKey, w.getFullName(), entry.selected, entry.hierState);
|
||||
}
|
||||
|
||||
@ -1199,10 +1196,10 @@ public class WaveformView implements IWaveformView {
|
||||
}
|
||||
|
||||
protected void drawTextFormat(GC gc, Rectangle subArea, int yOffset, String value, boolean highlite) {
|
||||
drawTextFormat(gc, subArea, yOffset, value, highlite, TrackEntry.HierState.NONE);
|
||||
drawTextFormat(gc, subArea, yOffset, value, highlite, HierState.NONE);
|
||||
}
|
||||
|
||||
protected void drawTextFormat(GC gc, Rectangle subArea, int yOffset, String value, boolean highlite, TrackEntry.HierState state) {
|
||||
protected void drawTextFormat(GC gc, Rectangle subArea, int yOffset, String value, boolean highlite, HierState state) {
|
||||
Point size = gc.textExtent(value);
|
||||
int height = styleProvider.getTrackHeight();
|
||||
if (highlite) {
|
||||
@ -1215,14 +1212,28 @@ public class WaveformView implements IWaveformView {
|
||||
gc.setForeground(namePaneHeader.getForeground());
|
||||
gc.setFont(styleProvider.getNameFont());
|
||||
}
|
||||
if(state==TrackEntry.HierState.NONE) {
|
||||
gc.drawText(value, subArea.x + 5, subArea.y + yOffset + (height - size.y) / 2, true);
|
||||
/* if(state==HierState.NONE) {
|
||||
gc.drawText(value, subArea.x + 5, subArea.y + yOffset + (height - size.y) / 2, true);
|
||||
} else {
|
||||
gc.setBackground(highlite?SWTResourceManager.getColor(SWT.COLOR_LIST_SELECTION_TEXT):namePaneHeader.getForeground());
|
||||
gc.fillPolygon(new int[]{3, yOffset+(height-10)/2, 10, yOffset+height/2, 3, yOffset+(height+10)/2});
|
||||
int o = yOffset + (height-12)/2;
|
||||
if(state==HierState.OPENED) {
|
||||
Point tl = new Point(1,o+2);
|
||||
Point tr = new Point(10,o+2);
|
||||
Point br = new Point(6,o+9);
|
||||
Point bl = new Point(5,o+9);
|
||||
gc.fillPolygon(new int[] {tl.x, tl.y, tr.x, tr.y, br.x, br.y, bl.x, bl.y});
|
||||
} else {
|
||||
Point tl = new Point(2,o+1);
|
||||
Point tr = new Point(9,o+5);
|
||||
Point br = new Point(9,o+6);
|
||||
Point bl = new Point(2,o+10);
|
||||
gc.fillPolygon(new int[] {tl.x, tl.y, tr.x, tr.y, br.x, br.y, bl.x, bl.y});
|
||||
}
|
||||
Rectangle textArea = new Rectangle(subArea.x+12, subArea.y, subArea.width-12, subArea.height);
|
||||
gc.drawText(value, textArea.x + 5, subArea.y + yOffset + (height - size.y) / 2, true);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public void setHighliteRelation(RelationType relationType) {
|
||||
|
@ -118,7 +118,7 @@
|
||||
<handlers xmi:id="_TwU0IEYoEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handler.enabletxdetails" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.EnableTxDetails" command="_Fj1gQEYoEeyKK_icsY7Xjg"/>
|
||||
<handlers xmi:id="_htyxgHCOEeyub8CfGE1sGA" elementId="com.minres.scviewer.e4.application.handler.helpContent" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.HelpContentsHandler" command="_RdUMoHCOEeyub8CfGE1sGA"/>
|
||||
<handlers xmi:id="__Ozu4LcxEe294PIiYLxpfA" elementId="com.minres.scviewer.e4.application.handler.add_separator" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.AddSeparatorHandler" command="_vYAOQLcxEe294PIiYLxpfA"/>
|
||||
<handlers xmi:id="_zpAa4LepEe294PIiYLxpfA" elementId="com.minres.scviewer.e4.application.handler.set_label_text" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SetLabelTextHandler" command="_wcqasLepEe294PIiYLxpfA"/>
|
||||
<handlers xmi:id="_zpAa4LepEe294PIiYLxpfA" elementId="com.minres.scviewer.e4.application.handler.wave_double_click" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.WaveformDoubleClickTextHandler" command="_wcqasLepEe294PIiYLxpfA"/>
|
||||
<bindingTables xmi:id="_95PfvnNmEeWBq8z1Dv39LA" bindingContext="_95PfuXNmEeWBq8z1Dv39LA">
|
||||
<bindings xmi:id="_95Pfv3NmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.keybinding.quit" keySequence="M1+Q" command="_95PfvHNmEeWBq8z1Dv39LA">
|
||||
<tags>type:user</tags>
|
||||
@ -218,7 +218,7 @@
|
||||
<visibleWhen xsi:type="ui:ImperativeExpression" xmi:id="_Se1voBlEEeuiP60JNw0iiA" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SearchHandler"/>
|
||||
</children>
|
||||
<children xsi:type="menu:HandledMenuItem" xmi:id="_Wblk0LexEe294PIiYLxpfA" elementId="com.minres.scviewer.e4.application.handledmenuitem.edit_text" label="Edit Text" command="_wcqasLepEe294PIiYLxpfA">
|
||||
<visibleWhen xsi:type="ui:ImperativeExpression" xmi:id="_fH08MLexEe294PIiYLxpfA" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SetLabelTextHandler"/>
|
||||
<visibleWhen xsi:type="ui:ImperativeExpression" xmi:id="_fH08MLexEe294PIiYLxpfA" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.WaveformDoubleClickTextHandler"/>
|
||||
</children>
|
||||
</menus>
|
||||
<toolbar xmi:id="_ReeeAE-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.toolbar.3">
|
||||
@ -319,7 +319,7 @@
|
||||
<parameters xmi:id="_y2BUsU-HEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.command.pancommand.parameter.direction" name="direction" optional="false"/>
|
||||
</commands>
|
||||
<commands xmi:id="_RdUMoHCOEeyub8CfGE1sGA" elementId="org.eclipse.ui.help.helpContentCommand" commandName="Help Content Command" description=""/>
|
||||
<commands xmi:id="_wcqasLepEe294PIiYLxpfA" elementId="com.minres.scviewer.e4.application.command.set_label_text" commandName="Set Label Text"/>
|
||||
<commands xmi:id="_wcqasLepEe294PIiYLxpfA" elementId="com.minres.scviewer.e4.application.command.wave_double_click" commandName="Waveform Double Click"/>
|
||||
<addons xmi:id="_95PfsnNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
|
||||
<addons xmi:id="_95Pfs3NmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
|
||||
<addons xmi:id="_95PftHNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>
|
||||
|
@ -41,7 +41,7 @@ public class AppModelId {
|
||||
public static final String COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_PANCOMMAND = "com.minres.scviewer.e4.application.command.pancommand";
|
||||
public static final String COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_SELECTALLCOMMAND = "com.minres.scviewer.e4.application.command.selectallCommand";
|
||||
public static final String COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_SETRELATIONTYPE = "com.minres.scviewer.e4.application.command.setrelationtype";
|
||||
public static final String COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_SET_LABEL_TEXT = "com.minres.scviewer.e4.application.command.set_label_text";
|
||||
public static final String COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_WAVE_DOUBLE_CLICK = "com.minres.scviewer.e4.application.command.wave_double_click";
|
||||
public static final String COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_SET_THEM = "com.minres.scviewer.e4.application.command.set_them";
|
||||
public static final String COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_UPDATE = "com.minres.scviewer.e4.application.command.update";
|
||||
public static final String COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_ZOOMCOMMAND = "com.minres.scviewer.e4.application.command.zoomcommand";
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
package com.minres.scviewer.e4.application.handlers;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.eclipse.e4.core.di.annotations.CanExecute;
|
||||
@ -34,12 +36,11 @@ public class AddSeparatorHandler {
|
||||
if(part!=null && part.getObject() instanceof WaveformViewer){
|
||||
Object sel = ((WaveformViewer)part.getObject()).getSelection();
|
||||
if( sel instanceof IStructuredSelection) {
|
||||
if(((IStructuredSelection)sel).isEmpty()) return false;
|
||||
IStructuredSelection isel = (IStructuredSelection) sel;
|
||||
if(isel.size()==1)
|
||||
return isel.getFirstElement() instanceof TrackEntry;
|
||||
else if(isel.size()==2) {
|
||||
return isel.toArray()[1] instanceof TrackEntry;
|
||||
if( sel instanceof IStructuredSelection) {
|
||||
if(((IStructuredSelection)sel).isEmpty()) return false;
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<TrackEntry> o= ((IStructuredSelection)sel).toList().stream().filter(e -> e instanceof TrackEntry).findFirst();
|
||||
return o.isPresent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
package com.minres.scviewer.e4.application.handlers;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.e4.core.di.annotations.CanExecute;
|
||||
import org.eclipse.e4.core.di.annotations.Execute;
|
||||
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
|
||||
@ -25,13 +27,11 @@ public class DeleteWaveformHandler {
|
||||
@SuppressWarnings("unchecked")
|
||||
@CanExecute
|
||||
public Boolean canExecute(ESelectionService selectionService){
|
||||
Object o = selectionService.getSelection();
|
||||
if(o instanceof IStructuredSelection) {
|
||||
IStructuredSelection sel = (IStructuredSelection) o;
|
||||
if(sel.size()>0)
|
||||
return sel.toList().stream().allMatch(e-> e instanceof TrackEntry);
|
||||
else
|
||||
return false;
|
||||
Object sel = selectionService.getSelection();
|
||||
if(sel instanceof IStructuredSelection) {
|
||||
if(((IStructuredSelection)sel).isEmpty()) return false;
|
||||
Optional<TrackEntry> o= ((IStructuredSelection)sel).toList().stream().filter(e -> e instanceof TrackEntry).findFirst();
|
||||
return o.isPresent();
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
package com.minres.scviewer.e4.application.handlers;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.e4.core.di.annotations.CanExecute;
|
||||
import org.eclipse.e4.core.di.annotations.Evaluate;
|
||||
import org.eclipse.e4.core.di.annotations.Execute;
|
||||
@ -22,10 +24,11 @@ import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.minres.scviewer.database.EmptyWaveform;
|
||||
import com.minres.scviewer.database.ui.TrackEntry;
|
||||
import com.minres.scviewer.database.ui.TrackEntry.HierState;
|
||||
import com.minres.scviewer.e4.application.parts.TextInputDialog;
|
||||
import com.minres.scviewer.e4.application.parts.WaveformViewer;
|
||||
|
||||
public class SetLabelTextHandler {
|
||||
public class WaveformDoubleClickTextHandler {
|
||||
|
||||
@Execute
|
||||
public void execute(Shell shell, EPartService partService) {
|
||||
@ -33,9 +36,10 @@ public class SetLabelTextHandler {
|
||||
if(part!=null && part.getObject() instanceof WaveformViewer){
|
||||
Object sel = ((WaveformViewer)part.getObject()).getSelection();
|
||||
if( sel instanceof IStructuredSelection) {
|
||||
Object o= ((IStructuredSelection)sel).getFirstElement();
|
||||
if(o instanceof TrackEntry) {
|
||||
TrackEntry te = (TrackEntry)o;
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<TrackEntry> o = ((IStructuredSelection)sel).toList().stream().filter(e -> e instanceof TrackEntry).findFirst();
|
||||
if(o.isPresent()) {
|
||||
TrackEntry te = o.get();
|
||||
if(te.waveform instanceof EmptyWaveform) {
|
||||
EmptyWaveform waveform= (EmptyWaveform)te.waveform;
|
||||
TextInputDialog dialog = new TextInputDialog(shell);
|
||||
@ -45,6 +49,10 @@ public class SetLabelTextHandler {
|
||||
if (dialog.open() == Window.OK) {
|
||||
waveform.setName(dialog.getText());
|
||||
}
|
||||
} else if(te.hierState==HierState.CLOSED) {
|
||||
te.hierState=HierState.OPENED;
|
||||
} else if(te.hierState==HierState.OPENED) {
|
||||
te.hierState=HierState.CLOSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,10 +67,11 @@ public class SetLabelTextHandler {
|
||||
Object sel = ((WaveformViewer)activePart.getObject()).getSelection();
|
||||
if( sel instanceof IStructuredSelection) {
|
||||
if(((IStructuredSelection)sel).isEmpty()) return false;
|
||||
Object o= ((IStructuredSelection)sel).getFirstElement();
|
||||
if(o instanceof TrackEntry) {
|
||||
TrackEntry te = (TrackEntry)o;
|
||||
return te.waveform instanceof EmptyWaveform;
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<TrackEntry> o = ((IStructuredSelection)sel).toList().stream().filter(e -> e instanceof TrackEntry).findFirst();
|
||||
if(o.isPresent()) {
|
||||
TrackEntry te = o.get();
|
||||
return te.waveform instanceof EmptyWaveform || te.hierState!=HierState.NONE;
|
||||
}
|
||||
}
|
||||
}
|
@ -418,7 +418,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||
waveformPane.addEventListner(new IWaveformviewEventListener() {
|
||||
@Override
|
||||
public void onTrackEntryDoubleClickEvent(TrackEntry trackEntry) {
|
||||
ParameterizedCommand command = commandService.createCommand(AppModelId.COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_SET_LABEL_TEXT);
|
||||
ParameterizedCommand command = commandService.createCommand(AppModelId.COMMAND_COM_MINRES_SCVIEWER_E4_APPLICATION_COMMAND_WAVE_DOUBLE_CLICK);
|
||||
handlerService.executeHandler(command);
|
||||
}
|
||||
});
|
||||
@ -1000,9 +1000,10 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||
for (IWaveform waveform : iWaveforms)
|
||||
waveformPane.addWaveform(waveform, -1);
|
||||
} else {
|
||||
Object first = selection.getFirstElement();
|
||||
if(first instanceof ITx) {
|
||||
TrackEntry trackEntry = waveformPane.getEntryFor((ITx) first);
|
||||
@SuppressWarnings("unchecked")
|
||||
java.util.Optional<TrackEntry> o = selection.toList().stream().filter(e -> e instanceof TrackEntry).findFirst();
|
||||
if(o.isPresent()) {
|
||||
TrackEntry trackEntry = o.get();
|
||||
if (insert) {
|
||||
int index = waveformPane.getStreamList().indexOf(trackEntry);
|
||||
for (IWaveform waveform : iWaveforms)
|
||||
@ -1011,18 +1012,8 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||
for (IWaveform waveform : iWaveforms)
|
||||
waveformPane.addWaveform(waveform, -1);
|
||||
}
|
||||
} else if(first instanceof TrackEntry) {
|
||||
TrackEntry trackEntry = (TrackEntry) first;
|
||||
if (insert) {
|
||||
int index = waveformPane.getStreamList().indexOf(trackEntry);
|
||||
for (IWaveform waveform : iWaveforms)
|
||||
waveformPane.addWaveform(waveform, index++);
|
||||
} else {
|
||||
for (IWaveform waveform : iWaveforms)
|
||||
waveformPane.addWaveform(waveform, -1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
showTxDetails(waveformPane.getStreamList().stream().filter(t -> t.waveform.getType() == WaveformType.TRANSACTION).findFirst().isPresent());
|
||||
setFocus();
|
||||
@ -1033,10 +1024,6 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
|
||||
showTxDetails(waveformPane.getStreamList().stream().filter(t -> t.waveform.getType() == WaveformType.TRANSACTION).findFirst().isPresent());
|
||||
}
|
||||
|
||||
public void removeSelectedStreamFromList() {
|
||||
waveformPane.deleteSelectedTracks();
|
||||
showTxDetails(waveformPane.getStreamList().stream().filter(t -> t.waveform.getType() == WaveformType.TRANSACTION).findFirst().isPresent());
|
||||
}
|
||||
/**
|
||||
* Move selected.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user