From: Peter Penz Date: Sat, 4 Sep 2010 16:59:47 +0000 (+0000) Subject: Use the size-hint provided by the item-delegate to calculate the required width of... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/f9554d6457b1439fb0a139a86aa91a94d525e653 Use the size-hint provided by the item-delegate to calculate the required width of the columns. This assures that columns like "Path" are not clipped. svn path=/trunk/KDE/kdebase/apps/; revision=1171601 --- diff --git a/src/views/dolphindetailsview.cpp b/src/views/dolphindetailsview.cpp index 961bd7872..243debb1b 100644 --- a/src/views/dolphindetailsview.cpp +++ b/src/views/dolphindetailsview.cpp @@ -37,6 +37,7 @@ #include "dolphin_generalsettings.h" #include +#include #include #include @@ -166,6 +167,9 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, m_extensionsFactory = new ViewExtensionsFactory(this, dolphinViewController, viewModeController); m_extensionsFactory->fileItemDelegate()->setMinimizedNameColumn(true); m_extensionsFactory->setAutoFolderExpandingEnabled(settings->expandableFolders()); + + KDirLister *dirLister = qobject_cast(proxyModel->sourceModel())->dirLister(); + connect(dirLister, SIGNAL(completed()), this, SLOT(resizeColumns())); } DolphinDetailsView::~DolphinDetailsView() @@ -519,6 +523,12 @@ void DolphinDetailsView::scrollTo(const QModelIndex & index, ScrollHint hint) } } +void DolphinDetailsView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + removeExpandedIndexes(parent, start, end); + QTreeView::rowsAboutToBeRemoved(parent, start, end); +} + void DolphinDetailsView::setSortIndicatorSection(DolphinView::Sorting sorting) { header()->setSortIndicator(sorting, header()->sortIndicatorOrder()); @@ -678,6 +688,86 @@ void DolphinDetailsView::updateColumnVisibility() this, SLOT(saveColumnPositions())); } +void DolphinDetailsView::resizeColumns() +{ + QHeaderView* headerView = header(); + const int rowCount = model()->rowCount(); + if (rowCount <= 0) { + headerView->resizeSection(KDirModel::Name, viewport()->width()); + return; + } + + // 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). + + QFontMetrics fontMetrics(viewport()->font()); + + // Define the maximum number of rows, where an exact (but expensive) calculation + // of the widths is done. + const int maxRowCount = 200; + + // Calculate the required with for each column and store it in columnWidth[] + int columnWidth[DolphinModel::ExtraColumnCount]; + + const QAbstractProxyModel* proxyModel = qobject_cast(model()); + const KDirModel* dirModel = qobject_cast(proxyModel->sourceModel()); + for (int column = 0; column < DolphinModel::ExtraColumnCount; ++column) { + columnWidth[column] = 0; + if (!isColumnHidden(column)) { + // Calculate the required width for the current column and consider only + // up to maxRowCount columns for performance reasons + const int count = qMin(rowCount, maxRowCount); + const QStyleOptionViewItem option = viewOptions(); + for (int row = 0; row < count; ++row) { + const QModelIndex index = dirModel->index(row, column); + const int width = itemDelegate()->sizeHint(option, index).width(); + if (width > columnWidth[column]) { + columnWidth[column] = width; + } + } + + // Assure that the required width is sufficient for the header too + const int logicalIndex = headerView->logicalIndex(column); + const QString headline = model()->headerData(logicalIndex, Qt::Horizontal).toString(); + const int headlineWidth = fontMetrics.width(headline); + + columnWidth[column] = qMax(columnWidth[column], headlineWidth); + } + } + + // Resize all columns except of the name column + int requiredWidth = 0; + for (int column = KDirModel::Size; column < DolphinModel::ExtraColumnCount; ++column) { + if (!isColumnHidden(column)) { + requiredWidth += columnWidth[column]; + headerView->resizeSection(column, columnWidth[column]); + } + } + + // Resize the name column in a way that the whole available width is used + columnWidth[KDirModel::Name] = viewport()->width() - requiredWidth; + + const int minNameWidth = 300; + if (columnWidth[KDirModel::Name] < minNameWidth) { + columnWidth[KDirModel::Name] = minNameWidth; + + if ((rowCount > 0) && (rowCount < maxRowCount)) { + // Try to decrease the name column width without clipping any text + const int nameWidth = sizeHintForColumn(DolphinModel::Name); + if (nameWidth + requiredWidth <= viewport()->width()) { + columnWidth[KDirModel::Name] = viewport()->width() - requiredWidth; + } else if (nameWidth < minNameWidth) { + columnWidth[KDirModel::Name] = nameWidth; + } + } + } + + headerView->resizeSection(KDirModel::Name, columnWidth[KDirModel::Name]); +} + void DolphinDetailsView::saveColumnPositions() { QList columnPositions; @@ -959,12 +1049,6 @@ void DolphinDetailsView::slotCollapsed(const QModelIndex& index) } } -void DolphinDetailsView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) -{ - removeExpandedIndexes(parent, start, end); - QTreeView::rowsAboutToBeRemoved(parent, start, end); -} - void DolphinDetailsView::removeExpandedIndexes(const QModelIndex& parent, int start, int end) { if (m_expandedUrls.isEmpty()) { @@ -995,73 +1079,6 @@ KFileItemDelegate::Information DolphinDetailsView::infoForColumn(int columnIndex return AdditionalInfoAccessor::instance().keyForColumn(columnIndex); } -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()); - - // Calculate the required with for each column and store it in columnWidth[] - int columnWidth[DolphinModel::ExtraColumnCount]; - const int defaultWidth = fontMetrics.width("xxxxxxxxxx"); - - for (int i = 0; i < DolphinModel::ExtraColumnCount; ++i) { - const int logicalIndex = headerView->logicalIndex(i); - const QString headline = model()->headerData(logicalIndex, Qt::Horizontal).toString(); - const int headlineWidth = fontMetrics.width(headline); - - columnWidth[i] = qMax(defaultWidth, headlineWidth); - } - - const int defaultSizeWidth = fontMetrics.width("00000 Items"); - if (defaultSizeWidth > columnWidth[DolphinModel::Size]) { - columnWidth[DolphinModel::Size] = defaultSizeWidth; - } - - const int defaultTimeWidth = fontMetrics.width("0000-00-00 00:00"); - if (defaultTimeWidth > columnWidth[DolphinModel::ModifiedTime]) { - columnWidth[DolphinModel::ModifiedTime] = defaultTimeWidth; - } - - int requiredWidth = 0; - for (int i = KDirModel::Size; i < DolphinModel::ExtraColumnCount; ++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; - - const int minNameWidth = 300; - if (columnWidth[KDirModel::Name] < minNameWidth) { - columnWidth[KDirModel::Name] = minNameWidth; - - // It might be possible that the name column width can be - // decreased without clipping any text. For performance - // reasons the exact necessary width for full visible names is - // only checked for up to 200 items: - const int rowCount = model()->rowCount(); - if (rowCount > 0 && rowCount < 200) { - const int nameWidth = sizeHintForColumn(DolphinModel::Name); - if (nameWidth + requiredWidth <= viewport()->width()) { - columnWidth[KDirModel::Name] = viewport()->width() - requiredWidth; - } else if (nameWidth < minNameWidth) { - columnWidth[KDirModel::Name] = nameWidth; - } - } - } - - headerView->resizeSection(KDirModel::Name, columnWidth[KDirModel::Name]); -} - bool DolphinDetailsView::isAboveExpandingToggle(const QPoint& pos) const { // QTreeView offers no public API to get the information whether an index has an diff --git a/src/views/dolphindetailsview.h b/src/views/dolphindetailsview.h index 3ac08d337..8b76cbc36 100644 --- a/src/views/dolphindetailsview.h +++ b/src/views/dolphindetailsview.h @@ -88,6 +88,10 @@ protected: virtual void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags command); virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible); + +protected slots: + virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + private slots: /** * Sets the sort indicator section of the header view @@ -147,6 +151,11 @@ private slots: */ void updateColumnVisibility(); + /** + * Resizes all columns in a way to use the whole available width of the view. + */ + void resizeColumns(); + /** * Saves order of the columns as global setting. */ @@ -193,10 +202,6 @@ private slots: void slotExpanded(const QModelIndex& index); void slotCollapsed(const QModelIndex& index); -protected slots: - - virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); - private: /** * Removes the URLs corresponding to the children of \a index in the rows @@ -214,11 +219,6 @@ private: KFileItemDelegate::Information infoForColumn(int columnIndex) const; - /** - * Resizes all columns in a way to use the whole available width of the view. - */ - void resizeColumns(); - /** * Returns true, if \a pos is within the expanding toggle of a tree. */