Merge branch 'qbittorrent:master' into master

This commit is contained in:
Daniel Nylander 2024-12-20 19:31:01 +01:00 committed by GitHub
commit 817385adeb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 1254 additions and 1330 deletions

View file

@ -32,7 +32,7 @@ jobs:
curl \
-L \
-o "${{ runner.temp }}/pandoc.tar.gz" \
"https://github.com/jgm/pandoc/releases/download/3.4/pandoc-3.4-linux-amd64.tar.gz"
"https://github.com/jgm/pandoc/releases/download/3.6/pandoc-3.6-linux-amd64.tar.gz"
tar -xf "${{ runner.temp }}/pandoc.tar.gz" -C "${{ github.workspace }}/.."
mv "${{ github.workspace }}/.."/pandoc-* "${{ env.pandoc_path }}"
# run pandoc

View file

@ -34,7 +34,7 @@ jobs:
- name: Lint code (auxiliary scripts)
run: |
pyflakes $PY_FILES
bandit --skip B314,B405 $PY_FILES
bandit --skip B101,B314,B405 $PY_FILES
- name: Format code (auxiliary scripts)
run: |

View file

@ -0,0 +1,95 @@
#!/usr/bin/env python3
# A pre-commit hook for checking items order in grid layouts
# Copyright (C) 2024 Mike Tzou (Chocobo1)
#
# 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.
from collections.abc import Callable, Sequence
from typing import Optional
import argparse
import re
import xml.etree.ElementTree as ElementTree
import sys
def traversePostOrder(root: ElementTree.Element, visitFunc: Callable[[ElementTree.Element], None]) -> None:
stack = [(root, False)]
while len(stack) > 0:
(element, visit) = stack.pop()
if visit:
visitFunc(element)
else:
stack.append((element, True))
stack.extend((child, False) for child in reversed(element))
def modifyElement(element: ElementTree.Element) -> None:
def getSortKey(e: ElementTree.Element) -> tuple[int, int]:
if e.tag == 'item':
return (int(e.attrib['row']), int(e.attrib['column']))
return (-1, -1) # don't care
if element.tag == 'layout' and element.attrib['class'] == 'QGridLayout' and len(element) > 0:
element[:] = sorted(element, key=getSortKey)
# workaround_2a: ElementTree will unescape `"` and we need to escape it back
if element.tag == 'string' and element.text is not None:
element.text = element.text.replace('"', '"')
def main(argv: Optional[Sequence[str]] = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help='Filenames to check')
args = parser.parse_args(argv)
for filename in args.filenames:
with open(filename, 'r+') as f:
orig = f.read()
root = ElementTree.fromstring(orig)
traversePostOrder(root, modifyElement)
ElementTree.indent(root, ' ')
# workaround_1: cannot use `xml_declaration=True` since it uses single quotes instead of Qt preferred double quotes
ret = f'<?xml version="1.0" encoding="UTF-8"?>\n{ElementTree.tostring(root, 'unicode')}\n'
# workaround_2b: ElementTree will turn `&quot;` into `&amp;quot;`, so revert it back
ret = ret.replace('&amp;quot;', '&quot;')
# workaround_3: Qt prefers no whitespaces in self-closing tags
ret = re.sub('<(.+) +/>', r'<\1/>', ret)
if ret != orig:
print(f'Tip: run this script to apply the fix: `python {__file__} {filename}`', file=sys.stderr)
f.seek(0)
f.write(ret)
f.truncate()
return 0
if __name__ == '__main__':
sys.exit(main())

View file

@ -26,9 +26,11 @@
# but you are not obligated to do so. If you do not wish to do so, delete this
# exception statement from your version.
from typing import Optional, Sequence
from collections.abc import Sequence
from typing import Optional
import argparse
import re
import sys
def main(argv: Optional[Sequence[str]] = None) -> int:
@ -67,4 +69,4 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
if __name__ == '__main__':
exit(main())
sys.exit(main())

View file

@ -1,6 +1,12 @@
repos:
- repo: local
hooks:
- id: check-grid-order
name: Check items order in grid layouts
entry: .github/workflows/helper/pre-commit/check_grid_items_order.py
language: script
files: \.ui$
- id: check-translation-tag
name: Check newline characters in <translation> tag
entry: .github/workflows/helper/pre-commit/check_translation_tag.py
@ -13,7 +19,7 @@ repos:
- ts
- repo: https://github.com/pre-commit/pre-commit-hooks.git
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-json
name: Check JSON files
@ -82,7 +88,7 @@ repos:
- ts
- repo: https://github.com/crate-ci/typos.git
rev: v1.25.0
rev: v1.28.4
hooks:
- id: typos
name: Check spelling (typos)

View file

@ -62,6 +62,6 @@
<url type="contribute">https://github.com/qbittorrent/qBittorrent/blob/master/CONTRIBUTING.md</url>
<content_rating type="oars-1.1"/>
<releases>
<release version="5.1.0~alpha1" date="2024-08-24"/>
<release version="5.1.0~beta1" date="2024-12-16"/>
</releases>
</component>

View file

@ -32,7 +32,7 @@
#define QBT_VERSION_MINOR 1
#define QBT_VERSION_BUGFIX 0
#define QBT_VERSION_BUILD 0
#define QBT_VERSION_STATUS "alpha1" // Should be empty for stable releases!
#define QBT_VERSION_STATUS "beta1" // Should be empty for stable releases!
#define QBT__STRINGIFY(x) #x
#define QBT_STRINGIFY(x) QBT__STRINGIFY(x)

View file

@ -75,6 +75,9 @@
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByKeyboard|Qt::TextInteractionFlag::LinksAccessibleByMouse</set>
</property>
</widget>
</item>
</layout>
@ -90,6 +93,27 @@
<string>Current maintainer</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_17">
<property name="text">
<string notr="true">Sledgehammer999</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Nationality:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_18">
<property name="text">
@ -97,6 +121,13 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>E-mail:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_19">
<property name="text">
@ -110,34 +141,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Nationality:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>E-mail:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_17">
<property name="text">
<string notr="true">Sledgehammer999</string>
</property>
</widget>
</item>
<item row="2" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
@ -160,10 +163,10 @@
<string>Original author</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="1" column="1">
<widget class="QLabel" name="label_7">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>France</string>
<string>Name:</string>
</property>
</widget>
</item>
@ -174,6 +177,27 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Nationality:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_7">
<property name="text">
<string>France</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>E-mail:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
@ -187,27 +211,6 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>E-mail:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Nationality:</string>
</property>
</widget>
</item>
<item row="2" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
@ -365,8 +368,54 @@
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="2">
<widget class="QLabel" name="labelBoostVer">
<item row="0" column="1">
<widget class="QLabel" name="labelQt">
<property name="text">
<string notr="true">Qt:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelQtVer">
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QLabel" name="labelLibt">
<property name="text">
<string notr="true">Libtorrent:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="labelLibtVer">
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
@ -385,32 +434,6 @@
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labelQt">
<property name="text">
<string notr="true">Qt:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="labelLibt">
<property name="text">
<string notr="true">Libtorrent:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="labelBoost">
<property name="text">
@ -424,33 +447,13 @@
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelQtVer">
<item row="2" column="2">
<widget class="QLabel" name="labelBoostVer">
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="labelLibtVer">
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QLabel" name="labelOpenssl">
<property name="text">

View file

@ -378,6 +378,26 @@
<string>Torrent information</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="labelSize">
<property name="text">
<string>Size:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labelSizeData"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelDate">
<property name="text">
<string>Date:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="labelDateData"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelInfohash1">
<property name="text">
@ -385,11 +405,36 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labelSizeData"/>
<item row="2" column="1">
<widget class="QLabel" name="labelInfohash1Data">
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="labelDateData"/>
<item row="3" column="0">
<widget class="QLabel" name="labelInfohash2">
<property name="text">
<string>Info hash v2:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="labelInfohash2Data">
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelComment">
<property name="text">
<string>Comment:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QScrollArea" name="scrollArea">
@ -439,7 +484,7 @@
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::TextBrowserInteraction</set>
<set>Qt::TextInteractionFlag::TextSelectableByKeyboard|Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
@ -447,51 +492,6 @@
</widget>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelComment">
<property name="text">
<string>Comment:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelSize">
<property name="text">
<string>Size:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="labelInfohash1Data">
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelDate">
<property name="text">
<string>Date:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelInfohash2">
<property name="text">
<string>Info hash v2:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="labelInfohash2Data">
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View file

@ -102,12 +102,6 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>bannedIPList</tabstop>
<tabstop>txtIP</tabstop>
<tabstop>buttonBanIP</tabstop>
<tabstop>buttonDeleteIP</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -86,12 +86,6 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>whitelistedIPSubnetList</tabstop>
<tabstop>txtIPSubnet</tabstop>
<tabstop>buttonWhitelistIPSubnet</tabstop>
<tabstop>buttonDeleteIPSubnet</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,9 @@
</item>
<item>
<widget class="QTextEdit" name="textEditPeers">
<property name="tabChangesFocus">
<bool>true</bool>
</property>
<property name="lineWrapMode">
<enum>QTextEdit::LineWrapMode::NoWrap</enum>
</property>

View file

@ -85,6 +85,13 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="tempProgressBarArea">
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelProgressVal">
<property name="sizePolicy">
@ -114,6 +121,13 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="tempAvailabilityBarArea">
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="labelAverageAvailabilityVal">
<property name="sizePolicy">
@ -127,20 +141,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="tempAvailabilityBarArea">
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="tempProgressBarArea">
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -163,6 +163,196 @@
<property name="bottomMargin">
<number>4</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="labelTimeActive">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string extracomment="Time (duration) the torrent is active (not stopped)">Time Active:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labelElapsedVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelETA">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>ETA:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="labelETAVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="labelConnections">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Connections:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLabel" name="labelConnectionsVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelDownloaded">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Downloaded:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="labelDlTotalVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="labelUploaded">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Uploaded:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="labelUpTotalVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="labelSeeds">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Seeds:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QLabel" name="labelSeedsVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelDlSpeed">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Download Speed:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="labelDlSpeedVal">
<property name="sizePolicy">
@ -221,37 +411,8 @@
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="labelConnections">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Connections:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QLabel" name="labelReannounceInVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="labelETAVal">
<item row="2" column="5">
<widget class="QLabel" name="labelPeersVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -279,43 +440,8 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelRatio">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Share Ratio:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="labelPopularity">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Ratio / Time Active (in months), indicates how popular the torrent is</string>
</property>
<property name="text">
<string>Popularity:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLabel" name="labelConnectionsVal">
<item row="3" column="1">
<widget class="QLabel" name="labelDlLimitVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -327,35 +453,6 @@
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QLabel" name="labelPeersVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelDownloaded">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Downloaded:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="labelUpLimit">
<property name="sizePolicy">
@ -372,24 +469,8 @@
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QLabel" name="labelLastSeenComplete">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Last Seen Complete:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="labelDlLimitVal">
<item row="3" column="3">
<widget class="QLabel" name="labelUpLimitVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -401,8 +482,53 @@
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="labelUpTotalVal">
<item row="3" column="4">
<widget class="QLabel" name="labelWasted">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Wasted:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QLabel" name="labelWastedVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelRatio">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Share Ratio:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="labelShareRatioVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -430,6 +556,35 @@
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QLabel" name="labelReannounceInVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QLabel" name="labelLastSeenComplete">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Last Seen Complete:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="5">
<widget class="QLabel" name="labelLastSeenCompleteVal">
<property name="sizePolicy">
@ -443,77 +598,25 @@
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="labelSeeds">
<item row="5" column="0">
<widget class="QLabel" name="labelPopularity">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Ratio / Time Active (in months), indicates how popular the torrent is</string>
</property>
<property name="text">
<string>Seeds:</string>
<string>Popularity:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelDlSpeed">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Download Speed:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="labelDlTotalVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QLabel" name="labelWastedVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="labelShareRatioVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="labelPopularityVal">
<property name="sizePolicy">
@ -530,109 +633,6 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="labelUploaded">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Uploaded:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QLabel" name="labelSeedsVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labelElapsedVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelTimeActive">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string extracomment="Time (duration) the torrent is active (not stopped)">Time Active:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="labelUpLimitVal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::PlainText</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelETA">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>ETA:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QLabel" name="labelWasted">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Wasted:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View file

@ -182,22 +182,11 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelMustNotContain">
<property name="text">
<string>Must Not Contain:</string>
</property>
</widget>
<item row="0" column="1">
<widget class="QLineEdit" name="lineContains"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblEFilter">
<property name="text">
<string>Episode Filter:</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="lblEFilterStat">
<item row="0" column="2">
<widget class="QLabel" name="labelMustStat">
<property name="maximumSize">
<size>
<width>18</width>
@ -206,6 +195,16 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelMustNotContain">
<property name="text">
<string>Must Not Contain:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineNotContains"/>
</item>
<item row="1" column="2">
<widget class="QLabel" name="labelMustNotStat">
<property name="maximumSize">
@ -216,11 +215,18 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineContains"/>
<item row="2" column="0">
<widget class="QLabel" name="lblEFilter">
<property name="text">
<string>Episode Filter:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelMustStat">
<item row="2" column="1">
<widget class="QLineEdit" name="lineEFilter"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="lblEFilterStat">
<property name="maximumSize">
<size>
<width>18</width>
@ -239,12 +245,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineNotContains"/>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEFilter"/>
</item>
</layout>
</item>
<item>
@ -427,20 +427,6 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
</item>
</layout>
</widget>
<tabstops>
<tabstop>renameRuleBtn</tabstop>
<tabstop>removeRuleBtn</tabstop>
<tabstop>addRuleBtn</tabstop>
<tabstop>ruleList</tabstop>
<tabstop>lineContains</tabstop>
<tabstop>lineNotContains</tabstop>
<tabstop>lineEFilter</tabstop>
<tabstop>spinIgnorePeriod</tabstop>
<tabstop>listFeeds</tabstop>
<tabstop>matchingArticlesTree</tabstop>
<tabstop>importBtn</tabstop>
<tabstop>exportBtn</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -54,6 +54,48 @@
#include "feedlistwidget.h"
#include "ui_rsswidget.h"
namespace
{
void convertRelativeUrlToAbsolute(QString &html, const QString &baseUrl)
{
const QRegularExpression rx {uR"(((<a\s+[^>]*?href|<img\s+[^>]*?src)\s*=\s*["'])((https?|ftp):)?(\/\/[^\/]*)?(\/?[^\/"].*?)(["']))"_s
, QRegularExpression::CaseInsensitiveOption};
const QString normalizedBaseUrl = baseUrl.endsWith(u'/') ? baseUrl : (baseUrl + u'/');
const QUrl url {normalizedBaseUrl};
const QString defaultScheme = url.scheme();
QRegularExpressionMatchIterator iter = rx.globalMatch(html);
while (iter.hasNext())
{
const QRegularExpressionMatch match = iter.next();
const QString scheme = match.captured(4);
const QString host = match.captured(5);
if (!scheme.isEmpty())
{
if (host.isEmpty())
break; // invalid URL, should never happen
// already absolute URL
continue;
}
QString relativePath = match.captured(6);
if (relativePath.startsWith(u'/'))
relativePath = relativePath.mid(1);
const QString absoluteUrl = !host.isEmpty()
? QString(defaultScheme + u':' + host) : (normalizedBaseUrl + relativePath);
const QString fullMatch = match.captured(0);
const QString prefix = match.captured(1);
const QString suffix = match.captured(7);
html.replace(fullMatch, (prefix + absoluteUrl + suffix));
}
}
}
RSSWidget::RSSWidget(IGUIApplication *app, QWidget *parent)
: GUIApplicationComponent(app, parent)
, m_ui {new Ui::RSSWidget}
@ -79,23 +121,19 @@ RSSWidget::RSSWidget(IGUIApplication *app, QWidget *parent)
m_ui->rssDownloaderBtn->setIcon(UIThemeManager::instance()->getIcon(u"downloading"_s, u"download"_s));
#endif
m_articleListWidget = new ArticleListWidget(m_ui->splitterMain);
m_ui->splitterMain->insertWidget(0, m_articleListWidget);
connect(m_articleListWidget, &ArticleListWidget::customContextMenuRequested, this, &RSSWidget::displayItemsListMenu);
connect(m_articleListWidget, &ArticleListWidget::currentItemChanged, this, &RSSWidget::handleCurrentArticleItemChanged);
connect(m_articleListWidget, &ArticleListWidget::itemDoubleClicked, this, &RSSWidget::downloadSelectedTorrents);
connect(m_ui->articleListWidget, &ArticleListWidget::customContextMenuRequested, this, &RSSWidget::displayItemsListMenu);
connect(m_ui->articleListWidget, &ArticleListWidget::currentItemChanged, this, &RSSWidget::handleCurrentArticleItemChanged);
connect(m_ui->articleListWidget, &ArticleListWidget::itemDoubleClicked, this, &RSSWidget::downloadSelectedTorrents);
m_feedListWidget = new FeedListWidget(m_ui->splitterSide);
m_ui->splitterSide->insertWidget(0, m_feedListWidget);
connect(m_feedListWidget, &QAbstractItemView::doubleClicked, this, &RSSWidget::renameSelectedRSSItem);
connect(m_feedListWidget, &QTreeWidget::currentItemChanged, this, &RSSWidget::handleCurrentFeedItemChanged);
connect(m_feedListWidget, &QWidget::customContextMenuRequested, this, &RSSWidget::displayRSSListMenu);
connect(m_ui->feedListWidget, &QAbstractItemView::doubleClicked, this, &RSSWidget::renameSelectedRSSItem);
connect(m_ui->feedListWidget, &QTreeWidget::currentItemChanged, this, &RSSWidget::handleCurrentFeedItemChanged);
connect(m_ui->feedListWidget, &QWidget::customContextMenuRequested, this, &RSSWidget::displayRSSListMenu);
loadFoldersOpenState();
m_feedListWidget->setCurrentItem(m_feedListWidget->stickyUnreadItem());
m_ui->feedListWidget->setCurrentItem(m_ui->feedListWidget->stickyUnreadItem());
const auto *editHotkey = new QShortcut(Qt::Key_F2, m_feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
const auto *editHotkey = new QShortcut(Qt::Key_F2, m_ui->feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
connect(editHotkey, &QShortcut::activated, this, &RSSWidget::renameSelectedRSSItem);
const auto *deleteHotkey = new QShortcut(QKeySequence::Delete, m_feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
const auto *deleteHotkey = new QShortcut(QKeySequence::Delete, m_ui->feedListWidget, nullptr, nullptr, Qt::WidgetShortcut);
connect(deleteHotkey, &QShortcut::activated, this, &RSSWidget::deleteSelectedItems);
// Feeds list actions
@ -134,25 +172,24 @@ RSSWidget::~RSSWidget()
{
// we need it here to properly mark latest article
// as read without having additional code
m_articleListWidget->clear();
m_ui->articleListWidget->clear();
saveFoldersOpenState();
delete m_feedListWidget;
delete m_ui;
}
// display a right-click menu
void RSSWidget::displayRSSListMenu(const QPoint &pos)
{
if (!m_feedListWidget->indexAt(pos).isValid())
if (!m_ui->feedListWidget->indexAt(pos).isValid())
// No item under the mouse, clear selection
m_feedListWidget->clearSelection();
m_ui->feedListWidget->clearSelection();
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
const QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
const QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (!selectedItems.isEmpty())
{
menu->addAction(m_ui->actionUpdate);
@ -162,14 +199,14 @@ void RSSWidget::displayRSSListMenu(const QPoint &pos)
if (selectedItems.size() == 1)
{
QTreeWidgetItem *selectedItem = selectedItems.first();
if (selectedItem != m_feedListWidget->stickyUnreadItem())
if (selectedItem != m_ui->feedListWidget->stickyUnreadItem())
{
menu->addAction(m_ui->actionRename);
if (m_feedListWidget->isFeed(selectedItem))
if (m_ui->feedListWidget->isFeed(selectedItem))
menu->addAction(m_ui->actionEditFeedURL);
menu->addAction(m_ui->actionDelete);
menu->addSeparator();
if (m_feedListWidget->isFolder(selectedItem))
if (m_ui->feedListWidget->isFolder(selectedItem))
menu->addAction(m_ui->actionNewFolder);
}
}
@ -181,7 +218,7 @@ void RSSWidget::displayRSSListMenu(const QPoint &pos)
menu->addAction(m_ui->actionNewSubscription);
if (m_feedListWidget->isFeed(selectedItems.first()))
if (m_ui->feedListWidget->isFeed(selectedItems.first()))
{
menu->addSeparator();
menu->addAction(m_ui->actionCopyFeedURL);
@ -202,7 +239,7 @@ void RSSWidget::displayItemsListMenu()
{
bool hasTorrent = false;
bool hasLink = false;
for (const QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
for (const QListWidgetItem *item : asConst(m_ui->articleListWidget->selectedItems()))
{
auto *article = item->data(Qt::UserRole).value<RSS::Article *>();
Q_ASSERT(article);
@ -240,17 +277,17 @@ void RSSWidget::askNewFolder()
// Determine destination folder for new item
QTreeWidgetItem *destItem = nullptr;
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (!selectedItems.empty())
{
destItem = selectedItems.first();
if (!m_feedListWidget->isFolder(destItem))
if (!m_ui->feedListWidget->isFolder(destItem))
destItem = destItem->parent();
}
// Consider the case where the user clicked on Unread item
RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_feedListWidget->stickyUnreadItem()))
RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_ui->feedListWidget->stickyUnreadItem()))
? RSS::Session::instance()->rootFolder()
: qobject_cast<RSS::Folder *>(m_feedListWidget->getRSSItem(destItem)));
: qobject_cast<RSS::Folder *>(m_ui->feedListWidget->getRSSItem(destItem)));
const QString newFolderPath = RSS::Item::joinPath(rssDestFolder->path(), newName);
const nonstd::expected<void, QString> result = RSS::Session::instance()->addFolder(newFolderPath);
@ -258,10 +295,10 @@ void RSSWidget::askNewFolder()
QMessageBox::warning(this, u"qBittorrent"_s, result.error(), QMessageBox::Ok);
// Expand destination folder to display new feed
if (destItem && (destItem != m_feedListWidget->stickyUnreadItem()))
if (destItem && (destItem != m_ui->feedListWidget->stickyUnreadItem()))
destItem->setExpanded(true);
// As new RSS items are added synchronously, we can do the following here.
m_feedListWidget->setCurrentItem(m_feedListWidget->mapRSSItem(RSS::Session::instance()->itemByPath(newFolderPath)));
m_ui->feedListWidget->setCurrentItem(m_ui->feedListWidget->mapRSSItem(RSS::Session::instance()->itemByPath(newFolderPath)));
}
// add a stream by a button
@ -281,17 +318,17 @@ void RSSWidget::on_newFeedButton_clicked()
// Determine destination folder for new item
QTreeWidgetItem *destItem = nullptr;
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (!selectedItems.empty())
{
destItem = selectedItems.first();
if (!m_feedListWidget->isFolder(destItem))
if (!m_ui->feedListWidget->isFolder(destItem))
destItem = destItem->parent();
}
// Consider the case where the user clicked on Unread item
RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_feedListWidget->stickyUnreadItem()))
RSS::Folder *rssDestFolder = ((!destItem || (destItem == m_ui->feedListWidget->stickyUnreadItem()))
? RSS::Session::instance()->rootFolder()
: qobject_cast<RSS::Folder *>(m_feedListWidget->getRSSItem(destItem)));
: qobject_cast<RSS::Folder *>(m_ui->feedListWidget->getRSSItem(destItem)));
// NOTE: We still add feed using legacy way (with URL as feed name)
const QString newFeedPath = RSS::Item::joinPath(rssDestFolder->path(), newURL);
@ -300,18 +337,18 @@ void RSSWidget::on_newFeedButton_clicked()
QMessageBox::warning(this, u"qBittorrent"_s, result.error(), QMessageBox::Ok);
// Expand destination folder to display new feed
if (destItem && (destItem != m_feedListWidget->stickyUnreadItem()))
if (destItem && (destItem != m_ui->feedListWidget->stickyUnreadItem()))
destItem->setExpanded(true);
// As new RSS items are added synchronously, we can do the following here.
m_feedListWidget->setCurrentItem(m_feedListWidget->mapRSSItem(RSS::Session::instance()->itemByPath(newFeedPath)));
m_ui->feedListWidget->setCurrentItem(m_ui->feedListWidget->mapRSSItem(RSS::Session::instance()->itemByPath(newFeedPath)));
}
void RSSWidget::deleteSelectedItems()
{
const QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
const QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (selectedItems.isEmpty())
return;
if ((selectedItems.size() == 1) && (selectedItems.first() == m_feedListWidget->stickyUnreadItem()))
if ((selectedItems.size() == 1) && (selectedItems.first() == m_ui->feedListWidget->stickyUnreadItem()))
return;
QMessageBox::StandardButton answer = QMessageBox::question(
@ -321,8 +358,8 @@ void RSSWidget::deleteSelectedItems()
return;
for (QTreeWidgetItem *item : selectedItems)
if (item != m_feedListWidget->stickyUnreadItem())
RSS::Session::instance()->removeItem(m_feedListWidget->itemPath(item));
if (item != m_ui->feedListWidget->stickyUnreadItem())
RSS::Session::instance()->removeItem(m_ui->feedListWidget->itemPath(item));
}
void RSSWidget::loadFoldersOpenState()
@ -333,11 +370,11 @@ void RSSWidget::loadFoldersOpenState()
QTreeWidgetItem *parent = nullptr;
for (const QString &name : asConst(varPath.split(u'\\')))
{
int nbChildren = (parent ? parent->childCount() : m_feedListWidget->topLevelItemCount());
int nbChildren = (parent ? parent->childCount() : m_ui->feedListWidget->topLevelItemCount());
for (int i = 0; i < nbChildren; ++i)
{
QTreeWidgetItem *child = (parent ? parent->child(i) : m_feedListWidget->topLevelItem(i));
if (m_feedListWidget->getRSSItem(child)->name() == name)
QTreeWidgetItem *child = (parent ? parent->child(i) : m_ui->feedListWidget->topLevelItem(i));
if (m_ui->feedListWidget->getRSSItem(child)->name() == name)
{
parent = child;
parent->setExpanded(true);
@ -351,8 +388,8 @@ void RSSWidget::loadFoldersOpenState()
void RSSWidget::saveFoldersOpenState()
{
QStringList openedFolders;
for (QTreeWidgetItem *item : asConst(m_feedListWidget->getAllOpenedFolders()))
openedFolders << m_feedListWidget->itemPath(item);
for (QTreeWidgetItem *item : asConst(m_ui->feedListWidget->getAllOpenedFolders()))
openedFolders << m_ui->feedListWidget->itemPath(item);
Preferences::instance()->setRssOpenFolders(openedFolders);
}
@ -363,7 +400,7 @@ void RSSWidget::refreshAllFeeds()
void RSSWidget::downloadSelectedTorrents()
{
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
for (QListWidgetItem *item : asConst(m_ui->articleListWidget->selectedItems()))
{
auto *article = item->data(Qt::UserRole).value<RSS::Article *>();
Q_ASSERT(article);
@ -378,7 +415,7 @@ void RSSWidget::downloadSelectedTorrents()
// open the url of the selected RSS articles in the Web browser
void RSSWidget::openSelectedArticlesUrls()
{
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
for (QListWidgetItem *item : asConst(m_ui->articleListWidget->selectedItems()))
{
auto *article = item->data(Qt::UserRole).value<RSS::Article *>();
Q_ASSERT(article);
@ -393,14 +430,14 @@ void RSSWidget::openSelectedArticlesUrls()
void RSSWidget::renameSelectedRSSItem()
{
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (selectedItems.size() != 1) return;
QTreeWidgetItem *item = selectedItems.first();
if (item == m_feedListWidget->stickyUnreadItem())
if (item == m_ui->feedListWidget->stickyUnreadItem())
return;
RSS::Item *rssItem = m_feedListWidget->getRSSItem(item);
RSS::Item *rssItem = m_ui->feedListWidget->getRSSItem(item);
const QString parentPath = RSS::Item::parentPath(rssItem->path());
bool ok = false;
do
@ -422,12 +459,12 @@ void RSSWidget::renameSelectedRSSItem()
void RSSWidget::editSelectedRSSFeedURL()
{
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
QList<QTreeWidgetItem *> selectedItems = m_ui->feedListWidget->selectedItems();
if (selectedItems.size() != 1)
return;
QTreeWidgetItem *item = selectedItems.first();
RSS::Feed *rssFeed = qobject_cast<RSS::Feed *>(m_feedListWidget->getRSSItem(item));
RSS::Feed *rssFeed = qobject_cast<RSS::Feed *>(m_ui->feedListWidget->getRSSItem(item));
Q_ASSERT(rssFeed);
if (!rssFeed) [[unlikely]]
return;
@ -445,24 +482,24 @@ void RSSWidget::editSelectedRSSFeedURL()
void RSSWidget::refreshSelectedItems()
{
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
for (QTreeWidgetItem *item : asConst(m_ui->feedListWidget->selectedItems()))
{
if (item == m_feedListWidget->stickyUnreadItem())
if (item == m_ui->feedListWidget->stickyUnreadItem())
{
refreshAllFeeds();
return;
}
m_feedListWidget->getRSSItem(item)->refresh();
m_ui->feedListWidget->getRSSItem(item)->refresh();
}
}
void RSSWidget::copySelectedFeedsURL()
{
QStringList URLs;
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
for (QTreeWidgetItem *item : asConst(m_ui->feedListWidget->selectedItems()))
{
if (auto *feed = qobject_cast<RSS::Feed *>(m_feedListWidget->getRSSItem(item)))
if (auto *feed = qobject_cast<RSS::Feed *>(m_ui->feedListWidget->getRSSItem(item)))
URLs << feed->url();
}
qApp->clipboard()->setText(URLs.join(u'\n'));
@ -470,16 +507,16 @@ void RSSWidget::copySelectedFeedsURL()
void RSSWidget::handleCurrentFeedItemChanged(QTreeWidgetItem *currentItem)
{
m_articleListWidget->setRSSItem(m_feedListWidget->getRSSItem(currentItem)
, (currentItem == m_feedListWidget->stickyUnreadItem()));
m_ui->articleListWidget->setRSSItem(m_ui->feedListWidget->getRSSItem(currentItem)
, (currentItem == m_ui->feedListWidget->stickyUnreadItem()));
}
void RSSWidget::on_markReadButton_clicked()
{
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
for (QTreeWidgetItem *item : asConst(m_ui->feedListWidget->selectedItems()))
{
m_feedListWidget->getRSSItem(item)->markAsRead();
if (item == m_feedListWidget->stickyUnreadItem())
m_ui->feedListWidget->getRSSItem(item)->markAsRead();
if (item == m_ui->feedListWidget->stickyUnreadItem())
break; // all items was read
}
}
@ -491,7 +528,7 @@ void RSSWidget::handleCurrentArticleItemChanged(QListWidgetItem *currentItem, QL
if (previousItem)
{
auto *article = m_articleListWidget->getRSSArticle(previousItem);
auto *article = m_ui->articleListWidget->getRSSArticle(previousItem);
Q_ASSERT(article);
article->markAsRead();
}
@ -499,7 +536,7 @@ void RSSWidget::handleCurrentArticleItemChanged(QListWidgetItem *currentItem, QL
if (!currentItem)
return;
auto *article = m_articleListWidget->getRSSArticle(currentItem);
auto *article = m_ui->articleListWidget->getRSSArticle(currentItem);
renderArticle(article);
}
@ -548,10 +585,10 @@ bool RSSWidget::eventFilter(QObject *obj, QEvent *event)
{
if ((obj == m_ui->textBrowser) && (event->type() == QEvent::PaletteChange))
{
QListWidgetItem *currentItem = m_articleListWidget->currentItem();
QListWidgetItem *currentItem = m_ui->articleListWidget->currentItem();
if (currentItem)
{
const RSS::Article *article = m_articleListWidget->getRSSArticle(currentItem);
const RSS::Article *article = m_ui->articleListWidget->getRSSArticle(currentItem);
renderArticle(article);
}
}
@ -572,7 +609,7 @@ void RSSWidget::renderArticle(const RSS::Article *article) const
u"<div style='background-color: \"%1\"; font-weight: bold; color: \"%2\";'>%3</div>"_s.arg(highlightedBaseColor, highlightedBaseTextColor, article->title());
if (article->date().isValid())
html += u"<div style='background-color: \"%1\";'><b>%2</b>%3</div>"_s.arg(alternateBaseColor, tr("Date: "), QLocale::system().toString(article->date().toLocalTime()));
if (m_feedListWidget->currentItem() == m_feedListWidget->stickyUnreadItem())
if (m_ui->feedListWidget->currentItem() == m_ui->feedListWidget->stickyUnreadItem())
html += u"<div style='background-color: \"%1\";'><b>%2</b>%3</div>"_s.arg(alternateBaseColor, tr("Feed: "), article->feed()->title());
if (!article->author().isEmpty())
html += u"<div style='background-color: \"%1\";'><b>%2</b>%3</div>"_s.arg(alternateBaseColor, tr("Author: "), article->author());
@ -610,6 +647,11 @@ void RSSWidget::renderArticle(const RSS::Article *article) const
html += u"<pre>" + description + u"</pre>";
}
// Supplement relative URLs to absolute ones
const QUrl url {article->link()};
const QString baseUrl = url.toString(QUrl::RemovePath | QUrl::RemoveQuery);
convertRelativeUrlToAbsolute(html, baseUrl);
html += u"</div>";
m_ui->textBrowser->setHtml(html);
}

View file

@ -37,9 +37,6 @@
class QListWidgetItem;
class QTreeWidgetItem;
class ArticleListWidget;
class FeedListWidget;
namespace RSS
{
class Article;
@ -94,6 +91,4 @@ private:
void renderArticle(const RSS::Article *article) const;
Ui::RSSWidget *m_ui = nullptr;
ArticleListWidget *m_articleListWidget = nullptr;
FeedListWidget *m_feedListWidget = nullptr;
};

View file

@ -94,6 +94,7 @@
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<widget class="FeedListWidget" name="feedListWidget"/>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@ -119,6 +120,7 @@
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<widget class="ArticleListWidget" name="articleListWidget"/>
<widget class="HtmlBrowser" name="textBrowser">
<property name="openExternalLinks">
<bool>true</bool>
@ -211,6 +213,16 @@
<extends>QTextBrowser</extends>
<header>gui/rss/htmlbrowser.h</header>
</customwidget>
<customwidget>
<class>FeedListWidget</class>
<extends>QTreeWidget</extends>
<header>gui/rss/feedlistwidget.h</header>
</customwidget>
<customwidget>
<class>ArticleListWidget</class>
<extends>QListWidget</extends>
<header>gui/rss/articlelistwidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View file

@ -20,29 +20,15 @@
<string>User statistics</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelWaste">
<item row="0" column="0">
<widget class="QLabel" name="labelAlltimeULText">
<property name="text">
<string notr="true">TextLabel</string>
<string>All-time upload:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelPeersText">
<property name="text">
<string>Connected peers:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelGlobalRatioText">
<property name="text">
<string>All-time share ratio:</string>
</property>
</widget>
</item>
<item row="4" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelPeers">
<item row="0" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelAlltimeUL">
<property name="text">
<string notr="true">TextLabel</string>
</property>
@ -62,6 +48,13 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelGlobalRatioText">
<property name="text">
<string>All-time share ratio:</string>
</property>
</widget>
</item>
<item row="2" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelGlobalRatio">
<property name="text">
@ -76,15 +69,22 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelAlltimeULText">
<item row="3" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelWaste">
<property name="text">
<string>All-time upload:</string>
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelAlltimeUL">
<item row="4" column="0">
<widget class="QLabel" name="labelPeersText">
<property name="text">
<string>Connected peers:</string>
</property>
</widget>
</item>
<item row="4" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelPeers">
<property name="text">
<string notr="true">TextLabel</string>
</property>
@ -113,13 +113,6 @@
</property>
</widget>
</item>
<item row="1" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelTotalBuf">
<property name="text">
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelTotalBufText">
<property name="text">
@ -127,6 +120,13 @@
</property>
</widget>
</item>
<item row="1" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelTotalBuf">
<property name="text">
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -136,17 +136,10 @@
<string>Performance statistics</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="3" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelJobsTime">
<item row="0" column="0">
<widget class="QLabel" name="labelWriteStarveText">
<property name="text">
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
<item row="2" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelQueuedJobs">
<property name="text">
<string notr="true">TextLabel</string>
<string>Write cache overload:</string>
</property>
</widget>
</item>
@ -157,6 +150,13 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelReadStarveText">
<property name="text">
<string>Read cache overload:</string>
</property>
</widget>
</item>
<item row="1" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelReadStarve">
<property name="text">
@ -171,10 +171,10 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelWriteStarveText">
<item row="2" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelQueuedJobs">
<property name="text">
<string>Write cache overload:</string>
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
@ -185,10 +185,10 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelReadStarveText">
<item row="3" column="1" alignment="Qt::AlignmentFlag::AlignRight">
<widget class="QLabel" name="labelJobsTime">
<property name="text">
<string>Read cache overload:</string>
<string notr="true">TextLabel</string>
</property>
</widget>
</item>

View file

@ -173,12 +173,6 @@
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>textCategoryName</tabstop>
<tabstop>comboSavePath</tabstop>
<tabstop>comboUseDownloadPath</tabstop>
<tabstop>comboDownloadPath</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -313,11 +313,21 @@
<string>Fields</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="lbl_announce_url">
<property name="text">
<string>Tracker URLs:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QTextEdit" name="trackersList">
<property name="toolTip">
<string>You can separate tracker tiers / groups with an empty line.</string>
</property>
<property name="tabChangesFocus">
<bool>true</bool>
</property>
<property name="acceptRichText">
<bool>false</bool>
</property>
@ -332,25 +342,14 @@
</item>
<item row="1" column="1">
<widget class="QTextEdit" name="URLSeedsList">
<property name="tabChangesFocus">
<bool>true</bool>
</property>
<property name="acceptRichText">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QTextEdit" name="txtComment">
<property name="acceptRichText">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lbl_announce_url">
<property name="text">
<string>Tracker URLs:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbl_comment">
<property name="text">
@ -358,6 +357,16 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QTextEdit" name="txtComment">
<property name="tabChangesFocus">
<bool>true</bool>
</property>
<property name="acceptRichText">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelSource">
<property name="text">
@ -413,23 +422,6 @@
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>textInputPath</tabstop>
<tabstop>addFileButton</tabstop>
<tabstop>addFolderButton</tabstop>
<tabstop>comboTorrentFormat</tabstop>
<tabstop>comboPieceSize</tabstop>
<tabstop>buttonCalcTotalPieces</tabstop>
<tabstop>checkPrivate</tabstop>
<tabstop>checkStartSeeding</tabstop>
<tabstop>checkIgnoreShareLimits</tabstop>
<tabstop>checkOptimizeAlignment</tabstop>
<tabstop>spinPaddedFileSizeLimit</tabstop>
<tabstop>trackersList</tabstop>
<tabstop>URLSeedsList</tabstop>
<tabstop>txtComment</tabstop>
<tabstop>lineEditSource</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -52,6 +52,13 @@
</item>
<item>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="labelCategory">
<property name="text">
<string>Category:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboCategory">
<property name="sizePolicy">
@ -71,13 +78,6 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelCategory">
<property name="text">
<string>Category:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
@ -86,26 +86,17 @@
<string>Torrent Speed Limits</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Download:</string>
<string>Upload:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="spinDownloadLimit">
<property name="specialValueText">
<string>∞</string>
</property>
<property name="suffix">
<string> KiB/s</string>
</property>
<property name="maximum">
<number>2000000</number>
</property>
<property name="stepType">
<enum>QAbstractSpinBox::StepType::AdaptiveDecimalStepType</enum>
<item row="0" column="1">
<widget class="QSlider" name="sliderUploadLimit">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
</widget>
</item>
@ -125,24 +116,10 @@
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLabel" name="labelWarning">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>These will not exceed the global limits</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Upload:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="sliderUploadLimit">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
<string>Download:</string>
</property>
</widget>
</item>
@ -153,6 +130,29 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="spinDownloadLimit">
<property name="specialValueText">
<string>∞</string>
</property>
<property name="suffix">
<string> KiB/s</string>
</property>
<property name="maximum">
<number>2000000</number>
</property>
<property name="stepType">
<enum>QAbstractSpinBox::StepType::AdaptiveDecimalStepType</enum>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLabel" name="labelWarning">
<property name="text">
<string>These will not exceed the global limits</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -256,23 +256,6 @@
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>checkAutoTMM</tabstop>
<tabstop>savePath</tabstop>
<tabstop>checkUseDownloadPath</tabstop>
<tabstop>downloadPath</tabstop>
<tabstop>comboCategory</tabstop>
<tabstop>sliderUploadLimit</tabstop>
<tabstop>spinUploadLimit</tabstop>
<tabstop>sliderDownloadLimit</tabstop>
<tabstop>spinDownloadLimit</tabstop>
<tabstop>torrentShareLimitsBox</tabstop>
<tabstop>checkDisableDHT</tabstop>
<tabstop>checkSequential</tabstop>
<tabstop>checkDisablePEX</tabstop>
<tabstop>checkFirstLastPieces</tabstop>
<tabstop>checkDisableLSD</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -13,8 +13,60 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="limitsLayout">
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxInactiveSeedingTimeMode">
<item row="0" column="0">
<widget class="QLabel" name="labelRatio">
<property name="text">
<string>Ratio:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxRatioMode">
<property name="currentIndex">
<number>-1</number>
</property>
<item>
<property name="text">
<string>Default</string>
</property>
</item>
<item>
<property name="text">
<string>Unlimited</string>
</property>
</item>
<item>
<property name="text">
<string>Set to</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QDoubleSpinBox" name="spinBoxRatioValue">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximum">
<double>9998.000000000000000</double>
</property>
<property name="singleStep">
<double>0.050000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelSeedingTime">
<property name="text">
<string>Seeding time:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBoxSeedingTimeMode">
<property name="currentIndex">
<number>-1</number>
</property>
@ -51,13 +103,6 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelRatio">
<property name="text">
<string>Ratio:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelInactiveSeedingTime">
<property name="text">
@ -65,6 +110,28 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxInactiveSeedingTimeMode">
<property name="currentIndex">
<number>-1</number>
</property>
<item>
<property name="text">
<string>Default</string>
</property>
</item>
<item>
<property name="text">
<string>Unlimited</string>
</property>
</item>
<item>
<property name="text">
<string>Set to</string>
</property>
</item>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="spinBoxInactiveSeedingTimeValue">
<property name="enabled">
@ -81,73 +148,6 @@
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QDoubleSpinBox" name="spinBoxRatioValue">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximum">
<double>9998.000000000000000</double>
</property>
<property name="singleStep">
<double>0.050000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBoxSeedingTimeMode">
<property name="currentIndex">
<number>-1</number>
</property>
<item>
<property name="text">
<string>Default</string>
</property>
</item>
<item>
<property name="text">
<string>Unlimited</string>
</property>
</item>
<item>
<property name="text">
<string>Set to</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxRatioMode">
<property name="currentIndex">
<number>-1</number>
</property>
<item>
<property name="text">
<string>Default</string>
</property>
</item>
<item>
<property name="text">
<string>Unlimited</string>
</property>
</item>
<item>
<property name="text">
<string>Set to</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelSeedingTime">
<property name="text">
<string>Seeding time:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
@ -208,15 +208,6 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>comboBoxRatioMode</tabstop>
<tabstop>spinBoxRatioValue</tabstop>
<tabstop>comboBoxSeedingTimeMode</tabstop>
<tabstop>spinBoxSeedingTimeValue</tabstop>
<tabstop>comboBoxInactiveSeedingTimeMode</tabstop>
<tabstop>spinBoxInactiveSeedingTimeValue</tabstop>
<tabstop>comboBoxAction</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -23,6 +23,9 @@
</item>
<item>
<widget class="QTextEdit" name="textEditTrackersList">
<property name="tabChangesFocus">
<bool>true</bool>
</property>
<property name="lineWrapMode">
<enum>QTextEdit::LineWrapMode::NoWrap</enum>
</property>