Add Delete operation in GridAccount
Fix a bug : Forgot to update stats when there is a modification
This commit is contained in:
parent
a9bcdcc733
commit
6c4ee9dec3
|
@ -467,6 +467,10 @@ void KissCount::GetMonthStats(int month, int year, int nbDays,
|
|||
_db->GetMonthStats(_user, month, year, nbDays, operations, categories);
|
||||
}
|
||||
|
||||
void KissCount::UpdateStats()
|
||||
{
|
||||
_wxUI->UpdateStats();
|
||||
}
|
||||
|
||||
std::map<int, double>* KissCount::GetNotChecked(int month, int year)
|
||||
{
|
||||
|
|
|
@ -113,7 +113,8 @@ public:
|
|||
void GetMonthStats(int month, int year, int nbDays,
|
||||
std::map<int, std::vector<double> >* operations,
|
||||
std::map<int, double>* categories);
|
||||
|
||||
void UpdateStats();
|
||||
|
||||
std::map<int, double>* GetNotChecked(int month, int year);
|
||||
std::map<int, double>* GetVirtualAmount(int month, int year);
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ enum {CUR_CREDIT, CUR_DEBIT, TOTAL_CREDIT, TOTAL_DEBIT, BALANCE, STATS_ROW, CATS
|
|||
|
||||
enum {VIRTUAL_MODE=0, REAL_MODE, CHECK_MODE};
|
||||
|
||||
AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _curMonth(-1), _curYear(-1)
|
||||
AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _curMonth(-1), _curYear(-1), _inModification(false)
|
||||
{
|
||||
QHBoxLayout *hbox = new QHBoxLayout;
|
||||
QHBoxLayout *hbox2 = new QHBoxLayout;
|
||||
|
@ -521,6 +521,8 @@ void AccountPanel::UpdateStats()
|
|||
bool blocked_account ;
|
||||
QString v;
|
||||
|
||||
_inModification = true;
|
||||
|
||||
if (_virtual->isChecked()) mode = VIRTUAL_MODE;
|
||||
else if (_real->isChecked()) mode = REAL_MODE;
|
||||
else if (_check->isChecked()) mode = CHECK_MODE;
|
||||
|
@ -754,6 +756,8 @@ void AccountPanel::UpdateStats()
|
|||
_statsGrid->resizeColumnToContents(1);
|
||||
|
||||
layout();
|
||||
|
||||
_inModification = false;
|
||||
}
|
||||
|
||||
void AccountPanel::OnOperationModified()
|
||||
|
@ -769,20 +773,14 @@ void AccountPanel::OnAccountModified(int row, int column)
|
|||
double amount;
|
||||
int id = user->GetAccountId(_accounts[row]);
|
||||
|
||||
static bool inModification = false;
|
||||
|
||||
if (inModification || column != ACCOUNT_INIT) return;
|
||||
if (_inModification || column != ACCOUNT_INIT) return;
|
||||
|
||||
inModification = true;
|
||||
|
||||
amount = _accountsGrid->item(row, column)->text().toDouble();
|
||||
|
||||
_kiss->SetAccountAmount(id, _curMonth, _curYear, amount);
|
||||
_accountsInitValues[id] = amount;
|
||||
|
||||
UpdateStats();
|
||||
|
||||
inModification = false;
|
||||
}
|
||||
|
||||
void AccountPanel::OnTreeRightClick(const QPoint & pos)
|
||||
|
|
|
@ -20,13 +20,6 @@
|
|||
#ifndef ACCOUNTPANEL_H
|
||||
#define ACCOUNTPANEL_H
|
||||
|
||||
// #include <wx/wx.h>
|
||||
// #include <wx/grid.h>
|
||||
// #include <wx/treectrl.h>
|
||||
// #include <wx/pie/pieplot.h>
|
||||
// #include <wx/chartpanel.h>
|
||||
// #include <wx/radiobox.h>
|
||||
|
||||
#include <QTreeWidget>
|
||||
#include <QCalendarWidget>
|
||||
#include <QTableWidget>
|
||||
|
@ -38,8 +31,6 @@
|
|||
|
||||
#include <model/model.hpp>
|
||||
#include "grid/GridAccount.hpp"
|
||||
// #include "grid/CalendarEditor.hpp"
|
||||
// #include <wx/category/categorysimpledataset.h>
|
||||
|
||||
class GridAccount;
|
||||
|
||||
|
@ -60,6 +51,7 @@ public:
|
|||
void LoadYear(int year, bool showMonth=true);
|
||||
void ShowMonth(int month, int year);
|
||||
void GenerateMonth(int month, int year);
|
||||
void UpdateStats();
|
||||
|
||||
int _curMonth, _curYear;
|
||||
|
||||
|
@ -91,10 +83,10 @@ private:
|
|||
QStandardItemModel* _dataset;
|
||||
int _fixCosts;
|
||||
QRadioButton *_virtual, *_real, *_check;
|
||||
bool _inModification;
|
||||
|
||||
void InitStatsGrid(User* user);
|
||||
void InitAccountsGrid(User* user, int month, int year);
|
||||
void UpdateStats();
|
||||
void InsertOperation(User* user, Operation* op, int line, bool fix);
|
||||
void GetTreeSelection(int* month, int* year);
|
||||
};
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
*/
|
||||
|
||||
#include <QtGui>
|
||||
#include <QHeaderView>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
|
||||
#include "GridAccount.hpp"
|
||||
#include "TableViewDelegate.hpp"
|
||||
|
@ -30,6 +27,8 @@
|
|||
#include "FormulaDelegate.hpp"
|
||||
#include "TabDelegate.hpp"
|
||||
|
||||
enum {TREE, DESCRIPTION, OP_DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, OP_DELETE, CHECKED, NUMBER_COLS_OPS};
|
||||
|
||||
#define SET_ROW_COLOR(row, backcolor, forecolor) for(int i=0; i<NUMBER_COLS_OPS; i++) \
|
||||
{ \
|
||||
if (!this->item(row, i)) setItem(row, i, new QTableWidgetItem("")); \
|
||||
|
@ -51,8 +50,8 @@ GridAccount::GridAccount(KissCount* kiss, QWidget *parent,
|
|||
_week2(0), _week3(0), _week4(0), _week5(0), _canAddOperation(canAddOperation),
|
||||
_parent(parent), _kiss(kiss), _setWeek(setWeek),
|
||||
_databaseSynchronization(synchronizeWithDatabase), _loadOperations(false),
|
||||
_curMonth(0), _curYear(0), _buttonSignalMapper(this), _checkSignalMapper(this),
|
||||
_inModification(false)
|
||||
_curMonth(0), _curYear(0), _treeSignalMapper(this), _checkSignalMapper(this),
|
||||
_deleteSignalMapper(this), _inModification(false)
|
||||
{
|
||||
//DEFAULT_FONT(font);
|
||||
QFont font;
|
||||
|
@ -117,8 +116,9 @@ GridAccount::GridAccount(KissCount* kiss, QWidget *parent,
|
|||
resizeColumnToContents(OP_DELETE);
|
||||
resizeColumnToContents(CHECKED);
|
||||
|
||||
connect(&_buttonSignalMapper, SIGNAL(mapped(int)), this, SLOT(OnMetaClicked(int)));
|
||||
connect(&_treeSignalMapper, SIGNAL(mapped(int)), this, SLOT(OnMetaClicked(int)));
|
||||
connect(&_checkSignalMapper, SIGNAL(mapped(int)), this, SLOT(OnCheckClicked(int)));
|
||||
connect(&_deleteSignalMapper, SIGNAL(mapped(int)), this, SLOT(OnDeleteClicked(int)));
|
||||
setItemDelegate(new TableViewDelegate(this));
|
||||
connect(this, SIGNAL(cellChanged(int, int)), this, SLOT(OnOperationModified(int, int)));
|
||||
}
|
||||
|
@ -360,6 +360,12 @@ void GridAccount::InsertOperation(User* user, Operation& op, int line, bool fix,
|
|||
if (!fix && !op.meta)
|
||||
setItem(line, CATEGORY, new QTableWidgetItem(_(cat.name.toStdString().c_str())));
|
||||
|
||||
checkBox = new QCheckBox();
|
||||
checkBox->setTristate(false);
|
||||
setCellWidget(line, OP_DELETE, checkBox);
|
||||
_deleteSignalMapper.setMapping(checkBox, op.id);
|
||||
connect(checkBox, SIGNAL(stateChanged(int)), &_deleteSignalMapper, SLOT(map()));
|
||||
|
||||
checkBox = new QCheckBox();
|
||||
checkBox->setTristate(false);
|
||||
setCellWidget(line, CHECKED, checkBox);
|
||||
|
@ -432,8 +438,8 @@ void GridAccount::InsertOperation(User* user, Operation& op, int line, bool fix,
|
|||
{
|
||||
int height = rowHeight(TREE);
|
||||
QPushButton* button = new QPushButton("+");
|
||||
_buttonSignalMapper.setMapping(button, op.id);
|
||||
connect(button, SIGNAL(clicked()), &_buttonSignalMapper, SLOT(map()));
|
||||
_treeSignalMapper.setMapping(button, op.id);
|
||||
connect(button, SIGNAL(clicked()), &_treeSignalMapper, SLOT(map()));
|
||||
|
||||
button->setMaximumSize(QSize(height, height));
|
||||
setCellWidget(line, TREE, button);
|
||||
|
@ -537,7 +543,6 @@ int GridAccount::RemoveMeta(Operation op, int line, bool removeRoot, bool delete
|
|||
int i, deletedOperations = 0;
|
||||
Operation op2;
|
||||
QPushButton* button = qobject_cast<QPushButton*> (cellWidget(line, TREE));
|
||||
QCheckBox* checkBox = qobject_cast<QCheckBox*> (cellWidget(line, CHECKED));
|
||||
|
||||
for(i=0; i<(int)op.childs.size(); i++)
|
||||
{
|
||||
|
@ -567,10 +572,12 @@ int GridAccount::RemoveMeta(Operation op, int line, bool removeRoot, bool delete
|
|||
|
||||
if (removeRoot)
|
||||
{
|
||||
removeRow(line);
|
||||
button->disconnect(&_buttonSignalMapper, SLOT(map()));
|
||||
button->disconnect(&_treeSignalMapper, SLOT(map()));
|
||||
QCheckBox* checkBox = qobject_cast<QCheckBox*> (cellWidget(line, CHECKED));
|
||||
checkBox->disconnect(&_checkSignalMapper, SLOT(map()));
|
||||
removeCellWidget(line, TREE);
|
||||
checkBox = qobject_cast<QCheckBox*> (cellWidget(line, OP_DELETE));
|
||||
checkBox->disconnect(&_deleteSignalMapper, SLOT(map()));
|
||||
removeRow(line);
|
||||
_displayedOperations.erase(_displayedOperations.begin()+line);
|
||||
if (op.fix_cost) _fixCosts--;
|
||||
if (deleteOp)
|
||||
|
@ -626,7 +633,7 @@ void GridAccount::CheckMeta(Operation& op, int line, bool check)
|
|||
|
||||
void GridAccount::OnMetaClicked(int id)
|
||||
{
|
||||
QPushButton* button = qobject_cast<QPushButton*> (_buttonSignalMapper.mapping(id));
|
||||
QPushButton* button = qobject_cast<QPushButton*> (_treeSignalMapper.mapping(id));
|
||||
std::vector<Operation>::iterator it;
|
||||
std::vector<int>::iterator it2;
|
||||
int i, row;
|
||||
|
@ -673,6 +680,102 @@ void GridAccount::OnCheckClicked(int id)
|
|||
row = it-_displayedOperations.begin();
|
||||
_displayedOperations[row].checked = (checkBox->checkState() == Qt::Checked);
|
||||
OnOperationModified(row, CHECKED);
|
||||
|
||||
_kiss->UpdateStats();
|
||||
}
|
||||
|
||||
void GridAccount::OnDeleteClicked(int id)
|
||||
{
|
||||
std::vector<Operation>::iterator it;
|
||||
std::vector<int>::iterator it2;
|
||||
int row;
|
||||
User* user = _kiss->GetUser();
|
||||
Operation op, op_tmp, op_tmp2;
|
||||
QColor color;
|
||||
unsigned char r, g, b;
|
||||
|
||||
if (_inModification || _loadOperations) return;
|
||||
|
||||
QCheckBox* checkBox = qobject_cast<QCheckBox*> (_deleteSignalMapper.mapping(id));
|
||||
|
||||
if (checkBox->checkState() == Qt::Unchecked) return;
|
||||
|
||||
it = std::find(_displayedOperations.begin(), _displayedOperations.end(), id);
|
||||
|
||||
if (it == _displayedOperations.end()) return ;
|
||||
|
||||
if (QMessageBox::question(0, "KissCount", _("Are you sure want to delete : \n")+it->description, QMessageBox::Yes|QMessageBox::No) == QMessageBox::No)
|
||||
{
|
||||
checkBox->setCheckState(Qt::Unchecked);
|
||||
return;
|
||||
}
|
||||
|
||||
op = *it; // Make a copy
|
||||
|
||||
_inModification = true;
|
||||
|
||||
row = it-_displayedOperations.begin();
|
||||
|
||||
if (op.parent)
|
||||
user->UnGroup(_displayedOperations[row]);
|
||||
|
||||
if (op.meta)
|
||||
RemoveMeta(_displayedOperations[row], row, true, true);
|
||||
else
|
||||
{
|
||||
if (op.parent)
|
||||
{
|
||||
op_tmp = GetOperation(op.parent);
|
||||
it2 = std::find(op_tmp.childs.begin(), op_tmp.childs.end(), op.id);
|
||||
if (it2 != op_tmp.childs.end())
|
||||
op_tmp.childs.erase(it2);
|
||||
}
|
||||
|
||||
removeRow(row);
|
||||
DeleteOperation(*it);
|
||||
if (_databaseSynchronization)
|
||||
_kiss->DeleteOperation(*it);
|
||||
_displayedOperations.erase(_displayedOperations.begin()+row);
|
||||
|
||||
if (op.parent && op_tmp.childs.size() < 2)
|
||||
{
|
||||
if (op.childs.size() == 1)
|
||||
{
|
||||
op_tmp2 = GetOperation(op_tmp.childs[0]);
|
||||
op_tmp2.parent = 0;
|
||||
UpdateOperation(op_tmp2);
|
||||
row = GetDisplayedRow(op_tmp2.id);
|
||||
_displayedOperations[row] = op_tmp2;
|
||||
}
|
||||
row = GetDisplayedRow(op.parent);
|
||||
removeRow(row);
|
||||
DeleteOperation(op_tmp);
|
||||
if (_databaseSynchronization)
|
||||
_kiss->DeleteOperation(op_tmp);
|
||||
_displayedOperations.erase(_displayedOperations.begin()+row);
|
||||
if (op.fix_cost)
|
||||
_fixCosts--;
|
||||
setItem(row, DESCRIPTION, new QTableWidgetItem(op.description)); // Remove tabulation
|
||||
color = user->GetCategory(op.category).backcolor;
|
||||
|
||||
if (op.checked)
|
||||
{
|
||||
r = ((color.red()*1.5) >= 0xFF) ? 0xFF : color.red()*1.5 ;
|
||||
g = ((color.green()*1.5) >= 0xFF) ? 0xFF : color.green()*1.5 ;
|
||||
b = ((color.blue()*1.5) >= 0xFF) ? 0xFF : color.blue()*1.5 ;
|
||||
color.setRgb(r, g, b);
|
||||
}
|
||||
|
||||
SET_ROW_COLOR(row, color, user->GetCategory(op.category).forecolor);
|
||||
SET_ROW_FONT(row, user->GetCategoryFont(op.category));
|
||||
}
|
||||
if (op.fix_cost)
|
||||
_fixCosts--;
|
||||
ComputeWeeks();
|
||||
}
|
||||
|
||||
_kiss->UpdateStats();
|
||||
_inModification = false;
|
||||
}
|
||||
|
||||
void GridAccount::OnOperationModified(int row, int col)
|
||||
|
@ -840,70 +943,9 @@ void GridAccount::OnOperationModified(int row, int col)
|
|||
SET_ROW_FONT(row, user->GetCategoryFont(new_op.category));
|
||||
}
|
||||
|
||||
if (col == OP_DELETE)
|
||||
{
|
||||
if (QMessageBox::question(0, "KissCount", _("Are you sure want to delete : \n")+new_op.description, QMessageBox::Yes|QMessageBox::No) == QMessageBox::No)
|
||||
{
|
||||
//SetCellValue(row, col, wxT("0"));
|
||||
_inModification = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Modify a fix operation
|
||||
if (row < _fixCosts || !_canAddOperation)
|
||||
{
|
||||
if (col == OP_DELETE)
|
||||
{
|
||||
if (cur_op.parent)
|
||||
user->UnGroup(_displayedOperations[row]);
|
||||
|
||||
if (cur_op.meta)
|
||||
RemoveMeta(_displayedOperations[row], row, true, true);
|
||||
else
|
||||
{
|
||||
if (cur_op.parent)
|
||||
{
|
||||
op_tmp = GetOperation(cur_op.parent);
|
||||
for (int a=0; a<(int)op_tmp.childs.size(); a++)
|
||||
if (op_tmp.childs[a] == op.id)
|
||||
{
|
||||
op2.childs.erase(op_tmp.childs.begin()+a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
removeRow(row);
|
||||
DeleteOperation(cur_op);
|
||||
if (_databaseSynchronization)
|
||||
_kiss->DeleteOperation(cur_op);
|
||||
_displayedOperations.erase(_displayedOperations.begin()+row);
|
||||
|
||||
if (cur_op.parent && op_tmp.childs.size() < 2)
|
||||
{
|
||||
if (op_tmp.childs.size() == 1)
|
||||
{
|
||||
op_tmp2 = GetOperation(op_tmp.childs[0]);
|
||||
op_tmp2.parent = 0;
|
||||
UpdateOperation(op_tmp2);
|
||||
row = GetDisplayedRow(op_tmp2.id);
|
||||
_displayedOperations[row] = op_tmp2;
|
||||
}
|
||||
row = GetDisplayedRow(cur_op.parent);
|
||||
removeRow(row);
|
||||
DeleteOperation(op_tmp);
|
||||
if (_databaseSynchronization)
|
||||
_kiss->DeleteOperation(op_tmp);
|
||||
_displayedOperations.erase(_displayedOperations.begin()+row);
|
||||
_fixCosts--;
|
||||
}
|
||||
_fixCosts--;
|
||||
ComputeWeeks();
|
||||
}
|
||||
_inModification = false ;
|
||||
return ;
|
||||
}
|
||||
|
||||
new_op.id = cur_op.id;
|
||||
new_op.fix_cost = true;
|
||||
new_op.transfert = cur_op.transfert;
|
||||
|
@ -962,56 +1004,6 @@ void GridAccount::OnOperationModified(int row, int col)
|
|||
new_op.childs = cur_op.childs;
|
||||
new_op._virtual = cur_op._virtual;
|
||||
|
||||
if (col == OP_DELETE)
|
||||
{
|
||||
if (cur_op.parent)
|
||||
user->UnGroup(_displayedOperations[row]);
|
||||
|
||||
if (cur_op.meta)
|
||||
RemoveMeta(_displayedOperations[row], row, true, true);
|
||||
else
|
||||
{
|
||||
if (cur_op.parent)
|
||||
{
|
||||
op_tmp = GetOperation(cur_op.parent);
|
||||
for (int a=0; a<(int)op_tmp.childs.size(); a++)
|
||||
if (op_tmp.childs[a] == op.id)
|
||||
{
|
||||
op2.childs.erase(op_tmp.childs.begin()+a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
removeRow(row);
|
||||
DeleteOperation(cur_op);
|
||||
_displayedOperations.erase(_displayedOperations.begin()+row);
|
||||
if (_databaseSynchronization)
|
||||
_kiss->DeleteOperation(cur_op);
|
||||
|
||||
if (cur_op.parent && op_tmp.childs.size() <= 1)
|
||||
{
|
||||
if (op_tmp.childs.size() == 1)
|
||||
{
|
||||
op_tmp2 = GetOperation(op_tmp.childs[0]);
|
||||
op_tmp2.parent = 0;
|
||||
UpdateOperation(op_tmp2);
|
||||
row = GetDisplayedRow(op_tmp2.id);
|
||||
_displayedOperations[row] = op_tmp2;
|
||||
}
|
||||
row = GetDisplayedRow(cur_op.parent);
|
||||
removeRow(row);
|
||||
DeleteOperation(op_tmp);
|
||||
if (_databaseSynchronization)
|
||||
_kiss->DeleteOperation(op_tmp);
|
||||
_displayedOperations.erase(_displayedOperations.begin()+row);
|
||||
}
|
||||
|
||||
ComputeWeeks();
|
||||
}
|
||||
_inModification = false ;
|
||||
return ;
|
||||
}
|
||||
|
||||
if (cur_op.day != new_op.day)
|
||||
{
|
||||
need_insertion = true;
|
||||
|
@ -1142,6 +1134,7 @@ void GridAccount::OnOperationModified(int row, int col)
|
|||
}
|
||||
}
|
||||
|
||||
_kiss->UpdateStats();
|
||||
_inModification = false ;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
|
||||
class KissCount;
|
||||
|
||||
enum {TREE, DESCRIPTION, OP_DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, OP_DELETE, CHECKED, NUMBER_COLS_OPS};
|
||||
|
||||
typedef void (*updateOperationFunc)(Operation* op, void** params);
|
||||
|
||||
class GridAccount : public QTableWidget
|
||||
|
@ -66,6 +64,7 @@ private slots:
|
|||
void OnOperationModified(int row, int col);
|
||||
void OnMetaClicked(int id);
|
||||
void OnCheckClicked(int id);
|
||||
void OnDeleteClicked(int id);
|
||||
|
||||
private:
|
||||
QWidget* _parent;
|
||||
|
@ -77,7 +76,7 @@ private:
|
|||
std::vector<Operation>* _operations;
|
||||
bool _loadOperations;
|
||||
int _curMonth, _curYear;
|
||||
QSignalMapper _buttonSignalMapper, _checkSignalMapper;
|
||||
QSignalMapper _treeSignalMapper, _checkSignalMapper, _deleteSignalMapper;
|
||||
bool _inModification;
|
||||
|
||||
void SetWeek(int week, int line);
|
||||
|
|
|
@ -22,16 +22,11 @@
|
|||
#include "AccountPanel.hpp"
|
||||
/*#include "PreferencesPanel.hpp"
|
||||
#include "UsersDialog.hpp"
|
||||
#include "GenerateDialog.hpp"
|
||||
#include "SearchPanel.hpp"
|
||||
#include "StatsPanel.hpp"
|
||||
#include "ImportPanel.hpp"
|
||||
#include "ExportPanel.hpp"
|
||||
|
||||
#include "grid/wxMyGrid.hpp"
|
||||
#include "grid/wxGridCellFastBoolEditor.hpp"
|
||||
#include "grid/wxGridCellButtonRenderer.hpp"
|
||||
#include "grid/wxGridCellButtonEditor.hpp"
|
||||
*/
|
||||
#include "wxUI.hpp"
|
||||
#include "view.hpp"
|
||||
|
@ -279,6 +274,12 @@ void wxUI::GenerateMonth(int month, int year)
|
|||
(dynamic_cast<AccountPanel*>(_panels[0]))->GenerateMonth(month, year);
|
||||
}
|
||||
|
||||
void wxUI::UpdateStats()
|
||||
{
|
||||
if (_curPanel == _panels[0])
|
||||
(dynamic_cast<AccountPanel*>(_panels[0]))->UpdateStats();
|
||||
}
|
||||
|
||||
void wxUI::KillMe()
|
||||
{
|
||||
std::vector<KissPanel*>::iterator it;
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
void ShowSearch();
|
||||
void ShowPreferences();
|
||||
void GenerateMonth(int month, int year);
|
||||
void UpdateStats();
|
||||
|
||||
void KillMe();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user