mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-01-08 11:47:30 +08:00
parent
b55d4b1733
commit
d40be79c69
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2021 Mike Tzou (Chocobo1)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@ -100,9 +101,18 @@ public:
|
||||
return (BaseType::erase(value) > 0);
|
||||
}
|
||||
|
||||
ThisType &unite(const ThisType &other)
|
||||
template <typename Set>
|
||||
ThisType &unite(const Set &other)
|
||||
{
|
||||
BaseType::insert(other.cbegin(), other.cend());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Set>
|
||||
ThisType united(const Set &other) const
|
||||
{
|
||||
ThisType result = *this;
|
||||
result.unite(other);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
@ -36,6 +36,7 @@ qt_wrap_ui(UI_HEADERS
|
||||
torrentcategorydialog.ui
|
||||
torrentcreatordialog.ui
|
||||
torrentoptionsdialog.ui
|
||||
torrenttagsdialog.ui
|
||||
trackerentriesdialog.ui
|
||||
uithemedialog.ui
|
||||
watchedfolderoptionsdialog.ui
|
||||
@ -58,6 +59,7 @@ add_library(qbt_gui STATIC
|
||||
desktopintegration.h
|
||||
downloadfromurldialog.h
|
||||
executionlogwidget.h
|
||||
flowlayout.h
|
||||
fspathedit.h
|
||||
fspathedit_p.h
|
||||
guiapplicationcomponent.h
|
||||
@ -114,6 +116,7 @@ add_library(qbt_gui STATIC
|
||||
torrentcontentwidget.h
|
||||
torrentcreatordialog.h
|
||||
torrentoptionsdialog.h
|
||||
torrenttagsdialog.h
|
||||
trackerentriesdialog.h
|
||||
transferlistdelegate.h
|
||||
transferlistfilterswidget.h
|
||||
@ -146,6 +149,7 @@ add_library(qbt_gui STATIC
|
||||
desktopintegration.cpp
|
||||
downloadfromurldialog.cpp
|
||||
executionlogwidget.cpp
|
||||
flowlayout.cpp
|
||||
fspathedit.cpp
|
||||
fspathedit_p.cpp
|
||||
guiapplicationcomponent.cpp
|
||||
@ -201,6 +205,7 @@ add_library(qbt_gui STATIC
|
||||
torrentcontentwidget.cpp
|
||||
torrentcreatordialog.cpp
|
||||
torrentoptionsdialog.cpp
|
||||
torrenttagsdialog.cpp
|
||||
trackerentriesdialog.cpp
|
||||
transferlistdelegate.cpp
|
||||
transferlistfilterswidget.cpp
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "base/utils/misc.h"
|
||||
#include "lineedit.h"
|
||||
#include "raisedmessagebox.h"
|
||||
#include "torrenttagsdialog.h"
|
||||
#include "ui_addnewtorrentdialog.h"
|
||||
#include "uithememanager.h"
|
||||
|
||||
@ -368,10 +369,23 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP
|
||||
|
||||
for (const QString &category : asConst(categories))
|
||||
{
|
||||
if (category != defaultCategory && category != m_torrentParams.category)
|
||||
if ((category != defaultCategory) && (category != m_torrentParams.category))
|
||||
m_ui->categoryComboBox->addItem(category);
|
||||
}
|
||||
|
||||
m_ui->tagsLineEdit->setText(m_torrentParams.tags.join(u", "_qs));
|
||||
connect(m_ui->tagsEditButton, &QAbstractButton::clicked, this, [this]
|
||||
{
|
||||
auto *dlg = new TorrentTagsDialog(m_torrentParams.tags, this);
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
connect(dlg, &TorrentTagsDialog::accepted, this, [this, dlg]
|
||||
{
|
||||
m_torrentParams.tags = dlg->tags();
|
||||
m_ui->tagsLineEdit->setText(m_torrentParams.tags.join(u", "_qs));
|
||||
});
|
||||
dlg->open();
|
||||
});
|
||||
|
||||
// Torrent content filtering
|
||||
m_filterLine->setPlaceholderText(tr("Filter files..."));
|
||||
m_filterLine->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
@ -201,6 +201,46 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="tagsLayout" stretch="0,0,0">
|
||||
<item>
|
||||
<widget class="QLabel" name="tagsLabel">
|
||||
<property name="text">
|
||||
<string>Tags:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="tagsLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Click [...] button to add/remove tags.</string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tagsEditButton">
|
||||
<property name="toolTip">
|
||||
<string>Add/remove tags</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
|
195
src/gui/flowlayout.cpp
Normal file
195
src/gui/flowlayout.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2016 The Qt Company Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#include "flowlayout.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "base/global.h"
|
||||
|
||||
FlowLayout::FlowLayout(QWidget *parent, const int margin, const int hSpacing, const int vSpacing)
|
||||
: QLayout(parent)
|
||||
, m_hSpace {hSpacing}
|
||||
, m_vSpace {vSpacing}
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
|
||||
FlowLayout::FlowLayout(const int margin, const int hSpacing, const int vSpacing)
|
||||
: m_hSpace {hSpacing}
|
||||
, m_vSpace {vSpacing}
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
|
||||
FlowLayout::~FlowLayout()
|
||||
{
|
||||
QLayoutItem *item;
|
||||
while ((item = takeAt(0)))
|
||||
delete item;
|
||||
}
|
||||
|
||||
void FlowLayout::addItem(QLayoutItem *item)
|
||||
{
|
||||
m_itemList.append(item);
|
||||
}
|
||||
|
||||
int FlowLayout::horizontalSpacing() const
|
||||
{
|
||||
if (m_hSpace >= 0)
|
||||
return m_hSpace;
|
||||
|
||||
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
|
||||
}
|
||||
|
||||
int FlowLayout::verticalSpacing() const
|
||||
{
|
||||
if (m_vSpace >= 0)
|
||||
return m_vSpace;
|
||||
|
||||
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
|
||||
}
|
||||
|
||||
int FlowLayout::count() const
|
||||
{
|
||||
return m_itemList.size();
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::itemAt(const int index) const
|
||||
{
|
||||
return m_itemList.value(index);
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::takeAt(const int index)
|
||||
{
|
||||
if ((index >= 0) && (index < m_itemList.size()))
|
||||
return m_itemList.takeAt(index);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Qt::Orientations FlowLayout::expandingDirections() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool FlowLayout::hasHeightForWidth() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int FlowLayout::heightForWidth(const int width) const
|
||||
{
|
||||
const int height = doLayout(QRect(0, 0, width, 0), true);
|
||||
return height;
|
||||
}
|
||||
|
||||
void FlowLayout::setGeometry(const QRect &rect)
|
||||
{
|
||||
QLayout::setGeometry(rect);
|
||||
doLayout(rect, false);
|
||||
}
|
||||
|
||||
QSize FlowLayout::sizeHint() const
|
||||
{
|
||||
return minimumSize();
|
||||
}
|
||||
|
||||
QSize FlowLayout::minimumSize() const
|
||||
{
|
||||
QSize size;
|
||||
for (const QLayoutItem *item : asConst(m_itemList))
|
||||
size = size.expandedTo(item->minimumSize());
|
||||
|
||||
const QMargins margins = contentsMargins();
|
||||
size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
|
||||
return size;
|
||||
}
|
||||
|
||||
int FlowLayout::doLayout(const QRect &rect, const bool testOnly) const
|
||||
{
|
||||
int left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
|
||||
const QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
|
||||
int x = effectiveRect.x();
|
||||
int y = effectiveRect.y();
|
||||
int lineHeight = 0;
|
||||
|
||||
for (QLayoutItem *item : asConst(m_itemList))
|
||||
{
|
||||
const QWidget *wid = item->widget();
|
||||
|
||||
int spaceX = horizontalSpacing();
|
||||
if (spaceX == -1)
|
||||
{
|
||||
spaceX = wid->style()->layoutSpacing(
|
||||
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
|
||||
}
|
||||
|
||||
int spaceY = verticalSpacing();
|
||||
if (spaceY == -1)
|
||||
{
|
||||
spaceY = wid->style()->layoutSpacing(
|
||||
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
|
||||
}
|
||||
|
||||
int nextX = x + item->sizeHint().width() + spaceX;
|
||||
if (((nextX - spaceX) > effectiveRect.right()) && (lineHeight > 0))
|
||||
{
|
||||
x = effectiveRect.x();
|
||||
y = y + lineHeight + spaceY;
|
||||
nextX = x + item->sizeHint().width() + spaceX;
|
||||
lineHeight = 0;
|
||||
}
|
||||
|
||||
if (!testOnly)
|
||||
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
|
||||
|
||||
x = nextX;
|
||||
lineHeight = std::max(lineHeight, item->sizeHint().height());
|
||||
}
|
||||
|
||||
return y + lineHeight - rect.y() + bottom;
|
||||
}
|
||||
|
||||
int FlowLayout::smartSpacing(const QStyle::PixelMetric pm) const
|
||||
{
|
||||
QObject *parent = this->parent();
|
||||
if (!parent)
|
||||
return -1;
|
||||
|
||||
if (parent->isWidgetType())
|
||||
{
|
||||
auto *pw = static_cast<QWidget *>(parent);
|
||||
return pw->style()->pixelMetric(pm, nullptr, pw);
|
||||
}
|
||||
|
||||
return static_cast<QLayout *>(parent)->spacing();
|
||||
}
|
63
src/gui/flowlayout.h
Normal file
63
src/gui/flowlayout.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2016 The Qt Company Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QLayout>
|
||||
#include <QRect>
|
||||
#include <QStyle>
|
||||
|
||||
class FlowLayout final : public QLayout
|
||||
{
|
||||
public:
|
||||
explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
~FlowLayout() override;
|
||||
|
||||
void addItem(QLayoutItem *item) override;
|
||||
int horizontalSpacing() const;
|
||||
int verticalSpacing() const;
|
||||
Qt::Orientations expandingDirections() const override;
|
||||
bool hasHeightForWidth() const override;
|
||||
int heightForWidth(int) const override;
|
||||
int count() const override;
|
||||
QLayoutItem *itemAt(int index) const override;
|
||||
QSize minimumSize() const override;
|
||||
void setGeometry(const QRect &rect) override;
|
||||
QSize sizeHint() const override;
|
||||
QLayoutItem *takeAt(int index) override;
|
||||
|
||||
private:
|
||||
int doLayout(const QRect &rect, bool testOnly) const;
|
||||
int smartSpacing(QStyle::PixelMetric pm) const;
|
||||
|
||||
QList<QLayoutItem *> m_itemList;
|
||||
int m_hSpace;
|
||||
int m_vSpace;
|
||||
};
|
@ -16,6 +16,7 @@ HEADERS += \
|
||||
$$PWD/desktopintegration.h \
|
||||
$$PWD/downloadfromurldialog.h \
|
||||
$$PWD/executionlogwidget.h \
|
||||
$$PWD/flowlayout.h \
|
||||
$$PWD/fspathedit.h \
|
||||
$$PWD/fspathedit_p.h \
|
||||
$$PWD/guiapplicationcomponent.h \
|
||||
@ -72,6 +73,7 @@ HEADERS += \
|
||||
$$PWD/torrentcontentwidget.h \
|
||||
$$PWD/torrentcreatordialog.h \
|
||||
$$PWD/torrentoptionsdialog.h \
|
||||
$$PWD/torrenttagsdialog.h \
|
||||
$$PWD/trackerentriesdialog.h \
|
||||
$$PWD/transferlistdelegate.h \
|
||||
$$PWD/transferlistfilterswidget.h \
|
||||
@ -104,6 +106,7 @@ SOURCES += \
|
||||
$$PWD/desktopintegration.cpp \
|
||||
$$PWD/downloadfromurldialog.cpp \
|
||||
$$PWD/executionlogwidget.cpp \
|
||||
$$PWD/flowlayout.cpp \
|
||||
$$PWD/fspathedit.cpp \
|
||||
$$PWD/fspathedit_p.cpp \
|
||||
$$PWD/guiapplicationcomponent.cpp \
|
||||
@ -159,6 +162,7 @@ SOURCES += \
|
||||
$$PWD/torrentcontentwidget.cpp \
|
||||
$$PWD/torrentcreatordialog.cpp \
|
||||
$$PWD/torrentoptionsdialog.cpp \
|
||||
$$PWD/torrenttagsdialog.cpp \
|
||||
$$PWD/trackerentriesdialog.cpp \
|
||||
$$PWD/transferlistdelegate.cpp \
|
||||
$$PWD/transferlistfilterswidget.cpp \
|
||||
@ -202,6 +206,7 @@ FORMS += \
|
||||
$$PWD/torrentcategorydialog.ui \
|
||||
$$PWD/torrentcreatordialog.ui \
|
||||
$$PWD/torrentoptionsdialog.ui \
|
||||
$$PWD/torrenttagsdialog.ui \
|
||||
$$PWD/trackerentriesdialog.ui \
|
||||
$$PWD/uithemedialog.ui \
|
||||
$$PWD/watchedfolderoptionsdialog.ui
|
||||
|
121
src/gui/torrenttagsdialog.cpp
Normal file
121
src/gui/torrenttagsdialog.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#include "torrenttagsdialog.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QSet>
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/global.h"
|
||||
#include "autoexpandabledialog.h"
|
||||
#include "flowlayout.h"
|
||||
|
||||
#include "ui_torrenttagsdialog.h"
|
||||
|
||||
#define SETTINGS_KEY(name) u"GUI/TorrentTagsDialog/" name
|
||||
|
||||
TorrentTagsDialog::TorrentTagsDialog(const TagSet &initialTags, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_ui {new Ui::TorrentTagsDialog}
|
||||
, m_storeDialogSize {SETTINGS_KEY(u"Size"_qs)}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
auto *tagsLayout = new FlowLayout(m_ui->scrollArea);
|
||||
for (const QString &tag : asConst(initialTags.united(BitTorrent::Session::instance()->tags())))
|
||||
{
|
||||
auto *tagWidget = new QCheckBox(tag);
|
||||
if (initialTags.contains(tag))
|
||||
tagWidget->setChecked(true);
|
||||
tagsLayout->addWidget(tagWidget);
|
||||
}
|
||||
|
||||
auto *addTagButton = new QPushButton(u"+"_qs);
|
||||
connect(addTagButton, &QPushButton::clicked, this, &TorrentTagsDialog::addNewTag);
|
||||
tagsLayout->addWidget(addTagButton);
|
||||
|
||||
if (const QSize dialogSize = m_storeDialogSize; dialogSize.isValid())
|
||||
resize(dialogSize);
|
||||
}
|
||||
|
||||
TorrentTagsDialog::~TorrentTagsDialog()
|
||||
{
|
||||
m_storeDialogSize = size();
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
TagSet TorrentTagsDialog::tags() const
|
||||
{
|
||||
TagSet tags;
|
||||
auto *layout = m_ui->scrollArea->layout();
|
||||
for (int i = 0; i < (layout->count() - 1); ++i)
|
||||
{
|
||||
const auto *tagWidget = static_cast<QCheckBox *>(layout->itemAt(i)->widget());
|
||||
if (tagWidget->isChecked())
|
||||
tags.insert(tagWidget->text());
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
void TorrentTagsDialog::addNewTag()
|
||||
{
|
||||
bool done = false;
|
||||
QString tag;
|
||||
while (!done)
|
||||
{
|
||||
bool ok = false;
|
||||
tag = AutoExpandableDialog::getText(this
|
||||
, tr("New Tag"), tr("Tag:"), QLineEdit::Normal, tag, &ok).trimmed();
|
||||
if (!ok || tag.isEmpty())
|
||||
break;
|
||||
|
||||
if (!BitTorrent::Session::isValidTag(tag))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid tag name"), tr("Tag name '%1' is invalid.").arg(tag));
|
||||
}
|
||||
else if (BitTorrent::Session::instance()->tags().contains(tag))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Tag exists"), tr("Tag name already exists."));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto *layout = m_ui->scrollArea->layout();
|
||||
auto *btn = layout->takeAt(layout->count() - 1);
|
||||
auto *tagWidget = new QCheckBox(tag);
|
||||
tagWidget->setChecked(true);
|
||||
layout->addWidget(tagWidget);
|
||||
layout->addItem(btn);
|
||||
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
57
src/gui/torrenttagsdialog.h
Normal file
57
src/gui/torrenttagsdialog.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "base/settingvalue.h"
|
||||
#include "base/tagset.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class TorrentTagsDialog;
|
||||
}
|
||||
|
||||
class TorrentTagsDialog final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY_MOVE(TorrentTagsDialog)
|
||||
|
||||
public:
|
||||
explicit TorrentTagsDialog(const TagSet &initialTags, QWidget *parent = nullptr);
|
||||
~TorrentTagsDialog() override;
|
||||
|
||||
TagSet tags() const;
|
||||
|
||||
private:
|
||||
void addNewTag();
|
||||
|
||||
Ui::TorrentTagsDialog *m_ui;
|
||||
SettingValue<QSize> m_storeDialogSize;
|
||||
};
|
81
src/gui/torrenttagsdialog.ui
Normal file
81
src/gui/torrenttagsdialog.ui
Normal file
@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TorrentTagsDialog</class>
|
||||
<widget class="QDialog" name="TorrentTagsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>484</width>
|
||||
<height>313</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Torrent Tags</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>464</width>
|
||||
<height>263</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>TorrentTagsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>241</x>
|
||||
<y>291</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>241</x>
|
||||
<y>156</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>TorrentTagsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>241</x>
|
||||
<y>291</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>241</x>
|
||||
<y>156</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2022 Mike Tzou (Chocobo1)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@ -26,6 +27,7 @@
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#include <QSet>
|
||||
#include <QTest>
|
||||
|
||||
#include "base/global.h"
|
||||
@ -114,16 +116,34 @@ private slots:
|
||||
{
|
||||
const OrderedSet<QString> newData1 {u"z"_qs};
|
||||
const OrderedSet<QString> newData2 {u"y"_qs};
|
||||
const QSet<QString> newData3 {u"c"_qs, u"d"_qs, u"e"_qs};
|
||||
|
||||
OrderedSet<QString> set {u"a"_qs, u"b"_qs, u"c"_qs};
|
||||
set.unite(newData1);
|
||||
QCOMPARE(set.join(u","_qs), u"a,b,c,z"_qs);
|
||||
set.unite(newData2);
|
||||
QCOMPARE(set.join(u","_qs), u"a,b,c,y,z"_qs);
|
||||
set.unite(newData3);
|
||||
QCOMPARE(set.join(u","_qs), u"a,b,c,d,e,y,z"_qs);
|
||||
|
||||
OrderedSet<QString> emptySet;
|
||||
emptySet.unite(newData1).unite(newData2);
|
||||
QCOMPARE(emptySet.join(u","_qs), u"y,z"_qs);
|
||||
emptySet.unite(newData1).unite(newData2).unite(newData3);
|
||||
QCOMPARE(emptySet.join(u","_qs), u"c,d,e,y,z"_qs);
|
||||
}
|
||||
|
||||
void testUnited() const
|
||||
{
|
||||
const OrderedSet<QString> newData1 {u"z"_qs};
|
||||
const OrderedSet<QString> newData2 {u"y"_qs};
|
||||
const QSet<QString> newData3 {u"c"_qs, u"d"_qs, u"e"_qs};
|
||||
|
||||
OrderedSet<QString> set {u"a"_qs, u"b"_qs, u"c"_qs};
|
||||
|
||||
QCOMPARE(set.united(newData1).join(u","_qs), u"a,b,c,z"_qs);
|
||||
QCOMPARE(set.united(newData2).join(u","_qs), u"a,b,c,y"_qs);
|
||||
QCOMPARE(set.united(newData3).join(u","_qs), u"a,b,c,d,e"_qs);
|
||||
|
||||
QCOMPARE(OrderedSet<QString>().united(newData1).united(newData2).united(newData3).join(u","_qs), u"c,d,e,y,z"_qs);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user