X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/2c582a7bc6eb13da9acb7ab92e04a26bba73cf7e..ac73af7bedeebe2afa451249e8a6500651a6ec00:/src/dolphindetailsview.cpp diff --git a/src/dolphindetailsview.cpp b/src/dolphindetailsview.cpp index 876f9852c..4fdb76e1a 100644 --- a/src/dolphindetailsview.cpp +++ b/src/dolphindetailsview.cpp @@ -24,6 +24,7 @@ #include "dolphincontroller.h" #include "dolphinsettings.h" #include "dolphinsortfilterproxymodel.h" +#include "draganddrophelper.h" #include "viewproperties.h" #include "dolphin_detailsmodesettings.h" @@ -43,7 +44,8 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* controller) : QTreeView(parent), m_controller(controller), - m_clearAdditionalInfo(false), + m_font(), + m_decorationSize(), m_dragging(false), m_showElasticBand(false), m_elasticBandOrigin(), @@ -59,6 +61,7 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr setDragDropMode(QAbstractItemView::DragDrop); setDropIndicatorShown(false); setAlternatingRowColors(true); + setItemsExpandable(false); setMouseTracking(true); viewport()->setAttribute(Qt::WA_Hover); @@ -105,13 +108,7 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr const DetailsModeSettings* settings = DolphinSettings::instance().detailsModeSettings(); Q_ASSERT(settings != 0); - m_viewOptions = QTreeView::viewOptions(); - - QFont font(settings->fontFamily(), settings->fontSize()); - font.setItalic(settings->italicFont()); - font.setBold(settings->boldFont()); - m_viewOptions.font = font; - m_viewOptions.showDecorationSelected = true; + m_font = QFont(settings->fontFamily(), settings->fontSize()); // TODO: Remove this check when 4.3.2 is released and KDE requires it... this // check avoids a division by zero happening on versions before 4.3.1. @@ -134,13 +131,8 @@ DolphinDetailsView::~DolphinDetailsView() bool DolphinDetailsView::event(QEvent* event) { if (event->type() == QEvent::Polish) { - // Assure that by respecting the available width that: - // - the 'Name' column is stretched as large as possible - // - the remaining columns are as small as possible QHeaderView* headerView = header(); - headerView->setStretchLastSection(false); - headerView->setResizeMode(QHeaderView::ResizeToContents); - headerView->setResizeMode(0, QHeaderView::Stretch); + headerView->setResizeMode(QHeaderView::Interactive); headerView->setMovable(false); updateColumnVisibility(); @@ -166,7 +158,11 @@ bool DolphinDetailsView::event(QEvent* event) QStyleOptionViewItem DolphinDetailsView::viewOptions() const { - return m_viewOptions; + QStyleOptionViewItem viewOptions = QTreeView::viewOptions(); + viewOptions.font = m_font; + viewOptions.showDecorationSelected = true; + viewOptions.decorationSize = m_decorationSize; + return viewOptions; } void DolphinDetailsView::contextMenuEvent(QContextMenuEvent* event) @@ -202,9 +198,27 @@ void DolphinDetailsView::mousePressEvent(QMouseEvent* event) void DolphinDetailsView::mouseMoveEvent(QMouseEvent* event) { - QTreeView::mouseMoveEvent(event); if (m_showElasticBand) { + const QPoint mousePos = event->pos(); + const QModelIndex index = indexAt(mousePos); + if (!index.isValid()) { + // the destination of the selection rectangle is above the viewport. In this + // case QTreeView does no selection at all, which is not the wanted behavior + // in Dolphin -> select all items within the elastic band rectangle + clearSelection(); + + const int nameColumnWidth = header()->sectionSize(DolphinModel::Name); + QRect selRect = QRect(m_elasticBandOrigin, m_elasticBandDestination).normalized(); + const QRect nameColumnsRect(0, 0, nameColumnWidth, viewport()->height()); + selRect = nameColumnsRect.intersected(selRect); + + setSelection(selRect, QItemSelectionModel::Select); + } + + QTreeView::mouseMoveEvent(event); updateElasticBand(); + } else { + QTreeView::mouseMoveEvent(event); } } @@ -217,6 +231,11 @@ void DolphinDetailsView::mouseReleaseEvent(QMouseEvent* event) } } +void DolphinDetailsView::startDrag(Qt::DropActions supportedActions) +{ + DragAndDropHelper::startDrag(this, supportedActions); +} + void DolphinDetailsView::dragEnterEvent(QDragEnterEvent* event) { if (event->mimeData()->hasUrls()) { @@ -250,13 +269,19 @@ void DolphinDetailsView::dragMoveEvent(QDragMoveEvent* event) m_dragging = false; } else { m_dragging = true; - if (itemForIndex(index).isDir()) { + const KFileItem item = itemForIndex(index); + if (!item.isNull() && item.isDir()) { m_dropRect = visualRect(index); } else { m_dropRect.setSize(QSize()); // set as invalid } setDirtyRegion(m_dropRect); } + + if (event->mimeData()->hasUrls()) { + // accept url drops, independently from the destination item + event->acceptProposedAction(); + } } void DolphinDetailsView::dropEvent(QDropEvent* event) @@ -298,8 +323,8 @@ void DolphinDetailsView::paintEvent(QPaintEvent* event) // TODO: remove this code when the issue #160611 is solved in Qt 4.4 if (m_dragging) { - const QBrush& brush = m_viewOptions.palette.brush(QPalette::Normal, QPalette::Highlight); - DolphinController::drawHoverIndication(viewport(), m_dropRect, brush); + const QBrush& brush = viewOptions().palette.brush(QPalette::Normal, QPalette::Highlight); + DragAndDropHelper::drawHoverIndication(this, m_dropRect, brush); } } @@ -321,47 +346,14 @@ void DolphinDetailsView::resizeEvent(QResizeEvent* event) { QTreeView::resizeEvent(event); - // assure that the width of the name-column does not get too small - const int minWidth = 120; - QHeaderView* headerView = header(); - bool useFixedWidth = (headerView->sectionSize(KDirModel::Name) <= minWidth) - && (headerView->resizeMode(0) != QHeaderView::Fixed); - if (useFixedWidth) { - // the current width of the name-column is too small, hence - // use a fixed size - headerView->setResizeMode(QHeaderView::Fixed); - headerView->setResizeMode(0, QHeaderView::Fixed); - headerView->resizeSection(KDirModel::Name, minWidth); - } else if (headerView->resizeMode(0) != QHeaderView::Stretch) { - // check whether there is enough available viewport width - // to automatically resize the columns - const int availableWidth = viewport()->width(); - - int headerWidth = 0; - const int count = headerView->count(); - for (int i = 0; i < count; ++i) { - headerWidth += headerView->sectionSize(i); - } - - if (headerWidth < availableWidth) { - headerView->setResizeMode(QHeaderView::ResizeToContents); - headerView->setResizeMode(0, QHeaderView::Stretch); - } - } -} - -void DolphinDetailsView::closeEvent(QCloseEvent* event) -{ - if (m_clearAdditionalInfo) { - disconnect(m_controller->dolphinView(), SIGNAL(additionalInfoChanged(const KFileItemDelegate::InformationList&)), - this, SLOT(updateColumnVisibility())); - - KFileItemDelegate::InformationList info; - info.append(KFileItemDelegate::NoInformation); - m_controller->indicateAdditionalInfoChange(info); - m_clearAdditionalInfo = false; + // TODO: There seems to be no easy way to find out whether the resize event + // has been triggered because of resizing the window or by adjusting the column-width + // by a left mouse-click (the columns should only be resized automatically when the window + // size is adjusted). The following workaround works well, but it should be + // considered solving this in a more transparent way. + if (!(QApplication::mouseButtons() & Qt::LeftButton)) { + resizeColumns(); } - QTreeView::closeEvent(event); } void DolphinDetailsView::setSortIndicatorSection(DolphinView::Sorting sorting) @@ -400,11 +392,12 @@ void DolphinDetailsView::slotEntered(const QModelIndex& index) void DolphinDetailsView::updateElasticBand() { - Q_ASSERT(m_showElasticBand); - QRect dirtyRegion(elasticBandRect()); - m_elasticBandDestination = viewport()->mapFromGlobal(QCursor::pos()); - dirtyRegion = dirtyRegion.united(elasticBandRect()); - setDirtyRegion(dirtyRegion); + if (m_showElasticBand) { + QRect dirtyRegion(elasticBandRect()); + m_elasticBandDestination = viewport()->mapFromGlobal(QCursor::pos()); + dirtyRegion = dirtyRegion.united(elasticBandRect()); + setDirtyRegion(dirtyRegion); + } } QRect DolphinDetailsView::elasticBandRect() const @@ -489,29 +482,16 @@ void DolphinDetailsView::configureColumns(const QPoint& pos) void DolphinDetailsView::updateColumnVisibility() { - KFileItemDelegate::InformationList list = m_controller->dolphinView()->additionalInfo(); - const bool useDefaultColumns = !isVisible() && - (list.isEmpty() || - list.contains(KFileItemDelegate::NoInformation)); - if (useDefaultColumns) { - // Using the details view without any additional information (-> additional column) - // makes no sense and leads to a usability problem as no viewport area is available - // anymore. Hence as fallback provide at least a size and date column. - list.clear(); - list.append(KFileItemDelegate::Size); - list.append(KFileItemDelegate::ModificationTime); - m_controller->indicateAdditionalInfoChange(list); - m_clearAdditionalInfo = true; - } - + const KFileItemDelegate::InformationList list = m_controller->dolphinView()->additionalInfo(); for (int i = DolphinModel::Size; i <= DolphinModel::Type; ++i) { const KFileItemDelegate::Information info = infoForColumn(i); const bool hide = !list.contains(info); if (isColumnHidden(i) != hide) { setColumnHidden(i, hide); - m_clearAdditionalInfo = false; } } + + resizeColumns(); } bool DolphinDetailsView::isZoomInPossible() const @@ -530,7 +510,7 @@ void DolphinDetailsView::updateDecorationSize() { DetailsModeSettings* settings = DolphinSettings::instance().detailsModeSettings(); const int iconSize = settings->iconSize(); - m_viewOptions.decorationSize = QSize(iconSize, iconSize); + m_decorationSize = QSize(iconSize, iconSize); m_controller->setZoomInPossible(isZoomInPossible()); m_controller->setZoomOutPossible(isZoomOutPossible()); @@ -581,4 +561,40 @@ KFileItemDelegate::Information DolphinDetailsView::infoForColumn(int columnIndex return info; } +void DolphinDetailsView::resizeColumns() +{ + // Using the resize mode QHeaderView::ResizeToContents is too slow (it takes + // around 3 seconds for each (!) resize operation when having > 10000 items). + // This gets a problem especially when opening large directories, where several + // resize operations are received for showing the currently available items during + // loading (the application hangs around 20 seconds when loading > 10000 items). + + QHeaderView* headerView = header(); + QFontMetrics fontMetrics(viewport()->font()); + + int columnWidth[KDirModel::ColumnCount]; + columnWidth[KDirModel::Size] = fontMetrics.width("00000 Items"); + columnWidth[KDirModel::ModifiedTime] = fontMetrics.width("0000-00-00 00:00"); + columnWidth[KDirModel::Permissions] = fontMetrics.width("xxxxxxxxxx"); + columnWidth[KDirModel::Owner] = fontMetrics.width("xxxxxxxxxx"); + columnWidth[KDirModel::Group] = fontMetrics.width("xxxxxxxxxx"); + columnWidth[KDirModel::Type] = fontMetrics.width("XXXX Xxxxxxx"); + + int requiredWidth = 0; + for (int i = KDirModel::Size; i <= KDirModel::Type; ++i) { + if (!isColumnHidden(i)) { + columnWidth[i] += 20; // provide a default gap + requiredWidth += columnWidth[i]; + headerView->resizeSection(i, columnWidth[i]); + } + } + + // resize the name column in a way that the whole available width is used + columnWidth[KDirModel::Name] = viewport()->width() - requiredWidth; + if (columnWidth[KDirModel::Name] < 120) { + columnWidth[KDirModel::Name] = 120; + } + headerView->resizeSection(KDirModel::Name, columnWidth[KDirModel::Name]); +} + #include "dolphindetailsview.moc"