File: driveselectiondelegate.cpp

package info (click to toggle)
kup-backup 0.10.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,576 kB
  • sloc: cpp: 8,422; xml: 311; makefile: 6; sh: 3
file content (172 lines) | stat: -rw-r--r-- 7,520 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// SPDX-FileCopyrightText: 2020 Simon Persson <simon.persson@mykolab.com>
//
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL

#include "driveselectiondelegate.h"
#include "driveselection.h"

#include <QApplication>
#include <QIcon>
#include <QPainter>
#include <QStyle>

#include <KCapacityBar>
#include <KFormat>
#include <KIO/Global>
#include <KLocalizedString>

static const int cMargin = 6;

DriveSelectionDelegate::DriveSelectionDelegate(QListView *pParent)
    : QStyledItemDelegate(pParent)
    , mCapacityBar(new KCapacityBar(KCapacityBar::DrawTextInline))
    , mListView(pParent)
{
}

DriveSelectionDelegate::~DriveSelectionDelegate()
{
    delete mCapacityBar;
}

void DriveSelectionDelegate::paint(QPainter *pPainter, const QStyleOptionViewItem &pOption, const QModelIndex &pIndex) const
{
    pPainter->save();
    pPainter->setRenderHint(QPainter::Antialiasing);
    QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &pOption, pPainter);

    auto lTotalSize = pIndex.data(DriveSelection::TotalSpace).toULongLong();
    auto lUsedSize = pIndex.data(DriveSelection::UsedSpace).toULongLong();
    bool lIsDisconnected = pIndex.data(DriveSelection::UDI).toString().isEmpty();

    auto lFontMetrics = mListView->fontMetrics();

    if (lTotalSize == 0 || lIsDisconnected) {
        mCapacityBar->setValue(0);
    } else {
        mCapacityBar->setValue(static_cast<int>((lUsedSize * 100) / lTotalSize));
    }
    mCapacityBar->drawCapacityBar(
        pPainter,
        pOption.rect.adjusted(cMargin, cMargin + lFontMetrics.height() + cMargin, -cMargin, 4 * cMargin + lFontMetrics.height() - pOption.rect.height()));

    if (pOption.state & QStyle::State_HasFocus)
        pPainter->setPen(pOption.palette.color(QPalette::HighlightedText));
    else
        pPainter->setPen(pOption.palette.color(QPalette::Text));

    KFormat lFormat;
    QString lDisplayLabel, lPartitionLabel, lDisconnectedLabel;
    int lTextEnd = pOption.rect.right() - cMargin;
    if (lIsDisconnected) {
        lDisconnectedLabel = xi18nc("@item:inlistbox this text is added if selected drive is disconnected", " (disconnected)");
    } else {
        lDisconnectedLabel = QString();
        if (lTotalSize > 0) {
            QString lFreeSpace = xi18nc("@label %1 is amount of free storage space of hard drive", "%1 free", lFormat.formatByteSize(lTotalSize - lUsedSize));
            int lTextWidth = lFontMetrics.horizontalAdvance(lFreeSpace);
            lTextEnd -= lTextWidth + cMargin;
            QPoint lOffset = QPoint(-cMargin - lTextWidth, cMargin + lFontMetrics.height());
            pPainter->drawText(pOption.rect.topRight() + lOffset, lFreeSpace);
        }
    }

    QString lDeviceDescription = pIndex.data(DriveSelection::DeviceDescription).toString();
    QString lLabel = pIndex.data(DriveSelection::Label).toString();
    int lPartitionNumber = pIndex.data(DriveSelection::PartitionNumber).toInt();
    if (lLabel.isEmpty() || lLabel == lDeviceDescription) {
        if (pIndex.data(DriveSelection::PartitionsOnDrive).toInt() > 1) {
            lPartitionLabel = xi18nc(
                "@item:inlistbox used for unnamed filesystems, more than one filesystem on device. %1 is partition number, %2 is device description, %3 is "
                "either empty or the \" (disconnected)\" text",
                "Partition %1 on %2%3",
                lPartitionNumber,
                lDeviceDescription,
                lDisconnectedLabel);
        } else {
            lPartitionLabel = xi18nc(
                "@item:inlistbox used when there is only one unnamed filesystem on device. %1 is device description, %2 is either empty or the \" "
                "(disconnected)\" text",
                "%1%2",
                lDeviceDescription,
                lDisconnectedLabel);
        }
    } else {
        lPartitionLabel = xi18nc("@item:inlistbox %1 is filesystem label, %2 is the device description, %3 is either empty or the \" (disconnected)\" text",
                                 "%1 on %2%3",
                                 lLabel,
                                 lDeviceDescription,
                                 lDisconnectedLabel);
    }

    if (lTotalSize == 0) {
        lDisplayLabel = lPartitionLabel;
    } else {
        lDisplayLabel = xi18nc("@item:inlistbox %1 is drive(partition) label, %2 is storage capacity",
                               "%1: %2 total capacity",
                               lPartitionLabel,
                               lFormat.formatByteSize(lTotalSize));
    }
    lDisplayLabel = lFontMetrics.elidedText(lDisplayLabel, Qt::ElideMiddle, lTextEnd - pOption.rect.left() - cMargin);
    pPainter->drawText(pOption.rect.topLeft() + QPoint(cMargin, cMargin + lFontMetrics.height()), lDisplayLabel);

    int lIconSize = 48;
    QRect lWarningRect = warningRect(pOption.rect.adjusted(lIconSize + cMargin, 0, 0, 0), pIndex);
    if (!lWarningRect.isEmpty()) {
        QIcon lIcon = QIcon::fromTheme(QStringLiteral("dialog-warning"));
        lIcon.paint(pPainter, lWarningRect.left() - cMargin - lIconSize, lWarningRect.top(), lIconSize, lIconSize);
        pPainter->drawText(lWarningRect, Qt::AlignVCenter | Qt::TextWordWrap, warningText(pIndex));
    }

    pPainter->restore();
}

QSize DriveSelectionDelegate::sizeHint(const QStyleOptionViewItem &pOption, const QModelIndex &pIndex) const
{
    Q_UNUSED(pOption)
    auto lFontMetrics = mListView->fontMetrics();
    QSize lSize;
    lSize.setWidth(cMargin * 2 + lFontMetrics.horizontalAdvance(pIndex.data().toString()));
    lSize.setHeight(cMargin * 5 + lFontMetrics.height());
    int lIconSize = 48;
    QRect lWarningRect = warningRect(mListView->rect().adjusted(lIconSize + cMargin, 0, 0, 0), pIndex);
    if (!lWarningRect.isEmpty()) {
        lSize.setHeight(lSize.height() + 2 * cMargin + lWarningRect.height());
    }
    return lSize;
}

QRect DriveSelectionDelegate::warningRect(const QRect &pRect, const QModelIndex &pIndex) const
{
    auto lFontMetrics = mListView->fontMetrics();
    QRect lTextLocation = pRect.adjusted(cMargin, 5 * cMargin + lFontMetrics.height(), -cMargin, -cMargin);
    QString lWarningText = warningText(pIndex);
    if (lWarningText.isEmpty()) {
        return {};
    }
    QRect lTextBoundary = lFontMetrics.boundingRect(lTextLocation, Qt::TextWordWrap, lWarningText);
    int lIconSize = 48;
    if (lTextBoundary.height() < lIconSize) {
        lTextBoundary.setHeight(lIconSize);
    }
    return lTextBoundary;
}

QString DriveSelectionDelegate::warningText(const QModelIndex &pIndex)
{
    bool lPermissionWarning = pIndex.data(DriveSelection::PermissionLossWarning).toBool();
    bool lSymlinkWarning = pIndex.data(DriveSelection::SymlinkLossWarning).toBool();
    if (lPermissionWarning && lSymlinkWarning) {
        return xi18nc("@item:inlistbox",
                      "Warning: Symbolic links and file permissions can not be saved "
                      "to this file system. File permissions only matters if there is more than one "
                      "user of this computer or if you are backing up executable program files.");
    }
    if (lPermissionWarning) {
        return xi18nc("@item:inlistbox",
                      "Warning: File permissions can not be saved to this file "
                      "system. File permissions only matters if there is more than one "
                      "user of this computer or if you are backing up executable program files.");
    }
    return {};
}