Move PartResizerWidget and related from PartitionManager into KPMcore.
This commit is contained in:
parent
3db017e4c1
commit
195e495876
|
@ -1,4 +1,5 @@
|
|||
# Copyright (C) 2008, 2012 by Volker Lanz <vl@fidra.de>
|
||||
# Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
|
@ -21,6 +22,7 @@ include(util/CMakeLists.txt)
|
|||
include(ops/CMakeLists.txt)
|
||||
include(jobs/CMakeLists.txt)
|
||||
include(fs/CMakeLists.txt)
|
||||
include(gui/CMakeLists.txt)
|
||||
|
||||
set(kpmcore_SRCS
|
||||
${BACKEND_SRC}
|
||||
|
@ -29,6 +31,7 @@ set(kpmcore_SRCS
|
|||
${OPS_SRC}
|
||||
${JOBS_SRC}
|
||||
${UTIL_SRC}
|
||||
${GUI_SRC}
|
||||
)
|
||||
|
||||
file(GLOB kpmcore_UIFILES config/*.ui)
|
||||
|
@ -57,6 +60,7 @@ install(FILES ${FS_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/fs/ COMP
|
|||
install(FILES ${JOBS_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/jobs/ COMPONENT Devel)
|
||||
install(FILES ${OPS_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/ops/ COMPONENT Devel)
|
||||
install(FILES ${UTIL_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/util/ COMPONENT Devel)
|
||||
install(FILES ${GUI_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/kpmcore/gui/ COMPONENT Devel)
|
||||
|
||||
############################################
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
set(GUI_SRC
|
||||
gui/partresizerwidget.cpp
|
||||
gui/partwidget.cpp
|
||||
gui/partwidgetbase.cpp
|
||||
)
|
||||
|
||||
set(GUI_LIB_HDRS
|
||||
gui/partresizerwidget.h
|
||||
gui/partwidget.h
|
||||
gui/partwidgetbase.h
|
||||
)
|
|
@ -0,0 +1,501 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008, 2010 by Volker Lanz <vl@fidra.de> *
|
||||
* *
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "gui/partresizerwidget.h"
|
||||
#include "gui/partwidget.h"
|
||||
|
||||
#include "core/partition.h"
|
||||
#include "core/device.h"
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/partitionalignment.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
#include <QPaintEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <QStyleOptionToolBar>
|
||||
#include <QStyleOptionFrameV3>
|
||||
#include <QStyleOptionButton>
|
||||
|
||||
const qint32 PartResizerWidget::m_HandleHeight = 59;
|
||||
|
||||
/** Creates a new PartResizerWidget
|
||||
|
||||
Initializing is mostly done in init().
|
||||
|
||||
@param parent pointer to the parent widget
|
||||
*/
|
||||
PartResizerWidget::PartResizerWidget(QWidget* parent) :
|
||||
QWidget(parent),
|
||||
m_Device(NULL),
|
||||
m_Partition(NULL),
|
||||
m_PartWidget(NULL),
|
||||
m_MinimumFirstSector(0),
|
||||
m_MaximumFirstSector(-1),
|
||||
m_MinimumLastSector(-1),
|
||||
m_MaximumLastSector(0),
|
||||
m_MinimumLength(-1),
|
||||
m_MaximumLength(-1),
|
||||
m_LeftHandle(this),
|
||||
m_RightHandle(this),
|
||||
m_DraggedWidget(NULL),
|
||||
m_Hotspot(0),
|
||||
m_MoveAllowed(true),
|
||||
m_ReadOnly(false),
|
||||
m_Align(true)
|
||||
{
|
||||
}
|
||||
|
||||
/** Intializes the PartResizerWidget
|
||||
@param d the Device the Partition is on
|
||||
@param p the Partition to show and/or resize
|
||||
@param minFirst the minimum value for the first sector
|
||||
@param maxLast the maximum value for the last sector
|
||||
*/
|
||||
void PartResizerWidget::init(Device& d, Partition& p, qint64 minFirst, qint64 maxLast, bool read_only, bool move_allowed)
|
||||
{
|
||||
setDevice(d);
|
||||
setPartition(p);
|
||||
|
||||
setMinimumFirstSector(minFirst);
|
||||
setMaximumLastSector(maxLast);
|
||||
|
||||
setReadOnly(read_only);
|
||||
setMoveAllowed(move_allowed);
|
||||
|
||||
setMinimumLength(qMax(partition().sectorsUsed(), partition().minimumSectors()));
|
||||
setMaximumLength(qMin(totalSectors(), partition().maximumSectors()));
|
||||
|
||||
// set margins to accommodate to top/bottom button asymmetric layouts
|
||||
QStyleOptionButton bOpt;
|
||||
bOpt.initFrom(this);
|
||||
|
||||
QRect buttonRect(style()->subElementRect(QStyle::SE_PushButtonContents, &bOpt));
|
||||
|
||||
int asym = (rect().bottom() - buttonRect.bottom()) - (buttonRect.top() - rect().top());
|
||||
if (asym > 0)
|
||||
setContentsMargins(0, asym, 0, 0);
|
||||
else
|
||||
setContentsMargins(0, 0, 0, asym);
|
||||
|
||||
if (!readOnly())
|
||||
{
|
||||
QPixmap pixmap(handleWidth(), handleHeight());
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter p(&pixmap);
|
||||
QStyleOption opt;
|
||||
opt.state |= QStyle::State_Horizontal;
|
||||
opt.rect = pixmap.rect().adjusted(0, 2, 0, -2);
|
||||
style()->drawControl(QStyle::CE_Splitter, &opt, &p, this);
|
||||
|
||||
leftHandle().setPixmap(pixmap);
|
||||
rightHandle().setPixmap(pixmap);
|
||||
|
||||
leftHandle().setFixedSize(handleWidth(), handleHeight());
|
||||
rightHandle().setFixedSize(handleWidth(), handleHeight());
|
||||
}
|
||||
|
||||
delete m_PartWidget;
|
||||
m_PartWidget = new PartWidget(this, &partition());
|
||||
|
||||
if (!readOnly())
|
||||
{
|
||||
leftHandle().setCursor(Qt::SizeHorCursor);
|
||||
rightHandle().setCursor(Qt::SizeHorCursor);
|
||||
}
|
||||
|
||||
if (moveAllowed())
|
||||
partWidget().setCursor(Qt::SizeAllCursor);
|
||||
|
||||
partWidget().setToolTip(QString());
|
||||
|
||||
updatePositions();
|
||||
}
|
||||
|
||||
qint32 PartResizerWidget::handleWidth() const
|
||||
{
|
||||
return style()->pixelMetric(QStyle::PM_SplitterWidth);
|
||||
}
|
||||
|
||||
qint64 PartResizerWidget::sectorsPerPixel() const
|
||||
{
|
||||
return totalSectors() / (width() - 2 * handleWidth());
|
||||
}
|
||||
|
||||
int PartResizerWidget::partWidgetStart() const
|
||||
{
|
||||
return handleWidth() + (partition().firstSector() - minimumFirstSector()) / sectorsPerPixel();
|
||||
}
|
||||
|
||||
int PartResizerWidget::partWidgetWidth() const
|
||||
{
|
||||
return partition().length() / sectorsPerPixel();
|
||||
}
|
||||
|
||||
void PartResizerWidget::updatePositions()
|
||||
{
|
||||
QMargins margins(contentsMargins());
|
||||
|
||||
partWidget().move(partWidgetStart() + margins.left(), margins.top());
|
||||
partWidget().resize(partWidgetWidth() - margins.left() - margins.right(), height() - margins.top() - margins.bottom());
|
||||
|
||||
leftHandle().move(partWidgetStart() - leftHandle().width(), 0);
|
||||
|
||||
rightHandle().move(partWidgetStart() + partWidgetWidth(), 0);
|
||||
|
||||
partWidget().update();
|
||||
}
|
||||
|
||||
void PartResizerWidget::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
updatePositions();
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
||||
void PartResizerWidget::paintEvent(QPaintEvent*)
|
||||
{
|
||||
// draw sunken frame
|
||||
QPainter painter(this);
|
||||
QStyleOptionFrameV3 opt;
|
||||
opt.initFrom(this);
|
||||
opt.frameShape = QFrame::StyledPanel;
|
||||
opt.rect = contentsRect();
|
||||
opt.lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, this);
|
||||
opt.midLineWidth = 0;
|
||||
opt.state |= QStyle::State_Sunken;
|
||||
|
||||
style()->drawPrimitive(QStyle::PE_PanelLineEdit, &opt, &painter, this);
|
||||
}
|
||||
|
||||
void PartResizerWidget::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
m_DraggedWidget = static_cast<QWidget*>(childAt(event->pos()));
|
||||
|
||||
if (m_DraggedWidget != NULL)
|
||||
{
|
||||
if (partWidget().isAncestorOf(m_DraggedWidget))
|
||||
m_DraggedWidget = &partWidget();
|
||||
|
||||
m_Hotspot = m_DraggedWidget->mapFromParent(event->pos()).x();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PartResizerWidget::checkConstraints(qint64 first, qint64 last) const
|
||||
{
|
||||
return (maximumFirstSector() == -1 || first <= maximumFirstSector()) &&
|
||||
(minimumFirstSector() == 0 || first >= minimumFirstSector()) &&
|
||||
(minimumLastSector() == -1 || last >= minimumLastSector()) &&
|
||||
(maximumLastSector() == 0 || last <= maximumLastSector());
|
||||
}
|
||||
|
||||
bool PartResizerWidget::movePartition(qint64 newFirstSector)
|
||||
{
|
||||
const qint64 originalLength = partition().length();
|
||||
const bool isLengthAligned = PartitionAlignment::isLengthAligned(device(), partition());
|
||||
|
||||
if (maximumFirstSector(align()) > -1 && newFirstSector > maximumFirstSector(align()))
|
||||
newFirstSector = maximumFirstSector(align());
|
||||
|
||||
if (minimumFirstSector(align()) > 0 && newFirstSector < minimumFirstSector(align()))
|
||||
newFirstSector = minimumFirstSector(align());
|
||||
|
||||
if (align())
|
||||
newFirstSector = PartitionAlignment::alignedFirstSector(device(), partition(), newFirstSector, minimumFirstSector(align()), maximumFirstSector(align()), -1, -1);
|
||||
|
||||
qint64 delta = newFirstSector - partition().firstSector();
|
||||
|
||||
if (delta == 0)
|
||||
return false;
|
||||
|
||||
qint64 newLastSector = partition().lastSector() + delta;
|
||||
|
||||
if (minimumLastSector(align()) > -1 && newLastSector < minimumLastSector(align()))
|
||||
{
|
||||
const qint64 deltaLast = minimumLastSector(align()) - newLastSector;
|
||||
newFirstSector += deltaLast;
|
||||
newLastSector += deltaLast;
|
||||
}
|
||||
|
||||
if (maximumLastSector(align()) > 0 && newLastSector > maximumLastSector(align()))
|
||||
{
|
||||
const qint64 deltaLast = newLastSector - maximumLastSector(align());
|
||||
newFirstSector -= deltaLast;
|
||||
newLastSector -= deltaLast;
|
||||
}
|
||||
|
||||
if (align())
|
||||
newLastSector = PartitionAlignment::alignedLastSector(device(), partition(), newLastSector, minimumLastSector(align()), maximumLastSector(align()), -1, -1, originalLength, isLengthAligned);
|
||||
|
||||
if (newLastSector == partition().lastSector())
|
||||
return false;
|
||||
|
||||
if (isLengthAligned && newLastSector - newFirstSector + 1 != partition().length())
|
||||
{
|
||||
qDebug() << "length changes while trying to move partition " << partition().deviceNode() << ". new first: " << newFirstSector << ", new last: " << newLastSector << ", old length: " << partition().length() << ", new length: " << newLastSector - newFirstSector + 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkConstraints(newFirstSector, newLastSector))
|
||||
{
|
||||
qDebug() << "constraints not satisfied while trying to move partition " << partition().deviceNode() << ". new first: " << newFirstSector << ", new last: " << newLastSector;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (align() && !PartitionAlignment::isAligned(device(), partition(), newFirstSector, newLastSector, true))
|
||||
{
|
||||
qDebug() << "partition " << partition().deviceNode() << " not aligned but supposed to be. new first: " << newFirstSector << " delta: " << PartitionAlignment::firstDelta(device(), partition(), newFirstSector) << ", new last: " << newLastSector << ", delta: " << PartitionAlignment::lastDelta(device(), partition(), newLastSector);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (partition().children().size() > 0 &&
|
||||
(!checkAlignment(*partition().children().first(), partition().firstSector() - newFirstSector) ||
|
||||
!checkAlignment(*partition().children().last(), partition().lastSector() - newLastSector)))
|
||||
{
|
||||
qDebug() << "cannot align children while trying to move partition " << partition().deviceNode();
|
||||
return false;
|
||||
}
|
||||
|
||||
partition().setFirstSector(newFirstSector);
|
||||
partition().fileSystem().setFirstSector(newFirstSector);
|
||||
|
||||
partition().setLastSector(newLastSector);
|
||||
partition().fileSystem().setLastSector(newLastSector);
|
||||
|
||||
updatePositions();
|
||||
|
||||
emit firstSectorChanged(partition().firstSector());
|
||||
emit lastSectorChanged(partition().lastSector());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PartResizerWidget::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
int x = event->pos().x() - m_Hotspot;
|
||||
|
||||
if (draggedWidget() == &leftHandle())
|
||||
{
|
||||
const qint64 newFirstSector = qMax(minimumFirstSector() + x * sectorsPerPixel(), 0LL);
|
||||
updateFirstSector(newFirstSector);
|
||||
}
|
||||
else if (draggedWidget() == &rightHandle())
|
||||
{
|
||||
const qint64 newLastSector = qMin(minimumFirstSector() + (x - rightHandle().width()) * sectorsPerPixel(), maximumLastSector());
|
||||
updateLastSector(newLastSector);
|
||||
}
|
||||
else if (draggedWidget() == &partWidget() && moveAllowed())
|
||||
{
|
||||
const qint64 newFirstSector = qMax(minimumFirstSector() + (x - handleWidth()) * sectorsPerPixel(), 0LL);
|
||||
movePartition(newFirstSector);
|
||||
}
|
||||
}
|
||||
|
||||
void PartResizerWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
m_DraggedWidget = NULL;
|
||||
}
|
||||
|
||||
bool PartResizerWidget::updateFirstSector(qint64 newFirstSector)
|
||||
{
|
||||
if (maximumFirstSector(align()) > -1 && newFirstSector > maximumFirstSector(align()))
|
||||
newFirstSector = maximumFirstSector(align());
|
||||
|
||||
if (minimumFirstSector(align()) > 0 && newFirstSector < minimumFirstSector(align()))
|
||||
newFirstSector = minimumFirstSector(align());
|
||||
|
||||
const qint64 newLength = partition().lastSector() - newFirstSector + 1;
|
||||
|
||||
if (newLength < minimumLength())
|
||||
newFirstSector -= minimumLength() - newLength;
|
||||
|
||||
if (newLength > maximumLength())
|
||||
newFirstSector -= newLength - maximumLength();
|
||||
|
||||
if (align())
|
||||
newFirstSector = PartitionAlignment::alignedFirstSector(device(), partition(), newFirstSector, minimumFirstSector(align()), maximumFirstSector(align()), minimumLength(), maximumLength());
|
||||
|
||||
if (newFirstSector != partition().firstSector() && (partition().children().size() == 0 || checkAlignment(*partition().children().first(), partition().firstSector() - newFirstSector)))
|
||||
{
|
||||
const qint64 deltaFirst = partition().firstSector() - newFirstSector;
|
||||
|
||||
partition().setFirstSector(newFirstSector);
|
||||
partition().fileSystem().setFirstSector(newFirstSector);
|
||||
|
||||
resizeLogicals(deltaFirst, 0);
|
||||
|
||||
updatePositions();
|
||||
|
||||
emit firstSectorChanged(partition().firstSector());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PartResizerWidget::checkAlignment(const Partition& child, qint64 delta) const
|
||||
{
|
||||
// TODO: what is this exactly good for? and is it correct in non-cylinder-aligned
|
||||
// situations?
|
||||
if (!partition().roles().has(PartitionRole::Extended))
|
||||
return true;
|
||||
|
||||
if (child.roles().has(PartitionRole::Unallocated))
|
||||
return true;
|
||||
|
||||
return qAbs(delta) >= PartitionAlignment::sectorAlignment(device());
|
||||
}
|
||||
|
||||
void PartResizerWidget::resizeLogicals(qint64 deltaFirst, qint64 deltaLast, bool force)
|
||||
{
|
||||
if (deltaFirst != 0 && partition().children().size() > 0 && partition().children().first()->roles().has(PartitionRole::Unallocated))
|
||||
{
|
||||
qint64 start = partition().children().first()->firstSector() - deltaFirst;
|
||||
qint64 end = partition().children().first()->lastSector() + deltaLast;
|
||||
if (PartitionTable::getUnallocatedRange(device(), partition(), start, end))
|
||||
{
|
||||
partition().children().first()->setFirstSector(start);
|
||||
deltaFirst = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (deltaLast != 0 && partition().children().size() > 0 && partition().children().last()->roles().has(PartitionRole::Unallocated))
|
||||
{
|
||||
qint64 start = partition().children().last()->firstSector() - deltaFirst;
|
||||
qint64 end = partition().children().last()->lastSector() + deltaLast;
|
||||
if (PartitionTable::getUnallocatedRange(device(), partition(), start, end))
|
||||
{
|
||||
partition().children().last()->setLastSector(end);
|
||||
deltaLast = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (force || deltaFirst != 0 || deltaLast != 0)
|
||||
{
|
||||
Q_ASSERT(device().partitionTable());
|
||||
|
||||
device().partitionTable()->removeUnallocated(&partition());
|
||||
|
||||
if (partition().roles().has(PartitionRole::Extended))
|
||||
device().partitionTable()->insertUnallocated(device(), &partition(), partition().firstSector());
|
||||
}
|
||||
|
||||
partWidget().updateChildren();
|
||||
}
|
||||
|
||||
bool PartResizerWidget::updateLastSector(qint64 newLastSector)
|
||||
{
|
||||
if (minimumLastSector(align()) > -1 && newLastSector < minimumLastSector(align()))
|
||||
newLastSector = minimumLastSector(align());
|
||||
|
||||
if (maximumLastSector(align()) > 0 && newLastSector > maximumLastSector(align()))
|
||||
newLastSector = maximumLastSector(align());
|
||||
|
||||
const qint64 newLength = newLastSector - partition().firstSector() + 1;
|
||||
|
||||
if (newLength < minimumLength())
|
||||
newLastSector += minimumLength() - newLength;
|
||||
|
||||
if (newLength > maximumLength())
|
||||
newLastSector -= newLength - maximumLength();
|
||||
|
||||
if (align())
|
||||
newLastSector = PartitionAlignment::alignedLastSector(device(), partition(), newLastSector, minimumLastSector(align()), maximumLastSector(align()), minimumLength(), maximumLength());
|
||||
|
||||
if (newLastSector != partition().lastSector() && (partition().children().size() == 0 || checkAlignment(*partition().children().last(), partition().lastSector() - newLastSector)))
|
||||
{
|
||||
const qint64 deltaLast = newLastSector - partition().lastSector();
|
||||
|
||||
partition().setLastSector(newLastSector);
|
||||
partition().fileSystem().setLastSector(newLastSector);
|
||||
|
||||
resizeLogicals(0, deltaLast);
|
||||
updatePositions();
|
||||
|
||||
emit lastSectorChanged(partition().lastSector());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Sets the minimum sectors the Partition can be long.
|
||||
@note This value can never be less than 0 and never be higher than totalSectors()
|
||||
@param s the new minimum length
|
||||
*/
|
||||
void PartResizerWidget::setMinimumLength(qint64 s)
|
||||
{
|
||||
m_MinimumLength = qBound(0LL, s, totalSectors());
|
||||
}
|
||||
|
||||
/** Sets the maximum sectors the Partition can be long.
|
||||
@note This value can never be less than 0 and never by higher than totalSectors()
|
||||
@param s the new maximum length
|
||||
*/
|
||||
void PartResizerWidget::setMaximumLength(qint64 s)
|
||||
{
|
||||
m_MaximumLength = qBound(0LL, s, totalSectors());
|
||||
}
|
||||
|
||||
/** Sets if moving the Partition is allowed.
|
||||
@param b true if moving is allowed
|
||||
*/
|
||||
void PartResizerWidget::setMoveAllowed(bool b)
|
||||
{
|
||||
m_MoveAllowed = b;
|
||||
|
||||
if (m_PartWidget != NULL)
|
||||
partWidget().setCursor(b ? Qt::SizeAllCursor : Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
qint64 PartResizerWidget::minimumFirstSector(bool aligned) const
|
||||
{
|
||||
if (!aligned || PartitionAlignment::firstDelta(device(), partition(), m_MinimumFirstSector) == 0)
|
||||
return m_MinimumFirstSector;
|
||||
|
||||
return m_MinimumFirstSector - PartitionAlignment::firstDelta(device(), partition(), m_MinimumFirstSector) + PartitionAlignment::sectorAlignment(device());
|
||||
}
|
||||
|
||||
qint64 PartResizerWidget::maximumFirstSector(bool aligned) const
|
||||
{
|
||||
return (m_MaximumFirstSector != -1 && aligned)
|
||||
? m_MaximumFirstSector - PartitionAlignment::firstDelta(device(), partition(), m_MaximumFirstSector)
|
||||
: m_MaximumFirstSector;
|
||||
}
|
||||
|
||||
qint64 PartResizerWidget::minimumLastSector(bool aligned) const
|
||||
{
|
||||
if (!aligned || PartitionAlignment::lastDelta(device(), partition(), m_MinimumLastSector) == 1)
|
||||
return m_MinimumLastSector;
|
||||
|
||||
return m_MinimumLastSector - PartitionAlignment::lastDelta(device(), partition(), m_MinimumLastSector) + 1 + PartitionAlignment::sectorAlignment(device());
|
||||
}
|
||||
|
||||
qint64 PartResizerWidget::maximumLastSector(bool aligned) const
|
||||
{
|
||||
return (m_MaximumLastSector != 0 && aligned)
|
||||
? m_MaximumLastSector - PartitionAlignment::lastDelta(device(), partition(), m_MaximumLastSector)
|
||||
: m_MaximumLastSector;
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008, 2010 by Volker Lanz <vl@fidra.de> *
|
||||
* *
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(PARTRESIZERWIDGET__H)
|
||||
|
||||
#define PARTRESIZERWIDGET__H
|
||||
|
||||
#include "../util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
|
||||
class Partition;
|
||||
class PartWidget;
|
||||
class Device;
|
||||
|
||||
class NewDialog;
|
||||
|
||||
class QPaintEvent;
|
||||
class QResizeEvent;
|
||||
class QMouseEvent;
|
||||
|
||||
/** Widget that allows the user to resize a Partition.
|
||||
@author Volker Lanz <vl@fidra.de>
|
||||
*/
|
||||
class LIBKPMCORE_EXPORT PartResizerWidget : public QWidget
|
||||
{
|
||||
friend class NewDialog;
|
||||
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(PartResizerWidget)
|
||||
|
||||
public:
|
||||
PartResizerWidget(QWidget* parent);
|
||||
|
||||
public:
|
||||
void init(Device& d, Partition& p, qint64 minFirst, qint64 maxLast, bool read_only = false, bool move_allowed = true);
|
||||
|
||||
qint64 totalSectors() const { return maximumLastSector() - minimumFirstSector() + 1; } /**< @return total sectors (free + Partition's length) */
|
||||
|
||||
qint64 minimumFirstSector(bool aligned = false) const; /**< @return the lowest allowed first sector */
|
||||
void setMinimumFirstSector(qint64 s) { m_MinimumFirstSector = s; } /**< @param s the new lowest allowed first sector */
|
||||
|
||||
qint64 maximumFirstSector(bool aligned = false) const; /**< @return the highest allowed first sector */
|
||||
void setMaximumFirstSector(qint64 s) { m_MaximumFirstSector = s; } /**< @param s the new highest allowed first sector */
|
||||
|
||||
qint64 minimumLastSector(bool aligned = false) const; /**< @return the lowest allowed last sector */
|
||||
void setMinimumLastSector(qint64 s) { m_MinimumLastSector = s; } /**< @param s the new lowest allowed last sector */
|
||||
|
||||
qint64 maximumLastSector(bool aligned = false) const; /**< @return the highest allowed last sector */
|
||||
void setMaximumLastSector(qint64 s) { m_MaximumLastSector = s; } /**< @param s the new highest allowed last sector */
|
||||
|
||||
void setMinimumLength(qint64 s);
|
||||
qint64 minimumLength() const { return m_MinimumLength; } /**< @return minimum length for Partition */
|
||||
|
||||
void setMaximumLength(qint64 s);
|
||||
qint64 maximumLength() const { return m_MaximumLength; } /**< @return maximum length for the Partition */
|
||||
|
||||
void setMoveAllowed(bool b);
|
||||
bool moveAllowed() const { return m_MoveAllowed; } /**< @return true if moving the Partition is allowed */
|
||||
|
||||
bool readOnly() const { return m_ReadOnly; } /**< @return true if the widget is read only */
|
||||
void setReadOnly(bool b) { m_ReadOnly = b; } /**< @param b the new value for read only */
|
||||
|
||||
bool align() const { return m_Align; } /**< @return true if the Partition is to be aligned */
|
||||
void setAlign(bool b) { m_Align = b; } /**< @param b the new value for aligning the Partition */
|
||||
|
||||
qint32 handleWidth() const; /**< @return the handle width in pixels */
|
||||
static qint32 handleHeight() { return m_HandleHeight; } /**< @return the handle height in pixels */
|
||||
|
||||
Q_SIGNALS:
|
||||
void firstSectorChanged(qint64);
|
||||
void lastSectorChanged(qint64);
|
||||
|
||||
public Q_SLOTS:
|
||||
bool updateFirstSector(qint64 newFirstSector);
|
||||
bool updateLastSector(qint64 newLastSector);
|
||||
bool movePartition(qint64 newFirstSector);
|
||||
|
||||
protected:
|
||||
Partition& partition() { Q_ASSERT(m_Partition); return *m_Partition; }
|
||||
const Partition& partition() const { Q_ASSERT(m_Partition); return *m_Partition; }
|
||||
void setPartition(Partition& p) { m_Partition = &p; }
|
||||
|
||||
Device& device() { Q_ASSERT(m_Device); return *m_Device; }
|
||||
const Device& device() const { Q_ASSERT(m_Device); return *m_Device; }
|
||||
void setDevice(Device& d) { m_Device = &d; }
|
||||
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
||||
PartWidget& partWidget() { Q_ASSERT(m_PartWidget); return *m_PartWidget; }
|
||||
const PartWidget& partWidget() const { Q_ASSERT(m_PartWidget); return *m_PartWidget; }
|
||||
|
||||
void updatePositions();
|
||||
|
||||
int partWidgetStart() const;
|
||||
int partWidgetWidth() const;
|
||||
|
||||
QLabel& leftHandle() { return m_LeftHandle; }
|
||||
QLabel& rightHandle() { return m_RightHandle; }
|
||||
|
||||
qint64 sectorsPerPixel() const;
|
||||
|
||||
void set(qint64 newCap, qint64 newFreeBefore, qint64 newFreeAfter);
|
||||
|
||||
void resizeLogicals(qint64 deltaFirst, qint64 deltaLast, bool force = false);
|
||||
|
||||
bool checkAlignment(const Partition& child, qint64 delta) const;
|
||||
|
||||
QWidget* draggedWidget() { return m_DraggedWidget; }
|
||||
const QWidget* draggedWidget() const { return m_DraggedWidget; }
|
||||
|
||||
bool checkConstraints(qint64 first, qint64 last) const;
|
||||
|
||||
private:
|
||||
Device* m_Device;
|
||||
Partition* m_Partition;
|
||||
PartWidget* m_PartWidget;
|
||||
|
||||
qint64 m_MinimumFirstSector;
|
||||
qint64 m_MaximumFirstSector;
|
||||
qint64 m_MinimumLastSector;
|
||||
qint64 m_MaximumLastSector;
|
||||
qint64 m_MinimumLength;
|
||||
qint64 m_MaximumLength;
|
||||
|
||||
QLabel m_LeftHandle;
|
||||
QLabel m_RightHandle;
|
||||
|
||||
QWidget* m_DraggedWidget;
|
||||
int m_Hotspot;
|
||||
|
||||
bool m_MoveAllowed;
|
||||
bool m_ReadOnly;
|
||||
bool m_Align;
|
||||
|
||||
static const qint32 m_HandleHeight;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008, 2010 by Volker Lanz <vl@fidra.de> *
|
||||
* *
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "gui/partwidget.h"
|
||||
|
||||
#include "core/partition.h"
|
||||
#include "fs/filesystem.h"
|
||||
#include "util/capacity.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionButton>
|
||||
#include <QApplication>
|
||||
#include <QFontDatabase>
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/** Creates a new PartWidget
|
||||
@param parent pointer to the parent widget
|
||||
@param p pointer to the Partition this widget will show. must not be NULL.
|
||||
*/
|
||||
PartWidget::PartWidget(QWidget* parent, const Partition* p) :
|
||||
PartWidgetBase(parent),
|
||||
m_Partition(NULL),
|
||||
m_Active(false)
|
||||
{
|
||||
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
|
||||
init(p);
|
||||
}
|
||||
|
||||
void PartWidget::init(const Partition* p)
|
||||
{
|
||||
m_Partition = p;
|
||||
|
||||
if (partition())
|
||||
setToolTip(partition()->deviceNode() + QStringLiteral("\n") + partition()->fileSystem().name() + QStringLiteral(" ") + QString(Capacity::formatByteSize(partition()->capacity())));
|
||||
else
|
||||
setToolTip(QString());
|
||||
|
||||
updateChildren();
|
||||
}
|
||||
|
||||
/** Updates the widget's children */
|
||||
void PartWidget::updateChildren()
|
||||
{
|
||||
if (partition())
|
||||
{
|
||||
foreach (QWidget* w, childWidgets())
|
||||
{
|
||||
w->setVisible(false);
|
||||
w->deleteLater();
|
||||
w->setParent(NULL);
|
||||
}
|
||||
|
||||
foreach(const Partition* child, partition()->children())
|
||||
{
|
||||
QWidget* w = new PartWidget(this, child);
|
||||
w->setVisible(true);
|
||||
}
|
||||
|
||||
positionChildren(this, partition()->children(), childWidgets());
|
||||
}
|
||||
}
|
||||
|
||||
void PartWidget::resizeEvent(QResizeEvent*)
|
||||
{
|
||||
if (partition())
|
||||
positionChildren(this, partition()->children(), childWidgets());
|
||||
}
|
||||
|
||||
QColor PartWidget::activeColor(const QColor& col) const
|
||||
{
|
||||
return isActive() ? col.darker(190) : col;
|
||||
}
|
||||
|
||||
void PartWidget::paintEvent(QPaintEvent*)
|
||||
{
|
||||
if (partition() == NULL)
|
||||
return;
|
||||
|
||||
const int usedPercentage = partition()->used() * 100 / partition()->capacity();
|
||||
const int w = width() * usedPercentage / 100;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHints(QPainter::Antialiasing);
|
||||
|
||||
if (partition()->roles().has(PartitionRole::Extended))
|
||||
{
|
||||
drawGradient(&painter, activeColor(Config::fileSystemColorCode(partition()->fileSystem().type())), QRect(0, 0, width(), height()));
|
||||
return;
|
||||
}
|
||||
|
||||
const QColor base = activeColor(Config::fileSystemColorCode(partition()->fileSystem().type()));
|
||||
|
||||
if (!partition()->roles().has(PartitionRole::Unallocated))
|
||||
{
|
||||
const QColor dark = base.darker(105);
|
||||
const QColor light = base.lighter(120);
|
||||
|
||||
// draw free space background
|
||||
drawGradient(&painter, light, QRect(0, 0, width(), height()), isActive());
|
||||
|
||||
// draw used space in front of that
|
||||
drawGradient(&painter, dark, QRect(0, 0, w, height() - 1));
|
||||
}
|
||||
else
|
||||
drawGradient(&painter, base, QRect(0, 0, width(), height()), isActive());
|
||||
|
||||
// draw name and size
|
||||
QString text = partition()->deviceNode().remove(QStringLiteral("/dev/")) + QStringLiteral("\n") + QString(Capacity::formatByteSize(partition()->capacity()));
|
||||
|
||||
const QRect textRect(0, 0, width() - 1, height() - 1);
|
||||
const QRect boundingRect = painter.boundingRect(textRect, Qt::AlignVCenter | Qt::AlignHCenter, text);
|
||||
if (boundingRect.x() > PartWidgetBase::borderWidth() && boundingRect.y() > PartWidgetBase::borderHeight())
|
||||
{
|
||||
if (isActive())
|
||||
painter.setPen(QColor(255, 255, 255));
|
||||
painter.drawText(textRect, Qt::AlignVCenter | Qt::AlignHCenter, text);
|
||||
}
|
||||
}
|
||||
|
||||
void PartWidget::drawGradient(QPainter* painter, const QColor& color, const QRect& rect, bool active) const
|
||||
{
|
||||
if (rect.width() < 8)
|
||||
return;
|
||||
|
||||
QStyleOptionButton option;
|
||||
option.initFrom(this);
|
||||
option.rect = rect;
|
||||
option.palette.setColor(QPalette::Button, color);
|
||||
option.palette.setColor(QPalette::Window, color);
|
||||
option.state |= QStyle::State_Raised;
|
||||
if (!active)
|
||||
option.state &= ~QStyle::State_MouseOver;
|
||||
else
|
||||
option.state |= QStyle::State_MouseOver;
|
||||
|
||||
style()->drawControl(QStyle::CE_PushButtonBevel, &option, painter, this);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008, 2010 by Volker Lanz <vl@fidra.de> *
|
||||
* *
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(PARTWIDGET__H)
|
||||
|
||||
#define PARTWIDGET__H
|
||||
|
||||
#include "../util/libpartitionmanagerexport.h"
|
||||
|
||||
#include "partwidgetbase.h"
|
||||
|
||||
class Partition;
|
||||
|
||||
class QPaintEvent;
|
||||
class QResizeEvent;
|
||||
|
||||
/** Widget that represents a Partition.
|
||||
|
||||
Represents a single Partition (possibly with its children, in case of an extended Partition) in the GUI.
|
||||
|
||||
@author Volker Lanz <vl@fidra.de>
|
||||
*/
|
||||
class LIBKPMCORE_EXPORT PartWidget : public PartWidgetBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PartWidget(QWidget* parent, const Partition* p = NULL);
|
||||
|
||||
public:
|
||||
void init(const Partition* p);
|
||||
void setActive(bool b) { m_Active = b; }
|
||||
bool isActive() const { return m_Active; } /**< @return true if this is the currently active widget */
|
||||
void updateChildren();
|
||||
|
||||
const Partition* partition() const { return m_Partition; } /**< @return the widget's Partition */
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
|
||||
QColor activeColor(const QColor& col) const;
|
||||
|
||||
void drawGradient(QPainter* painter, const QColor& color, const QRect& rect, bool active = false) const;
|
||||
|
||||
private:
|
||||
const Partition* m_Partition;
|
||||
bool m_Active;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
|
||||
* *
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "gui/partwidgetbase.h"
|
||||
#include "gui/partwidget.h"
|
||||
|
||||
#include "core/partition.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
const qint32 PartWidgetBase::m_Spacing = 2;
|
||||
const qint32 PartWidgetBase::m_BorderWidth = 3;
|
||||
const qint32 PartWidgetBase::m_BorderHeight = 3;
|
||||
const qint32 PartWidgetBase::m_MinWidth = 30;
|
||||
|
||||
template<typename T>
|
||||
T sum(const QList<T>& list)
|
||||
{
|
||||
T rval = 0;
|
||||
foreach(const T& val, list)
|
||||
rval += val;
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool distributeLostPixels(QList<qint32>& childrenWidth, qint32 lostPixels)
|
||||
{
|
||||
if (lostPixels == 0 || childrenWidth.size() == 0)
|
||||
return false;
|
||||
|
||||
while (lostPixels > 0)
|
||||
for (qint32 i = 0; i < childrenWidth.size() && lostPixels > 0; i++)
|
||||
{
|
||||
childrenWidth[i]++;
|
||||
lostPixels--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool levelChildrenWidths(QList<qint32>& childrenWidth, const QList<qint32>& minChildrenWidth, const qint32 destWidgetWidth)
|
||||
{
|
||||
if (childrenWidth.size() == 0)
|
||||
return false;
|
||||
|
||||
distributeLostPixels(childrenWidth, destWidgetWidth - sum(childrenWidth));
|
||||
|
||||
// if we find out a partition is too narrow, adjust its screen
|
||||
// width to its minimum width and increase adjust by how much we had to increase the
|
||||
// screen width. thus, in the end, we have the number of pixels we need
|
||||
// to find somewhere else in adjust.
|
||||
qint32 adjust = 0;
|
||||
for (qint32 i = 0; i < childrenWidth.size(); i++)
|
||||
if (childrenWidth[i] < minChildrenWidth[i])
|
||||
{
|
||||
adjust += minChildrenWidth[i] - childrenWidth[i];
|
||||
childrenWidth[i] = minChildrenWidth[i];
|
||||
}
|
||||
|
||||
// find out how many partitions are wide enough to have their width reduced; we'd love to
|
||||
// check for w > minWidth - (pixels_to_reduce_by), but that last value _depends_ on the
|
||||
// number we're trying to find here...
|
||||
qint32 numReducable = 0;
|
||||
for (qint32 i = 0; i < childrenWidth.size(); i++)
|
||||
if (childrenWidth[i] > minChildrenWidth[i])
|
||||
numReducable++;
|
||||
|
||||
// no need to do anything... or nothing can be done because all are too narrow
|
||||
if (adjust == 0 || numReducable == 0)
|
||||
return false;
|
||||
|
||||
// if we have adjusted one or more partitions (and not ALL of them, because in that
|
||||
// case, nothing will help us), go through the partitions again and reduce the
|
||||
// on screen widths of those big enough anyway
|
||||
const qint32 reduce = ceil(1.0 * adjust / numReducable);
|
||||
for (qint32 i = 0; i < childrenWidth.size(); i++)
|
||||
if (childrenWidth[i] > minChildrenWidth[i])
|
||||
childrenWidth[i] -= reduce;
|
||||
|
||||
// distribute pixels lost due to rounding errors
|
||||
distributeLostPixels(childrenWidth, destWidgetWidth - sum(childrenWidth));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PartWidgetBase::positionChildren(const QWidget* destWidget, const PartitionNode::Partitions& partitions, QList<PartWidget*> widgets) const
|
||||
{
|
||||
if (partitions.size() == 0)
|
||||
return;
|
||||
|
||||
QList<qint32> childrenWidth;
|
||||
QList<qint32> minChildrenWidth;
|
||||
const qint32 destWidgetWidth = destWidget->width() - 2 * borderWidth() - (partitions.size() - 1) * spacing();
|
||||
|
||||
if (destWidgetWidth < 0)
|
||||
return;
|
||||
|
||||
qint64 totalLength = 0;
|
||||
foreach (const Partition* p, partitions)
|
||||
totalLength += p->length();
|
||||
|
||||
// calculate unleveled width for each child and store it
|
||||
for (int i = 0; i < partitions.size(); i++)
|
||||
{
|
||||
childrenWidth.append(partitions[i]->length() * destWidgetWidth / totalLength);
|
||||
|
||||
// Calculate the minimum width for the widget. This is easy for primary and logical partitions: they
|
||||
// just have a fixed min width (configured in m_MinWidth). But for extended partitions things
|
||||
// are not quite as simple. We need to calc the sum of the min widths for each child, taking
|
||||
// spacing and borders into account, and add our own min width.
|
||||
qint32 min = (minWidth() + 2 * borderWidth() + spacing()) * partitions[i]->children().size() - spacing() + 2 * borderWidth();
|
||||
|
||||
// if it's too small, this partition is a primary or logical so just use the configured value
|
||||
if (min < minWidth())
|
||||
min = minWidth();
|
||||
minChildrenWidth.append(min);
|
||||
}
|
||||
|
||||
// now go level the widths as long as required
|
||||
while (levelChildrenWidths(childrenWidth, minChildrenWidth, destWidgetWidth))
|
||||
;
|
||||
|
||||
// move the children to their positions and resize them
|
||||
for (int i = 0, x = borderWidth(); i < widgets.size(); i++)
|
||||
{
|
||||
widgets[i]->setMinimumWidth(minChildrenWidth[i]);
|
||||
widgets[i]->move(x, borderHeight());
|
||||
widgets[i]->resize(childrenWidth[i], destWidget->height() - 2 * borderHeight());
|
||||
x += childrenWidth[i] + spacing();
|
||||
}
|
||||
}
|
||||
|
||||
QList<PartWidget*> PartWidgetBase::childWidgets()
|
||||
{
|
||||
QList<PartWidget*> rval;
|
||||
|
||||
foreach(QObject* o, children())
|
||||
if (PartWidget* w = qobject_cast<PartWidget*>(o))
|
||||
rval.append(w);
|
||||
|
||||
return rval;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
|
||||
* *
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(PARTWIDGETBASE__H)
|
||||
|
||||
#define PARTWIDGETBASE__H
|
||||
|
||||
#include "../util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <kpmcore/core/partitionnode.h>
|
||||
|
||||
#include <QList>
|
||||
#include <QWidget>
|
||||
|
||||
class Partition;
|
||||
class PartWidget;
|
||||
class QWidget;
|
||||
|
||||
/** Base class for all widgets that need to position Partitions.
|
||||
@author Volker Lanz <vl@fidra.de>
|
||||
*/
|
||||
class LIBKPMCORE_EXPORT PartWidgetBase : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(PartWidgetBase)
|
||||
|
||||
protected:
|
||||
PartWidgetBase(QWidget* parent) : QWidget(parent) {}
|
||||
virtual ~PartWidgetBase() {}
|
||||
|
||||
public:
|
||||
virtual qint32 borderWidth() const { return m_BorderWidth; } /**< @return border width */
|
||||
virtual qint32 borderHeight() const { return m_BorderHeight; } /**< @return border height */
|
||||
static qint32 spacing() { return m_Spacing; } /**< @return spacing between Partitions */
|
||||
static qint32 minWidth() { return m_MinWidth; } /**< @return minimum width for a Partition widget */
|
||||
|
||||
virtual QList<PartWidget*> childWidgets();
|
||||
|
||||
protected:
|
||||
virtual void positionChildren(const QWidget* destWidget, const PartitionNode::Partitions& partitions, QList<PartWidget*> widgets) const;
|
||||
|
||||
private:
|
||||
static const qint32 m_Spacing;
|
||||
static const qint32 m_BorderWidth;
|
||||
static const qint32 m_BorderHeight;
|
||||
static const qint32 m_MinWidth;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue