Show a free space bar in the organise dialog, and also show how much space would be taken up after copying files.

This commit is contained in:
David Sansome 2010-07-29 22:16:12 +00:00
parent 3ad30d14a8
commit 6f259d4ecc
13 changed files with 123 additions and 28 deletions

View File

@ -26,7 +26,11 @@ public:
MusicStorage();
virtual ~MusicStorage() {}
static const int kStorageRole = Qt::UserRole + 100;
enum Role {
Role_Storage = Qt::UserRole + 100,
Role_Capacity,
Role_FreeSpace,
};
virtual QString LocalPath() const { return QString(); }

View File

@ -19,6 +19,8 @@
#include <QCoreApplication>
#include <QStringList>
#include <sys/statvfs.h>
namespace Utilities {
static QString tr(const char* str) {
@ -72,4 +74,20 @@ QString PrettySize(quint64 bytes) {
return ret;
}
quint64 FileSystemCapacity(const QString& path) {
struct statvfs fs_info;
if (statvfs(path.toLocal8Bit().constData(), &fs_info) == 0)
return fs_info.f_blocks * fs_info.f_bsize;
return 0;
}
quint64 FileSystemFreeSpace(const QString& path) {
struct statvfs fs_info;
if (statvfs(path.toLocal8Bit().constData(), &fs_info) == 0)
return fs_info.f_bavail * fs_info.f_bsize;
return 0;
}
} // namespace

View File

@ -23,6 +23,9 @@ namespace Utilities {
QString PrettyTime(int seconds);
QString PrettySize(quint64 bytes);
QString WordyTime(quint64 seconds);
quint64 FileSystemCapacity(const QString& path);
quint64 FileSystemFreeSpace(const QString& path);
}
#endif // UTILITIES_H

View File

@ -17,6 +17,7 @@
#include "config.h"
#include "devicekitlister.h"
#include "filesystemdevice.h"
#include "core/utilities.h"
#include "dbus/udisks.h"
#include "dbus/udisksdevice.h"
@ -178,12 +179,8 @@ DeviceKitLister::DeviceData DeviceKitLister::ReadDeviceData(
ret.device_mount_paths = device.deviceMountPaths();
// Get free space info
if (!ret.device_mount_paths.isEmpty()) {
struct statvfs fs_info;
if (statvfs(ret.device_mount_paths[0].toLocal8Bit().constData(), &fs_info) == 0) {
ret.free_space = fs_info.f_bavail * fs_info.f_bsize;
}
}
if (!ret.device_mount_paths.isEmpty())
ret.free_space = Utilities::FileSystemFreeSpace(ret.device_mount_paths[0]);
return ret;
}

View File

@ -217,9 +217,11 @@ QVariant DeviceManager::data(const QModelIndex& index, int role) const {
return info.icon_name_;
case Role_Capacity:
case MusicStorage::Role_Capacity:
return info.size_;
case Role_FreeSpace:
case MusicStorage::Role_FreeSpace:
return info.BestBackend()->lister_ ?
info.BestBackend()->lister_->DeviceFreeSpace(info.BestBackend()->unique_id_) :
QVariant();
@ -236,7 +238,7 @@ QVariant DeviceManager::data(const QModelIndex& index, int role) const {
return QVariant();
return info.task_percentage_;
case MusicStorage::kStorageRole:
case MusicStorage::Role_Storage:
if (!info.device_)
const_cast<DeviceManager*>(this)->Connect(index.row());
if (!info.device_)

View File

@ -18,6 +18,7 @@
#include "librarybackend.h"
#include "core/filesystemmusicstorage.h"
#include "core/musicstorage.h"
#include "core/utilities.h"
#include "ui/iconloader.h"
LibraryDirectoryModel::LibraryDirectoryModel(LibraryBackend* backend, QObject* parent)
@ -70,9 +71,17 @@ void LibraryDirectoryModel::RemoveDirectory(const QModelIndex& index) {
}
QVariant LibraryDirectoryModel::data(const QModelIndex &index, int role) const {
if (role == MusicStorage::kStorageRole) {
switch (role) {
case MusicStorage::Role_Storage:
return QVariant::fromValue(storage_[index.row()]);
}
return QStandardItemModel::data(index, role);
case MusicStorage::Role_FreeSpace:
return Utilities::FileSystemFreeSpace(data(index, Qt::DisplayRole).toString());
case MusicStorage::Role_Capacity:
return Utilities::FileSystemCapacity(data(index, Qt::DisplayRole).toString());
default:
return QStandardItemModel::data(index, role);
}
}

View File

@ -250,24 +250,30 @@ void LibraryView::scrollTo(const QModelIndex &index, ScrollHint hint) {
QTreeView::scrollTo(index, hint);
}
QStringList LibraryView::GetSelectedFilenames() const {
void LibraryView::GetSelectedFileInfo(
QStringList *filenames, quint64 *size) const {
QModelIndexList selected_indexes =
qobject_cast<QSortFilterProxyModel*>(model())->mapSelectionToSource(
selectionModel()->selection()).indexes();
SongList songs = library_->GetChildSongs(selected_indexes);
QStringList ret;
*size = 0;
foreach (const Song& song, songs) {
ret << song.filename();
}
*filenames << song.filename();
return ret;
if (song.filesize() >= 0)
*size += song.filesize();
}
}
void LibraryView::Organise() {
QStringList filenames;
quint64 size = 0;
GetSelectedFileInfo(&filenames, &size);
organise_dialog_->SetDestinationModel(library_->directory_model());
organise_dialog_->SetCopy(false);
organise_dialog_->SetFilenames(GetSelectedFilenames());
organise_dialog_->SetFilenames(filenames, size);
organise_dialog_->show();
}
@ -276,8 +282,12 @@ void LibraryView::Delete() {
}
void LibraryView::CopyToDevice() {
QStringList filenames;
quint64 size = 0;
GetSelectedFileInfo(&filenames, &size);
organise_dialog_->SetDestinationModel(devices_->connected_devices_model(), true);
organise_dialog_->SetCopy(true);
organise_dialog_->SetFilenames(GetSelectedFilenames());
organise_dialog_->SetFilenames(filenames, size);
organise_dialog_->show();
}

View File

@ -78,7 +78,7 @@ class LibraryView : public AutoExpandingTreeView {
private:
void RecheckIsEmpty();
void ShowInVarious(bool on);
QStringList GetSelectedFilenames() const;
void GetSelectedFileInfo(QStringList* filenames, quint64* size) const;
private:
LibraryModel* library_;

View File

@ -97,7 +97,7 @@ void OrganiseDialog::SetDestinationModel(QAbstractItemModel *model, bool devices
ui_->eject_after->setVisible(devices);
}
void OrganiseDialog::SetUrls(const QList<QUrl> &urls) {
void OrganiseDialog::SetUrls(const QList<QUrl> &urls, quint64 total_size) {
QStringList filenames;
// Only add file:// URLs
@ -107,10 +107,10 @@ void OrganiseDialog::SetUrls(const QList<QUrl> &urls) {
filenames << url.toLocalFile();
}
SetFilenames(filenames);
SetFilenames(filenames, total_size);
}
void OrganiseDialog::SetFilenames(const QStringList& filenames) {
void OrganiseDialog::SetFilenames(const QStringList& filenames, quint64 total_size) {
filenames_ = filenames;
preview_songs_.clear();
@ -120,6 +120,9 @@ void OrganiseDialog::SetFilenames(const QStringList& filenames) {
LoadPreviewSongs(filenames_[i]);
}
ui_->free_space->set_additional_bytes(total_size);
qDebug() << "Total bytes" << total_size;
UpdatePreviews();
}
@ -158,7 +161,7 @@ void OrganiseDialog::UpdatePreviews() {
bool has_local_destination = false;
if (destination.isValid()) {
storage = destination.data(MusicStorage::kStorageRole).value<MusicStorage*>();
storage = destination.data(MusicStorage::Role_Storage).value<MusicStorage*>();
has_local_destination = !storage->LocalPath().isEmpty();
}
@ -173,6 +176,18 @@ void OrganiseDialog::UpdatePreviews() {
if (!format_valid)
return;
// Update the free space bar
quint64 capacity = destination.data(MusicStorage::Role_Capacity).toLongLong();
quint64 free = destination.data(MusicStorage::Role_FreeSpace).toLongLong();
if (!capacity) {
ui_->free_space->hide();
} else {
ui_->free_space->show();
ui_->free_space->set_free_bytes(free);
ui_->free_space->set_total_bytes(capacity);
}
// Update the previews
ui_->preview->clear();
ui_->preview_group->setVisible(has_local_destination);
@ -232,7 +247,7 @@ void OrganiseDialog::accept() {
const QModelIndex destination = ui_->destination->model()->index(
ui_->destination->currentIndex(), 0);
MusicStorage* storage =
destination.data(MusicStorage::kStorageRole).value<MusicStorage*>();
destination.data(MusicStorage::Role_Storage).value<MusicStorage*>();
// It deletes itself when it's finished.
const bool copy = ui_->aftercopying->currentIndex() == 0;

View File

@ -47,8 +47,8 @@ public:
void SetDestinationModel(QAbstractItemModel* model, bool devices = false);
void SetUrls(const QList<QUrl>& urls);
void SetFilenames(const QStringList& filenames);
void SetUrls(const QList<QUrl>& urls, quint64 total_size = 0);
void SetFilenames(const QStringList& filenames, quint64 total_size = 0);
void SetCopy(bool copy);
public slots:

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>588</width>
<height>497</height>
<height>525</height>
</rect>
</property>
<property name="windowTitle">
@ -53,6 +53,9 @@
</item>
</layout>
</item>
<item>
<widget class="FreeSpaceBar" name="free_space" native="true"/>
</item>
<item>
<widget class="QCheckBox" name="eject_after">
<property name="text">
@ -151,6 +154,12 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>FreeSpaceBar</class>
<extends>QWidget</extends>
<header>widgets/freespacebar.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LineTextEdit</class>
<extends>QTextEdit</extends>

View File

@ -25,6 +25,8 @@ const int FreeSpaceBar::kMarkerSpacing = 32;
const QRgb FreeSpaceBar::kColorBg1 = qRgb(214, 207, 200);
const QRgb FreeSpaceBar::kColorBg2 = qRgb(234, 226, 218);
const QRgb FreeSpaceBar::kColorAdd1 = qRgb(250, 182, 134);
const QRgb FreeSpaceBar::kColorAdd2 = qRgb(229, 157, 105);
const QRgb FreeSpaceBar::kColorBar1 = qRgb(250, 148, 76);
const QRgb FreeSpaceBar::kColorBar2 = qRgb(214, 102, 24);
const QRgb FreeSpaceBar::kColorBorder = qRgb(174, 168, 162);
@ -32,7 +34,8 @@ const QRgb FreeSpaceBar::kColorBorder = qRgb(174, 168, 162);
FreeSpaceBar::FreeSpaceBar(QWidget *parent)
: QWidget(parent),
free_(33),
free_(100),
additional_(0),
total_(100)
{
setMinimumHeight(kBarHeight);
@ -43,6 +46,11 @@ void FreeSpaceBar::set_free_bytes(quint64 bytes) {
update();
}
void FreeSpaceBar::set_additional_bytes(quint64 bytes) {
additional_ = bytes;
update();
}
void FreeSpaceBar::set_total_bytes(quint64 bytes) {
total_ = bytes;
update();
@ -74,6 +82,20 @@ void FreeSpaceBar::paintEvent(QPaintEvent*) {
p.setBrush(background_gradient);
p.drawRoundedRect(background_rect, kBarBorderRadius, kBarBorderRadius);
// Draw any additional space
if (additional_) {
QRect additional_rect(bar_rect);
additional_rect.setWidth(float(background_rect.width()) * (
float(qMin(total_, total_ - free_ + additional_)) / total_));
QLinearGradient additional_gradient(additional_rect.topLeft(), additional_rect.bottomLeft());
additional_gradient.setColorAt(0, kColorAdd1);
additional_gradient.setColorAt(1, kColorAdd2);
p.setBrush(additional_gradient);
p.drawRoundedRect(additional_rect, kBarBorderRadius, kBarBorderRadius);
}
// Draw the bar foreground
p.setBrush(bar_gradient);
p.drawRoundedRect(bar_rect, kBarBorderRadius, kBarBorderRadius);

View File

@ -22,6 +22,7 @@
class FreeSpaceBar : public QWidget {
Q_OBJECT
Q_PROPERTY(quint64 free READ free_bytes WRITE set_free_bytes);
Q_PROPERTY(quint64 additional READ additional_bytes WRITE set_additional_bytes);
Q_PROPERTY(quint64 total READ total_bytes WRITE set_total_bytes);
public:
@ -33,13 +34,17 @@ public:
static const QRgb kColorBg1;
static const QRgb kColorBg2;
static const QRgb kColorAdd1;
static const QRgb kColorAdd2;
static const QRgb kColorBar1;
static const QRgb kColorBar2;
static const QRgb kColorBorder;
quint64 free_bytes() const { return free_; }
quint64 additional_bytes() const { return additional_; }
quint64 total_bytes() const { return total_; }
void set_free_bytes(quint64 bytes);
void set_additional_bytes(quint64 bytes);
void set_total_bytes(quint64 bytes);
QSize sizeHint() const;
@ -49,6 +54,7 @@ protected:
private:
quint64 free_;
quint64 additional_;
quint64 total_;
};