added: - history in combobox\n - settings in application
This commit is contained in:
parent
789317ea12
commit
cb384e1c51
@ -2,6 +2,9 @@ QT += core gui concurrent
|
|||||||
QT += KItemViews
|
QT += KItemViews
|
||||||
QT += KCompletion
|
QT += KCompletion
|
||||||
QT += widgets
|
QT += widgets
|
||||||
|
QT += KConfigCore KConfigGui
|
||||||
|
QT += KCoreAddons
|
||||||
|
QT += KDBusAddons
|
||||||
|
|
||||||
#LIBS += -lKF5WindowSystem
|
#LIBS += -lKF5WindowSystem
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
@ -1,19 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE TS>
|
<!DOCTYPE TS>
|
||||||
<TS version="2.1" language="fr_FR">
|
<TS version="2.1" language="fr_FR">
|
||||||
<context>
|
|
||||||
<name>Dialog</name>
|
|
||||||
<message>
|
|
||||||
<location filename="downloadProgress.ui" line="20"/>
|
|
||||||
<source>Dialog</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="downloadProgress.ui" line="32"/>
|
|
||||||
<source>TextLabel</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>MainWindow</name>
|
<name>MainWindow</name>
|
||||||
<message>
|
<message>
|
||||||
@ -40,28 +27,75 @@
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="mainwindow.ui" line="295"/>
|
<location filename="mainwindow.ui" line="295"/>
|
||||||
<source>debug</source>
|
<location filename="mainwindow.ui" line="312"/>
|
||||||
<translation>debug</translation>
|
<source>Menu</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="mainwindow.cpp" line="34"/>
|
<location filename="mainwindow.ui" line="301"/>
|
||||||
|
<source>help</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="mainwindow.ui" line="317"/>
|
||||||
|
<location filename="mainwindow.ui" line="320"/>
|
||||||
|
<source>Default save folder</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="mainwindow.ui" line="325"/>
|
||||||
|
<source>Bandwidth limit</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="mainwindow.ui" line="330"/>
|
||||||
|
<source>About</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="mainwindow.ui" line="335"/>
|
||||||
|
<source>About Qt</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>debug</source>
|
||||||
|
<translation type="vanished">debug</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="mainwindow.cpp" line="42"/>
|
||||||
<source>Path</source>
|
<source>Path</source>
|
||||||
<translation>Chemin</translation>
|
<translation>Chemin</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="mainwindow.cpp" line="34"/>
|
<location filename="mainwindow.cpp" line="42"/>
|
||||||
<source>Size</source>
|
<source>Size</source>
|
||||||
<translation>Taille</translation>
|
<translation>Taille</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="mainwindow.cpp" line="233"/>
|
<location filename="mainwindow.cpp" line="60"/>
|
||||||
|
<source>Exiting will stop downloading, and will clear the download queue.
|
||||||
|
Do you want to exit ?</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="mainwindow.cpp" line="281"/>
|
||||||
<source>server does not exists</source>
|
<source>server does not exists</source>
|
||||||
<translation>Le serveur n'existe pas</translation>
|
<translation>Le serveur n'existe pas</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="mainwindow.cpp" line="326"/>
|
<location filename="mainwindow.cpp" line="373"/>
|
||||||
<source>Choose directory to save file</source>
|
<source>Choose directory to save file</source>
|
||||||
<translation>Choisissez le dossier où enregistrer</translation>
|
<translation>Choisissez le dossier où enregistrer</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="mainwindow.cpp" line="419"/>
|
||||||
|
<source>Do you want to stop downloading and delete this file from download queue ?</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="mainwindow.cpp" line="431"/>
|
||||||
|
<source>Do you want to delete this file from download queue ?</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "downloadfile.h"
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
|
#include "downloadfile.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include <pstreams/pstream.h>
|
#include <pstreams/pstream.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -74,7 +74,7 @@ void downloadFile::download(MainWindow *mw)
|
|||||||
{
|
{
|
||||||
line.erase(0, pos);
|
line.erase(0, pos);
|
||||||
value = stoi(line);
|
value = stoi(line);
|
||||||
cout << value << endl;
|
//cout << value << endl;
|
||||||
emit progressSignal(value);
|
emit progressSignal(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
main.cpp
4
main.cpp
@ -1,6 +1,10 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <KAboutData>
|
||||||
|
#include <KDBusService>
|
||||||
|
#include <QTranslator>
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
106
mainwindow.cpp
106
mainwindow.cpp
@ -41,6 +41,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
ui->ktreewidgetsearchline->setCaseSensitivity(Qt::CaseInsensitive);
|
ui->ktreewidgetsearchline->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
ui->treeWidget->setHeaderLabels({tr("Path"), tr("Size")} );
|
ui->treeWidget->setHeaderLabels({tr("Path"), tr("Size")} );
|
||||||
ui->progressBar->hide();
|
ui->progressBar->hide();
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
populateList();
|
populateList();
|
||||||
@ -51,7 +52,6 @@ MainWindow::~MainWindow()
|
|||||||
{
|
{
|
||||||
QMessageBox::StandardButton reply;
|
QMessageBox::StandardButton reply;
|
||||||
|
|
||||||
|
|
||||||
if (ui->listDownload->count() != 0)
|
if (ui->listDownload->count() != 0)
|
||||||
{
|
{
|
||||||
reply = QMessageBox::question(
|
reply = QMessageBox::question(
|
||||||
@ -65,6 +65,7 @@ MainWindow::~MainWindow()
|
|||||||
emit (stopDownloading(this->downloading.pid));
|
emit (stopDownloading(this->downloading.pid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
saveSettings();
|
||||||
if (this->downloading.pid != 0)
|
if (this->downloading.pid != 0)
|
||||||
{
|
{
|
||||||
waitpid(this->downloading.pid, NULL, WUNTRACED);
|
waitpid(this->downloading.pid, NULL, WUNTRACED);
|
||||||
@ -79,36 +80,59 @@ void MainWindow::populateTree()
|
|||||||
|
|
||||||
if (!this->connexion.server.empty() and this->connexion.port > 0 and this->connexion.port < 65536)
|
if (!this->connexion.server.empty() and this->connexion.port > 0 and this->connexion.port < 65536)
|
||||||
{
|
{
|
||||||
|
QGuiApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
if (validateServer(this->connexion.server))
|
if (validateServer(this->connexion.server))
|
||||||
{
|
{
|
||||||
QGuiApplication::setOverrideCursor(Qt::WaitCursor);
|
|
||||||
path = explode(ui->listWidget->currentItem()->text().toStdString(), '\n', 2);
|
path = explode(ui->listWidget->currentItem()->text().toStdString(), '\n', 2);
|
||||||
scanDir(this->connexion.server, this->connexion.port, NULL, path[0].append("/") );
|
scanDir(this->connexion.server, this->connexion.port, NULL, path[0].append("/") );
|
||||||
this->unsetCursor();
|
|
||||||
QGuiApplication::setOverrideCursor(Qt::ArrowCursor);
|
|
||||||
}
|
}
|
||||||
|
QGuiApplication::setOverrideCursor(Qt::ArrowCursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::populateList()
|
void MainWindow::populateList()
|
||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
|
QString str;
|
||||||
|
QString server;
|
||||||
|
QString port;
|
||||||
|
|
||||||
this->connexion.server.assign(ui->khistorycombobox->currentText().toStdString());
|
server = ui->khistorycombobox->currentText();
|
||||||
|
this->connexion.server.assign(server.toStdString());
|
||||||
ss << ui->portEdit->text().toStdString();
|
ss << ui->portEdit->text().toStdString();
|
||||||
ss >> this->connexion.port;
|
ss >> this->connexion.port;
|
||||||
if (!this->connexion.server.empty() and this->connexion.port > 0 and this->connexion.port < 65536)
|
QGuiApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
|
||||||
|
this->settings.beginGroup("connexion/server");
|
||||||
|
if (this->settings.contains(server))
|
||||||
{
|
{
|
||||||
if (validateServer(this->connexion.server))
|
port = this->settings.value(server).toString();
|
||||||
|
ui->portEdit->setText(port);
|
||||||
|
this->connexion.port = this->settings.value(server).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!server.isEmpty() and this->connexion.port > 0 and this->connexion.port < 65536)
|
||||||
{
|
{
|
||||||
ui->khistorycombobox->addItem(this->connexion.server.c_str());
|
if (validateServer(server.toStdString()))
|
||||||
ui->centralwidget->cursor().setShape(Qt::WaitCursor);
|
{
|
||||||
|
//this->settings.beginGroup("connexion/server");
|
||||||
|
if (!this->settings.contains(server))
|
||||||
|
{
|
||||||
|
cout << server.toStdString() << endl;
|
||||||
|
// storing serverURL and port in settings
|
||||||
|
this->settings.setValue(server, this->connexion.port);
|
||||||
|
this->settings.sync();
|
||||||
|
|
||||||
|
// storing in history of combobox
|
||||||
|
ui->khistorycombobox->addToHistory(server);
|
||||||
|
}
|
||||||
|
// "waiting" cursor
|
||||||
|
// load and display rsync services of the rsync server
|
||||||
listServices();
|
listServices();
|
||||||
ui->centralwidget->cursor().setShape(Qt::ArrowCursor);
|
|
||||||
QStringList test = ui->khistorycombobox->historyItems();
|
|
||||||
sleep(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this->settings.endGroup();
|
||||||
|
QGuiApplication::setOverrideCursor(Qt::ArrowCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::listServices()
|
void MainWindow::listServices()
|
||||||
@ -119,11 +143,12 @@ void MainWindow::listServices()
|
|||||||
vector<string> v;
|
vector<string> v;
|
||||||
char service[4096];
|
char service[4096];
|
||||||
|
|
||||||
|
ui->listWidget->clear();
|
||||||
sprintf(cmd, "rsync --contimeout=10 -P \"%s::\" --port %d ", this->connexion.server.c_str(), this->connexion.port );
|
sprintf(cmd, "rsync --contimeout=10 -P \"%s::\" --port %d ", this->connexion.server.c_str(), this->connexion.port );
|
||||||
redi::ipstream in(cmd, redi::pstreams::pstdout | redi::pstreams::pstderr);
|
redi::ipstream in(cmd, redi::pstreams::pstdout | redi::pstreams::pstderr);
|
||||||
while (getline(in.out(), line))
|
while (getline(in.out(), line))
|
||||||
{
|
{
|
||||||
cout << "stdout: " << line << endl;
|
//cout << "stdout: " << line << endl;
|
||||||
boost::replace_all(line," ","");
|
boost::replace_all(line," ","");
|
||||||
boost::replace_all(line, "\t", " - ");
|
boost::replace_all(line, "\t", " - ");
|
||||||
v = explode(line, ' ', 3 );
|
v = explode(line, ' ', 3 );
|
||||||
@ -221,7 +246,7 @@ bool MainWindow::validateServer(string server)
|
|||||||
|
|
||||||
while (getline(in.out(), line))
|
while (getline(in.out(), line))
|
||||||
{
|
{
|
||||||
cout << "stdout: " << line << '\n';
|
//cout << "stdout: " << line << '\n';
|
||||||
if (line.find(";; ANSWER SECTION:") != string::npos)
|
if (line.find(";; ANSWER SECTION:") != string::npos)
|
||||||
{
|
{
|
||||||
flag = true;
|
flag = true;
|
||||||
@ -268,7 +293,16 @@ void MainWindow::displayTree()
|
|||||||
|
|
||||||
void MainWindow::on_khistorycombobox_returnPressed()
|
void MainWindow::on_khistorycombobox_returnPressed()
|
||||||
{
|
{
|
||||||
populateList();
|
//populateList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_khistorycombobox_currentIndexChanged(int i)
|
||||||
|
{
|
||||||
|
/*QString server = ui->khistorycombobox->currentText();
|
||||||
|
this->settings.beginGroup("connexion/server");
|
||||||
|
ui->portEdit->setText(this->settings.value(server).toString());
|
||||||
|
this->settings.endGroup();*/
|
||||||
|
this->populateList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_portEdit_returnPressed()
|
void MainWindow::on_portEdit_returnPressed()
|
||||||
@ -276,16 +310,6 @@ void MainWindow::on_portEdit_returnPressed()
|
|||||||
populateList();
|
populateList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_treeWidget_customContextMenuRequested()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_actionDownload_triggered()
|
void MainWindow::on_actionDownload_triggered()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -387,7 +411,7 @@ void MainWindow::on_listDownload_itemClicked(QListWidgetItem *item)
|
|||||||
QFileDialog dialog;
|
QFileDialog dialog;
|
||||||
QMessageBox::StandardButton reply;
|
QMessageBox::StandardButton reply;
|
||||||
|
|
||||||
cout << item->text().toStdString() << endl;
|
//cout << item->text().toStdString() << endl;
|
||||||
if (item->listWidget()->row(item) == 0)
|
if (item->listWidget()->row(item) == 0)
|
||||||
{
|
{
|
||||||
reply = QMessageBox::question(
|
reply = QMessageBox::question(
|
||||||
@ -418,10 +442,36 @@ void MainWindow::on_listDownload_itemClicked(QListWidgetItem *item)
|
|||||||
|
|
||||||
void MainWindow::loadSettings()
|
void MainWindow::loadSettings()
|
||||||
{
|
{
|
||||||
this->settings.value("serverlist");
|
this->restoreGeometry(settings.value("window/geometry").toByteArray());
|
||||||
|
this->settings.beginGroup("connexion/server");
|
||||||
|
|
||||||
|
QStringList servers = this->settings.allKeys();
|
||||||
|
this->settings.endGroup();
|
||||||
|
|
||||||
|
for( const QString &server : servers )
|
||||||
|
{
|
||||||
|
ui->khistorycombobox->addToHistory(server);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::saveSettings()
|
void MainWindow::saveSettings()
|
||||||
{
|
{
|
||||||
//ui->khistorycombobox->
|
this->settings.setValue("window/geometry", saveGeometry());
|
||||||
|
this->settings.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionAbout_triggered()
|
||||||
|
{
|
||||||
|
QString text = this->about.description + "\n\n" +
|
||||||
|
"Licence: " + this->about.licence + "\n" +
|
||||||
|
"Author: " + this->about.author + "\n" +
|
||||||
|
"EMail : " + this->about.email + "\n" +
|
||||||
|
"Source code: " + this->about.git;
|
||||||
|
QMessageBox::about(this, this->about.title, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionAbout_Qt_triggered()
|
||||||
|
{
|
||||||
|
QMessageBox::aboutQt(this);
|
||||||
}
|
}
|
||||||
|
25
mainwindow.h
25
mainwindow.h
@ -8,6 +8,7 @@
|
|||||||
#include "downloadfile.h"
|
#include "downloadfile.h"
|
||||||
#include <QProgressDialog>
|
#include <QProgressDialog>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
namespace Ui { class MainWindow; }
|
namespace Ui { class MainWindow; }
|
||||||
@ -32,6 +33,17 @@ class Downloading
|
|||||||
int pid = 0;
|
int pid = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class About
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString title = "RsyncUI";
|
||||||
|
QString author = "Daniel TARTAVEL-JEANNOT";
|
||||||
|
QString licence = "GPL_V3";
|
||||||
|
QString description = "Client for rsync server";
|
||||||
|
QString email = "dtux@free.fr";
|
||||||
|
QString git = "https://git.labolyon.fr/dtux/RsyncUI/issues";
|
||||||
|
};
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -58,6 +70,9 @@ class MainWindow : public QMainWindow
|
|||||||
Downloading downloading;
|
Downloading downloading;
|
||||||
downloadFile downloadO;
|
downloadFile downloadO;
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
About about;
|
||||||
|
|
||||||
|
std::vector <QString> serversList;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_khistorycombobox_returnPressed();
|
void on_khistorycombobox_returnPressed();
|
||||||
@ -66,10 +81,6 @@ class MainWindow : public QMainWindow
|
|||||||
|
|
||||||
void on_portEdit_returnPressed();
|
void on_portEdit_returnPressed();
|
||||||
|
|
||||||
void on_treeWidget_itemClicked(QTreeWidgetItem *item, int column);
|
|
||||||
|
|
||||||
void on_treeWidget_customContextMenuRequested();
|
|
||||||
|
|
||||||
void on_actionDownload_triggered();
|
void on_actionDownload_triggered();
|
||||||
|
|
||||||
void on_listWidget_clicked(const QModelIndex &index);
|
void on_listWidget_clicked(const QModelIndex &index);
|
||||||
@ -82,6 +93,12 @@ class MainWindow : public QMainWindow
|
|||||||
|
|
||||||
void on_listDownload_itemClicked(QListWidgetItem *item);
|
void on_listDownload_itemClicked(QListWidgetItem *item);
|
||||||
|
|
||||||
|
void on_actionAbout_triggered();
|
||||||
|
|
||||||
|
void on_actionAbout_Qt_triggered();
|
||||||
|
|
||||||
|
void on_khistorycombobox_currentIndexChanged(int i);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void stopDownloading(int);
|
void stopDownloading(int);
|
||||||
|
|
||||||
|
@ -296,7 +296,15 @@
|
|||||||
</property>
|
</property>
|
||||||
<addaction name="DefaultSaveFolder"/>
|
<addaction name="DefaultSaveFolder"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuhelp">
|
||||||
|
<property name="title">
|
||||||
|
<string>help</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionAbout"/>
|
||||||
|
<addaction name="actionAbout_Qt"/>
|
||||||
|
</widget>
|
||||||
<addaction name="menu"/>
|
<addaction name="menu"/>
|
||||||
|
<addaction name="menuhelp"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
<action name="actionMenu">
|
<action name="actionMenu">
|
||||||
@ -317,6 +325,16 @@
|
|||||||
<string>Bandwidth limit</string>
|
<string>Bandwidth limit</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionAbout">
|
||||||
|
<property name="text">
|
||||||
|
<string>About</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionAbout_Qt">
|
||||||
|
<property name="text">
|
||||||
|
<string>About Qt</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
Loading…
Reference in New Issue
Block a user