mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-22 04:24:23 +00:00
FEATURE: Added "Added/Completed On" columns to transfer list
This commit is contained in:
parent
ba27191b2a
commit
fb79146ae6
@ -1,7 +1,7 @@
|
|||||||
* Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.2.0
|
* Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.2.0
|
||||||
- FEATURE: User can set alternative speed limits for fast toggling
|
- FEATURE: User can set alternative speed limits for fast toggling
|
||||||
- FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period)
|
- FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period)
|
||||||
- FEATURE: Added back file prioritizing in a torrent
|
- FEATURE: Added "Added/Completed On" columns to transfer list
|
||||||
|
|
||||||
* Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0
|
* Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0
|
||||||
- FEATURE: Graphical User Interface can be disabled at compilation time (headless running)
|
- FEATURE: Graphical User Interface can be disabled at compilation time (headless running)
|
||||||
|
@ -1948,6 +1948,8 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
|
|||||||
if(h.is_valid()){
|
if(h.is_valid()){
|
||||||
QString hash = h.hash();
|
QString hash = h.hash();
|
||||||
qDebug("%s have just finished checking", hash.toLocal8Bit().data());
|
qDebug("%s have just finished checking", hash.toLocal8Bit().data());
|
||||||
|
// Save seed status
|
||||||
|
TorrentPersistentData::saveSeedStatus(h);
|
||||||
// Move to temp directory if necessary
|
// Move to temp directory if necessary
|
||||||
if(!h.is_seed() && !defaultTempPath.isEmpty()) {
|
if(!h.is_seed() && !defaultTempPath.isEmpty()) {
|
||||||
// Check if directory is different
|
// Check if directory is different
|
||||||
|
@ -494,6 +494,8 @@ void QTorrentHandle::prioritize_files(std::vector<int> v) {
|
|||||||
if(v.size() != (unsigned int)h.get_torrent_info().num_files())
|
if(v.size() != (unsigned int)h.get_torrent_info().num_files())
|
||||||
return;
|
return;
|
||||||
h.prioritize_files(v);
|
h.prioritize_files(v);
|
||||||
|
// Save seed status
|
||||||
|
TorrentPersistentData::saveSeedStatus(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTorrentHandle::set_ratio(float ratio) const {
|
void QTorrentHandle::set_ratio(float ratio) const {
|
||||||
@ -551,6 +553,8 @@ void QTorrentHandle::move_storage(QString new_path) const {
|
|||||||
void QTorrentHandle::file_priority(int index, int priority) const {
|
void QTorrentHandle::file_priority(int index, int priority) const {
|
||||||
Q_ASSERT(h.is_valid());
|
Q_ASSERT(h.is_valid());
|
||||||
h.file_priority(index, priority);
|
h.file_priority(index, priority);
|
||||||
|
// Save seed status
|
||||||
|
TorrentPersistentData::saveSeedStatus(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIBTORRENT_0_15
|
#ifdef LIBTORRENT_0_15
|
||||||
|
@ -202,6 +202,48 @@ public:
|
|||||||
return all_data.keys();
|
return all_data.keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setAddedDate(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[hash].toHash();
|
||||||
|
if(!data.contains("add_date")) {
|
||||||
|
data.insert("add_date", QDateTime::currentDateTime());
|
||||||
|
all_data[hash] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QDateTime getAddedDate(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[hash].toHash();
|
||||||
|
QDateTime dt = data.value("add_date", QDateTime()).toDateTime();
|
||||||
|
if(!dt.isValid()) {
|
||||||
|
setAddedDate(hash);
|
||||||
|
dt = QDateTime::currentDateTime();
|
||||||
|
}
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void saveSeedDate(QTorrentHandle h) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[h.hash()].toHash();
|
||||||
|
if(h.is_seed())
|
||||||
|
data.insert("seed_date", QDateTime::currentDateTime());
|
||||||
|
else
|
||||||
|
data.insert("seed_date", QDateTime());
|
||||||
|
all_data[h.hash()] = data;
|
||||||
|
settings.setValue("torrents", all_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QDateTime getSeedDate(QString hash) {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
|
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
|
||||||
|
QHash<QString, QVariant> data = all_data[hash].toHash();
|
||||||
|
return data.value("seed_date", QDateTime()).toDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
static void deletePersistentData(QString hash) {
|
static void deletePersistentData(QString hash) {
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
|
||||||
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
|
QHash<QString, QVariant> all_data = settings.value("torrents", QHash<QString, QVariant>()).toHash();
|
||||||
@ -232,6 +274,8 @@ public:
|
|||||||
all_data[h.hash()] = data;
|
all_data[h.hash()] = data;
|
||||||
settings.setValue("torrents", all_data);
|
settings.setValue("torrents", all_data);
|
||||||
qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", h.save_path().toLocal8Bit().data(), h.hash().toLocal8Bit().data());
|
qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", h.save_path().toLocal8Bit().data(), h.hash().toLocal8Bit().data());
|
||||||
|
// Set Added date
|
||||||
|
setAddedDate(h.hash());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setters
|
// Setters
|
||||||
@ -283,6 +327,8 @@ public:
|
|||||||
data["seed"] = h.is_seed();
|
data["seed"] = h.is_seed();
|
||||||
all_data[h.hash()] = data;
|
all_data[h.hash()] = data;
|
||||||
settings.setValue("torrents", all_data);
|
settings.setValue("torrents", all_data);
|
||||||
|
// Save completion date
|
||||||
|
saveSeedDate(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
// Defines for download list list columns
|
// Defines for download list list columns
|
||||||
enum TorrentState {STATE_DOWNLOADING, STATE_STALLED_DL, STATE_STALLED_UP, STATE_SEEDING, STATE_PAUSED_DL, STATE_PAUSED_UP, STATE_QUEUED_DL, STATE_QUEUED_UP, STATE_CHECKING_UP, STATE_CHECKING_DL, STATE_INVALID};
|
enum TorrentState {STATE_DOWNLOADING, STATE_STALLED_DL, STATE_STALLED_UP, STATE_SEEDING, STATE_PAUSED_DL, STATE_PAUSED_UP, STATE_QUEUED_DL, STATE_QUEUED_UP, STATE_CHECKING_UP, STATE_CHECKING_DL, STATE_INVALID};
|
||||||
enum Column {TR_NAME, TR_PRIORITY, TR_SIZE, TR_PROGRESS, TR_STATUS, TR_SEEDS, TR_PEERS, TR_DLSPEED, TR_UPSPEED, TR_ETA, TR_RATIO, TR_LABEL, TR_HASH};
|
enum Column {TR_NAME, TR_PRIORITY, TR_SIZE, TR_PROGRESS, TR_STATUS, TR_SEEDS, TR_PEERS, TR_DLSPEED, TR_UPSPEED, TR_ETA, TR_RATIO, TR_LABEL, TR_ADD_DATE, TR_SEED_DATE, TR_HASH};
|
||||||
|
|
||||||
class TransferListDelegate: public QItemDelegate {
|
class TransferListDelegate: public QItemDelegate {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -83,78 +83,83 @@ public:
|
|||||||
int state = index.data().toInt();
|
int state = index.data().toInt();
|
||||||
QString display = "";
|
QString display = "";
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case STATE_DOWNLOADING:
|
case STATE_DOWNLOADING:
|
||||||
display = tr("Downloading");
|
display = tr("Downloading");
|
||||||
break;
|
break;
|
||||||
case STATE_PAUSED_DL:
|
case STATE_PAUSED_DL:
|
||||||
case STATE_PAUSED_UP:
|
case STATE_PAUSED_UP:
|
||||||
display = tr("Paused");
|
display = tr("Paused");
|
||||||
break;
|
break;
|
||||||
case STATE_QUEUED_DL:
|
case STATE_QUEUED_DL:
|
||||||
case STATE_QUEUED_UP:
|
case STATE_QUEUED_UP:
|
||||||
display = tr("Queued", "i.e. torrent is queued");
|
display = tr("Queued", "i.e. torrent is queued");
|
||||||
break;
|
break;
|
||||||
case STATE_SEEDING:
|
case STATE_SEEDING:
|
||||||
case STATE_STALLED_UP:
|
case STATE_STALLED_UP:
|
||||||
display = tr("Seeding", "Torrent is complete and in upload-only mode");
|
display = tr("Seeding", "Torrent is complete and in upload-only mode");
|
||||||
break;
|
break;
|
||||||
case STATE_STALLED_DL:
|
case STATE_STALLED_DL:
|
||||||
display = tr("Stalled", "Torrent is waiting for download to begin");
|
display = tr("Stalled", "Torrent is waiting for download to begin");
|
||||||
break;
|
break;
|
||||||
case STATE_CHECKING_DL:
|
case STATE_CHECKING_DL:
|
||||||
case STATE_CHECKING_UP:
|
case STATE_CHECKING_UP:
|
||||||
display = tr("Checking", "Torrent local data is being checked");
|
display = tr("Checking", "Torrent local data is being checked");
|
||||||
}
|
}
|
||||||
QItemDelegate::drawBackground(painter, opt, index);
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, display);
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, display);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TR_UPSPEED:
|
case TR_UPSPEED:
|
||||||
case TR_DLSPEED:{
|
case TR_DLSPEED:{
|
||||||
QItemDelegate::drawBackground(painter, opt, index);
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
qulonglong speed = index.data().toULongLong();
|
qulonglong speed = index.data().toULongLong();
|
||||||
opt.displayAlignment = Qt::AlignRight;
|
opt.displayAlignment = Qt::AlignRight;
|
||||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, misc::friendlyUnit(speed)+tr("/s", "/second (.i.e per second)"));
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, misc::friendlyUnit(speed)+tr("/s", "/second (.i.e per second)"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TR_RATIO:{
|
case TR_ADD_DATE:
|
||||||
QItemDelegate::drawBackground(painter, opt, index);
|
case TR_SEED_DATE:
|
||||||
opt.displayAlignment = Qt::AlignRight;
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
double ratio = index.data().toDouble();
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, index.data().toDateTime().toLocalTime().toString(Qt::DefaultLocaleShortDate));
|
||||||
if(ratio > 100.)
|
break;
|
||||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞"));
|
case TR_RATIO:{
|
||||||
else
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(ratio, 'f', 1));
|
opt.displayAlignment = Qt::AlignRight;
|
||||||
break;
|
double ratio = index.data().toDouble();
|
||||||
}
|
if(ratio > 100.)
|
||||||
case TR_PRIORITY: {
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞"));
|
||||||
int priority = index.data().toInt();
|
else
|
||||||
if(priority >= 0) {
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(ratio, 'f', 1));
|
||||||
opt.displayAlignment = Qt::AlignRight;
|
break;
|
||||||
QItemDelegate::paint(painter, opt, index);
|
}
|
||||||
} else {
|
case TR_PRIORITY: {
|
||||||
QItemDelegate::drawBackground(painter, opt, index);
|
int priority = index.data().toInt();
|
||||||
opt.displayAlignment = Qt::AlignRight;
|
if(priority >= 0) {
|
||||||
QItemDelegate::drawDisplay(painter, opt, opt.rect, "*");
|
opt.displayAlignment = Qt::AlignRight;
|
||||||
}
|
QItemDelegate::paint(painter, opt, index);
|
||||||
break;
|
} else {
|
||||||
}
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
case TR_PROGRESS:{
|
opt.displayAlignment = Qt::AlignRight;
|
||||||
QStyleOptionProgressBarV2 newopt;
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, "*");
|
||||||
double progress = index.data().toDouble()*100.;
|
|
||||||
newopt.rect = opt.rect;
|
|
||||||
newopt.text = QString::number(progress, 'f', 1)+"%";
|
|
||||||
newopt.progress = (int)progress;
|
|
||||||
newopt.maximum = 100;
|
|
||||||
newopt.minimum = 0;
|
|
||||||
newopt.state |= QStyle::State_Enabled;
|
|
||||||
newopt.textVisible = true;
|
|
||||||
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
QItemDelegate::paint(painter, option, index);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TR_PROGRESS:{
|
||||||
|
QStyleOptionProgressBarV2 newopt;
|
||||||
|
double progress = index.data().toDouble()*100.;
|
||||||
|
newopt.rect = opt.rect;
|
||||||
|
newopt.text = QString::number(progress, 'f', 1)+"%";
|
||||||
|
newopt.progress = (int)progress;
|
||||||
|
newopt.maximum = 100;
|
||||||
|
newopt.minimum = 0;
|
||||||
|
newopt.state |= QStyle::State_Enabled;
|
||||||
|
newopt.textVisible = true;
|
||||||
|
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
QItemDelegate::paint(painter, option, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const {
|
QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const {
|
||||||
|
@ -59,7 +59,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, GUI *main_window, Bittor
|
|||||||
setItemDelegate(listDelegate);
|
setItemDelegate(listDelegate);
|
||||||
|
|
||||||
// Create transfer list model
|
// Create transfer list model
|
||||||
listModel = new QStandardItemModel(0,13);
|
listModel = new QStandardItemModel(0,15);
|
||||||
listModel->setHeaderData(TR_NAME, Qt::Horizontal, tr("Name", "i.e: torrent name"));
|
listModel->setHeaderData(TR_NAME, Qt::Horizontal, tr("Name", "i.e: torrent name"));
|
||||||
listModel->setHeaderData(TR_PRIORITY, Qt::Horizontal, "#");
|
listModel->setHeaderData(TR_PRIORITY, Qt::Horizontal, "#");
|
||||||
listModel->horizontalHeaderItem(TR_PRIORITY)->setTextAlignment(Qt::AlignRight);
|
listModel->horizontalHeaderItem(TR_PRIORITY)->setTextAlignment(Qt::AlignRight);
|
||||||
@ -80,6 +80,9 @@ TransferListWidget::TransferListWidget(QWidget *parent, GUI *main_window, Bittor
|
|||||||
listModel->horizontalHeaderItem(TR_RATIO)->setTextAlignment(Qt::AlignRight);
|
listModel->horizontalHeaderItem(TR_RATIO)->setTextAlignment(Qt::AlignRight);
|
||||||
listModel->setHeaderData(TR_ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left"));
|
listModel->setHeaderData(TR_ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left"));
|
||||||
listModel->setHeaderData(TR_LABEL, Qt::Horizontal, tr("Label"));
|
listModel->setHeaderData(TR_LABEL, Qt::Horizontal, tr("Label"));
|
||||||
|
listModel->setHeaderData(TR_ADD_DATE, Qt::Horizontal, tr("Added on", "Torrent was added to transfer list on 01/01/2010 08:00"));
|
||||||
|
listModel->setHeaderData(TR_SEED_DATE, Qt::Horizontal, tr("Completed on", "Torrent was completed on 01/01/2010 08:00"));
|
||||||
|
|
||||||
|
|
||||||
// Set Sort/Filter proxy
|
// Set Sort/Filter proxy
|
||||||
labelFilterModel = new QSortFilterProxyModel();
|
labelFilterModel = new QSortFilterProxyModel();
|
||||||
@ -163,6 +166,8 @@ void TransferListWidget::addTorrent(QTorrentHandle& h) {
|
|||||||
listModel->setData(listModel->index(row, TR_ETA), QVariant((qlonglong)-1));
|
listModel->setData(listModel->index(row, TR_ETA), QVariant((qlonglong)-1));
|
||||||
listModel->setData(listModel->index(row, TR_SEEDS), QVariant((double)0.0));
|
listModel->setData(listModel->index(row, TR_SEEDS), QVariant((double)0.0));
|
||||||
listModel->setData(listModel->index(row, TR_PEERS), QVariant((double)0.0));
|
listModel->setData(listModel->index(row, TR_PEERS), QVariant((double)0.0));
|
||||||
|
listModel->setData(listModel->index(row, TR_ADD_DATE), QVariant(TorrentPersistentData::getAddedDate(h.hash())));
|
||||||
|
listModel->setData(listModel->index(row, TR_SEED_DATE), QVariant(TorrentPersistentData::getSeedDate(h.hash())));
|
||||||
QString label = TorrentPersistentData::getLabel(h.hash());
|
QString label = TorrentPersistentData::getLabel(h.hash());
|
||||||
listModel->setData(listModel->index(row, TR_LABEL), QVariant(label));
|
listModel->setData(listModel->index(row, TR_LABEL), QVariant(label));
|
||||||
if(BTSession->isQueueingEnabled())
|
if(BTSession->isQueueingEnabled())
|
||||||
@ -429,6 +434,7 @@ void TransferListWidget::setFinished(QTorrentHandle &h) {
|
|||||||
listModel->setData(listModel->index(row, TR_DLSPEED), QVariant((double)0.));
|
listModel->setData(listModel->index(row, TR_DLSPEED), QVariant((double)0.));
|
||||||
listModel->setData(listModel->index(row, TR_PROGRESS), QVariant((double)1.));
|
listModel->setData(listModel->index(row, TR_PROGRESS), QVariant((double)1.));
|
||||||
listModel->setData(listModel->index(row, TR_PRIORITY), QVariant((int)-1));
|
listModel->setData(listModel->index(row, TR_PRIORITY), QVariant((int)-1));
|
||||||
|
listModel->setData(listModel->index(row, TR_SEED_DATE), QVariant(TorrentPersistentData::getSeedDate(h.hash())));
|
||||||
}
|
}
|
||||||
} catch(invalid_handle e) {
|
} catch(invalid_handle e) {
|
||||||
if(row >= 0) {
|
if(row >= 0) {
|
||||||
@ -799,6 +805,7 @@ void TransferListWidget::saveHiddenColumns() {
|
|||||||
|
|
||||||
for(short i=0; i<nbColumns; ++i){
|
for(short i=0; i<nbColumns; ++i){
|
||||||
if(isColumnHidden(i)) {
|
if(isColumnHidden(i)) {
|
||||||
|
qDebug("Column named %s is hidden.", listModel->headerData(i, Qt::Horizontal).toString().toLocal8Bit().data());
|
||||||
ishidden_list << "0";
|
ishidden_list << "0";
|
||||||
} else {
|
} else {
|
||||||
ishidden_list << "1";
|
ishidden_list << "1";
|
||||||
@ -810,8 +817,7 @@ void TransferListWidget::saveHiddenColumns() {
|
|||||||
// load the previous settings, and hide the columns
|
// load the previous settings, and hide the columns
|
||||||
bool TransferListWidget::loadHiddenColumns() {
|
bool TransferListWidget::loadHiddenColumns() {
|
||||||
QSettings settings("qBittorrent", "qBittorrent");
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
QString line = settings.value("TransferListColsHoS", QString()).toString();
|
QString line = settings.value("TransferListColsHoS", "").toString();
|
||||||
if(line.isEmpty()) return false;
|
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
QStringList ishidden_list;
|
QStringList ishidden_list;
|
||||||
ishidden_list = line.split(' ');
|
ishidden_list = line.split(' ');
|
||||||
@ -824,6 +830,11 @@ bool TransferListWidget::loadHiddenColumns() {
|
|||||||
}
|
}
|
||||||
loaded = true;
|
loaded = true;
|
||||||
}
|
}
|
||||||
|
// As a default, hide date columns
|
||||||
|
if(!loaded) {
|
||||||
|
setColumnHidden(TR_ADD_DATE, true);
|
||||||
|
setColumnHidden(TR_SEED_DATE, true);
|
||||||
|
}
|
||||||
return loaded;
|
return loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user