Skip to content

Commit 848548e

Browse files
committed
Allow to edit common path of torrent content items
1 parent 52d3a96 commit 848548e

6 files changed

Lines changed: 127 additions & 17 deletions

File tree

src/base/path.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,21 @@ Path Path::commonPath(const Path &left, const Path &right)
312312
return Path::createUnchecked(left.m_pathStr.first(commonPathSize));
313313
}
314314

315+
Path Path::commonPath(const PathList &filePaths)
316+
{
317+
if (filePaths.isEmpty())
318+
return {};
319+
320+
if (filePaths.size() == 1)
321+
return filePaths.at(0);
322+
323+
Path commonPath = Path::commonPath(filePaths.at(0), filePaths.at(1));
324+
for (qsizetype i = 2; i < filePaths.size(); ++ i)
325+
commonPath = Path::commonPath(commonPath, filePaths.at(i));
326+
327+
return commonPath;
328+
}
329+
315330
Path Path::findRootFolder(const PathList &filePaths)
316331
{
317332
Path rootFolder;

src/base/path.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class Path final
8282
Iterator end() const;
8383

8484
static Path commonPath(const Path &left, const Path &right);
85+
static Path commonPath(const PathList &filePaths);
8586

8687
static Path findRootFolder(const PathList &filePaths);
8788
static void stripRootFolder(PathList &filePaths);

src/gui/torrentcontentlayoutdialog.cpp

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,12 @@ TorrentContentLayoutDialog::TorrentContentLayoutDialog(BitTorrent::TorrentConten
8080
setWindowIcon(UIThemeManager::instance()->getIcon(u"edit-rename"_s));
8181

8282
m_model = new TorrentContentLayoutModel(contentHandler, this);
83-
m_ui->treeView->setModel(m_model);
83+
m_ui->pathListView->setModel(m_model);
8484
if (m_model->rowCount() > 0)
8585
{
86-
m_ui->treeView->selectionModel()->setCurrentIndex(m_model->index(0, 0)
86+
m_ui->pathListView->selectionModel()->setCurrentIndex(m_model->index(0, 0)
8787
, (QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows));
88+
populateCommonPath();
8889
}
8990

9091
connect(m_model, &QAbstractItemModel::dataChanged, this, [this]
@@ -105,21 +106,97 @@ TorrentContentLayoutDialog::TorrentContentLayoutDialog(BitTorrent::TorrentConten
105106
RaisedMessageBox::warning(this, tr("Rename error"), errorMessage, QMessageBox::Ok);
106107
});
107108

108-
m_ui->treeView->setItemDelegate(new TorrentContentLayoutItemDelegate(this));
109+
m_ui->pathListView->setItemDelegate(new TorrentContentLayoutItemDelegate(this));
110+
111+
connect(m_ui->pathListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TorrentContentLayoutDialog::populateCommonPath);
112+
connect(m_ui->commonPathEdit, &QLineEdit::textEdited, this, &TorrentContentLayoutDialog::onCommonPathEdited);
109113

110114
if (const QSize dialogSize = m_storeDialogSize; dialogSize.isValid())
111115
resize(dialogSize);
112116

113-
m_ui->treeView->header()->restoreState(m_storeViewState);
117+
m_ui->pathListView->header()->restoreState(m_storeViewState);
114118
}
115119

116120
TorrentContentLayoutDialog::~TorrentContentLayoutDialog()
117121
{
118122
m_storeDialogSize = size();
119-
m_storeViewState = m_ui->treeView->header()->saveState();
123+
m_storeViewState = m_ui->pathListView->header()->saveState();
120124
delete m_ui;
121125
}
122126

127+
Path TorrentContentLayoutDialog::currentPath() const
128+
{
129+
const QModelIndex currentIndex = m_ui->pathListView->selectionModel()->currentIndex();
130+
if (!currentIndex.isValid())
131+
return {};
132+
133+
return Path(currentIndex.siblingAtColumn(TorrentContentLayoutModel::COL_PATH).data().toString());
134+
}
135+
136+
PathList TorrentContentLayoutDialog::selectedPaths() const
137+
{
138+
const QModelIndexList selectedRows = m_ui->pathListView->selectionModel()->selectedRows(TorrentContentLayoutModel::COL_PATH);
139+
if (selectedRows.isEmpty())
140+
return {};
141+
142+
PathList selectedPaths;
143+
selectedPaths.reserve(selectedRows.size());
144+
for (const QModelIndex &rowIndex : selectedRows)
145+
selectedPaths.append(Path(rowIndex.data().toString()));
146+
147+
return selectedPaths;
148+
}
149+
150+
void TorrentContentLayoutDialog::populateCommonPath()
151+
{
152+
PathList paths = selectedPaths();
153+
if (paths.isEmpty())
154+
{
155+
const Path currentPath = this->currentPath();
156+
if (currentPath.isValid())
157+
paths.append(currentPath);
158+
}
159+
160+
if (!paths.isEmpty())
161+
{
162+
m_commonPath = Path::commonPath(paths);
163+
m_ui->commonPathEdit->setText(m_commonPath.toString());
164+
m_ui->commonPathLabel->setEnabled(true);
165+
m_ui->commonPathEdit->setEnabled(true);
166+
}
167+
else
168+
{
169+
m_commonPath = {};
170+
m_ui->commonPathEdit->clear();
171+
m_ui->commonPathLabel->setEnabled(false);
172+
m_ui->commonPathEdit->setEnabled(false);
173+
}
174+
}
175+
176+
void TorrentContentLayoutDialog::onCommonPathEdited(const QString &pathStr)
177+
{
178+
const Path oldCommonPath = m_commonPath;
179+
m_commonPath = Path(pathStr);
180+
181+
QModelIndexList selectedRows = m_ui->pathListView->selectionModel()->selectedRows(TorrentContentLayoutModel::COL_PATH);
182+
if (selectedRows.isEmpty())
183+
{
184+
const QModelIndex currentIndex = m_ui->pathListView->selectionModel()->currentIndex();
185+
if (currentIndex.isValid())
186+
selectedRows.append(currentIndex.siblingAtColumn(TorrentContentLayoutModel::COL_PATH));
187+
}
188+
189+
if (selectedRows.isEmpty())
190+
return;
191+
192+
for (const QModelIndex &rowIndex : selectedRows)
193+
{
194+
const Path oldPath {rowIndex.data().toString()};
195+
const Path newPath = m_commonPath / oldCommonPath.relativePathOf(oldPath);
196+
m_model->setData(rowIndex, newPath.toString());
197+
}
198+
}
199+
123200
void TorrentContentLayoutDialog::apply()
124201
{
125202
m_model->applyChangedFilePaths();

src/gui/torrentcontentlayoutdialog.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <QDialog>
3232

33+
#include "base/path.h"
3334
#include "base/settingvalue.h"
3435

3536
class TorrentContentLayoutModel;
@@ -54,6 +55,10 @@ class TorrentContentLayoutDialog final : public QDialog
5455
~TorrentContentLayoutDialog();
5556

5657
private:
58+
Path currentPath() const;
59+
PathList selectedPaths() const;
60+
void populateCommonPath();
61+
void onCommonPathEdited(const QString &pathStr);
5762
void apply();
5863

5964
Ui::TorrentContentLayoutDialog *m_ui = nullptr;
@@ -62,4 +67,6 @@ class TorrentContentLayoutDialog final : public QDialog
6267

6368
SettingValue<QSize> m_storeDialogSize;
6469
SettingValue<QByteArray> m_storeViewState;
70+
71+
Path m_commonPath;
6572
};

src/gui/torrentcontentlayoutdialog.ui

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,32 @@
1313
<property name="windowTitle">
1414
<string>Manage Torrent Content</string>
1515
</property>
16-
<layout class="QVBoxLayout" name="verticalLayout_2">
16+
<layout class="QVBoxLayout" name="dialogLayout">
1717
<item>
18-
<layout class="QHBoxLayout" name="horizontalLayout">
18+
<widget class="QTreeView" name="pathListView">
19+
<property name="editTriggers">
20+
<set>QAbstractItemView::EditTrigger::AllEditTriggers</set>
21+
</property>
22+
<property name="alternatingRowColors">
23+
<bool>true</bool>
24+
</property>
25+
<property name="selectionMode">
26+
<enum>QAbstractItemView::SelectionMode::ExtendedSelection</enum>
27+
</property>
28+
</widget>
29+
</item>
30+
<item>
31+
<layout class="QHBoxLayout" name="commonPathLayout">
1932
<item>
20-
<widget class="QTreeView" name="treeView">
21-
<property name="editTriggers">
22-
<set>QAbstractItemView::EditTrigger::AllEditTriggers</set>
23-
</property>
24-
<property name="alternatingRowColors">
25-
<bool>true</bool>
26-
</property>
27-
<property name="selectionMode">
28-
<enum>QAbstractItemView::SelectionMode::ExtendedSelection</enum>
33+
<widget class="QLabel" name="commonPathLabel">
34+
<property name="text">
35+
<string>Common path:</string>
2936
</property>
3037
</widget>
3138
</item>
39+
<item>
40+
<widget class="QLineEdit" name="commonPathEdit"/>
41+
</item>
3242
</layout>
3343
</item>
3444
<item>

src/gui/torrentcontentlayoutmodel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class TorrentContentLayoutModel final : public QAbstractItemModel
6969
Qt::ItemFlags flags(const QModelIndex &index) const override;
7070
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
7171

72-
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
72+
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
7373

7474
bool haveChangedFilePaths() const;
7575
void applyChangedFilePaths();

0 commit comments

Comments
 (0)