diff --git a/krusader/Panel/krinterbriefview.cpp b/krusader/Panel/krinterbriefview.cpp index f4d38b87..28c88b9d 100644 --- a/krusader/Panel/krinterbriefview.cpp +++ b/krusader/Panel/krinterbriefview.cpp @@ -1,713 +1,714 @@ /***************************************************************************** * Copyright (C) 2009 Csaba Karai * * * * 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 2 of the License, or * * (at your option) any later version. * * * * This package 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 package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krinterbriefview.h" // QtCore #include #include #include #include // QtGui #include #include #include // QtWidgets #include #include #include #include #include #include #include #include "krviewfactory.h" #include "krviewitemdelegate.h" #include "krviewitem.h" #include "krvfsmodel.h" #include "krmousehandler.h" #include "krcolorcache.h" #include "../VFS/krpermhandler.h" #include "../defaults.h" #include "../GUI/krstyleproxy.h" KrInterBriefView::KrInterBriefView(QWidget *parent, KrViewInstance &instance, KConfig *cfg) : QAbstractItemView(parent), KrInterView(instance, cfg, this), _header(0) { setWidget(this); setModel(_model); setSelectionMode(QAbstractItemView::NoSelection); setSelectionModel(new DummySelectionModel(_model, this)); KConfigGroup grpSvr(_config, "Look&Feel"); _viewFont = grpSvr.readEntry("Filelist Font", _FilelistFont); setStyle(new KrStyleProxy()); setItemDelegate(new KrViewItemDelegate()); setMouseTracking(true); setAcceptDrops(true); setDropIndicatorShown(true); connect(_mouseHandler, SIGNAL(renameCurrentItem()), SLOT(renameCurrentItem())); _model->setExtensionEnabled(false); _model->setAlternatingTable(true); connect(_model, SIGNAL(layoutChanged()), SLOT(updateGeometries())); } KrInterBriefView::~KrInterBriefView() { delete _properties; _properties = 0; delete _operator; _operator = 0; } void KrInterBriefView::doRestoreSettings(KConfigGroup group) { _properties->numberOfColumns = group.readEntry("Number Of Brief Columns", _NumberOfBriefColumns); if (_properties->numberOfColumns < 1) _properties->numberOfColumns = 1; else if (_properties->numberOfColumns > MAX_BRIEF_COLS) _properties->numberOfColumns = MAX_BRIEF_COLS; _numOfColumns = _properties->numberOfColumns; KrInterView::doRestoreSettings(group); updateGeometries(); } void KrInterBriefView::saveSettings(KConfigGroup grp, KrViewProperties::PropertyType properties) { KrInterView::saveSettings(grp, properties); if(properties & KrViewProperties::PropColumns) grp.writeEntry("Number Of Brief Columns", _numOfColumns); } int KrInterBriefView::itemsPerPage() { int height = getItemHeight(); if (height == 0) height ++; int numRows = viewport()->height() / height; return numRows; } void KrInterBriefView::updateView() { } void KrInterBriefView::setup() { _header = new QHeaderView(Qt::Horizontal, this); _header->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); _header->setParent(this); _header->setModel(_model); _header->hideSection(KrViewProperties::Type); _header->hideSection(KrViewProperties::Permissions); _header->hideSection(KrViewProperties::KrPermissions); _header->hideSection(KrViewProperties::Owner); _header->hideSection(KrViewProperties::Group); _header->setStretchLastSection(true); _header->setSectionResizeMode(QHeaderView::Fixed); _header->setSectionsClickable(true); _header->setSortIndicatorShown(true); connect(_header, SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), _model, SLOT(sort(int, Qt::SortOrder))); _header->installEventFilter(this); _numOfColumns = _properties->numberOfColumns; setSortMode(_properties->sortColumn, (_properties->sortOptions & KrViewProperties::Descending)); } void KrInterBriefView::keyPressEvent(QKeyEvent *e) { if (!e || !_model->ready()) return ; // subclass bug if (handleKeyEvent(e)) return; QAbstractItemView::keyPressEvent(e); } bool KrInterBriefView::handleKeyEvent(QKeyEvent *e) { if ((e->key() != Qt::Key_Left && e->key() != Qt::Key_Right) && (KrView::handleKeyEvent(e))) // did the view class handled the event? return true; switch (e->key()) { case Qt::Key_Right : { if (e->modifiers() == Qt::ControlModifier) { // let the panel handle it e->ignore(); break; } KrViewItem *i = getCurrentKrViewItem(); KrViewItem *newCurrent = i; if (!i) break; int num = itemsPerPage() + 1; if (e->modifiers() & Qt::ShiftModifier) i->setSelected(!i->isSelected()); while (i && num > 0) { if (e->modifiers() & Qt::ShiftModifier) i->setSelected(!i->isSelected()); newCurrent = i; i = getNext(i); num--; } if (newCurrent) { setCurrentKrViewItem(newCurrent); makeCurrentVisible(); } if (e->modifiers() & Qt::ShiftModifier) op()->emitSelectionChanged(); return true; } case Qt::Key_Left : { if (e->modifiers() == Qt::ControlModifier) { // let the panel handle it e->ignore(); break; } KrViewItem *i = getCurrentKrViewItem(); KrViewItem *newCurrent = i; if (!i) break; int num = itemsPerPage() + 1; if (e->modifiers() & Qt::ShiftModifier) i->setSelected(!i->isSelected()); while (i && num > 0) { if (e->modifiers() & Qt::ShiftModifier) i->setSelected(!i->isSelected()); newCurrent = i; i = getPrev(i); num--; } if (newCurrent) { setCurrentKrViewItem(newCurrent); makeCurrentVisible(); } if (e->modifiers() & Qt::ShiftModifier) op()->emitSelectionChanged(); return true; } } return false; } void KrInterBriefView::wheelEvent(QWheelEvent *ev) { if (!_mouseHandler->wheelEvent(ev)) QApplication::sendEvent(horizontalScrollBar(), ev); } bool KrInterBriefView::eventFilter(QObject *object, QEvent *event) { if (object == _header) { if (event->type() == QEvent::ContextMenu) { QContextMenuEvent *me = (QContextMenuEvent *)event; showContextMenu(me->globalPos()); return true; } } return false; } void KrInterBriefView::showContextMenu(const QPoint & p) { QMenu popup(this); popup.setTitle(i18n("Columns")); int COL_ID = 14700; for (int i = 1; i <= MAX_BRIEF_COLS; i++) { QAction *act = popup.addAction(QString("%1").arg(i)); act->setData(QVariant(COL_ID + i)); act->setCheckable(true); act->setChecked(properties()->numberOfColumns == i); } QAction * res = popup.exec(p); int result = -1; if (res && res->data().canConvert()) result = res->data().toInt(); if (result > COL_ID && result <= COL_ID + MAX_BRIEF_COLS) { _properties->numberOfColumns = result - COL_ID; _numOfColumns = _properties->numberOfColumns; updateGeometries(); op()->settingsChanged(KrViewProperties::PropColumns); } } QRect KrInterBriefView::visualRect(const QModelIndex&ndx) const { int width = (viewport()->width()) / _numOfColumns; if ((viewport()->width()) % _numOfColumns) width++; int height = getItemHeight(); int numRows = viewport()->height() / height; if (numRows == 0) numRows++; int x = width * (ndx.row() / numRows); int y = height * (ndx.row() % numRows); return mapToViewport(QRect(x, y, width, height)); } void KrInterBriefView::scrollTo(const QModelIndex &ndx, QAbstractItemView::ScrollHint hint) { const QRect rect = visualRect(ndx); if (hint == EnsureVisible && viewport()->rect().contains(rect)) { setDirtyRegion(rect); return; } const QRect area = viewport()->rect(); const bool leftOf = rect.left() < area.left(); const bool rightOf = rect.right() > area.right(); int horizontalValue = horizontalScrollBar()->value(); if (leftOf) horizontalValue -= area.left() - rect.left(); else if (rightOf) horizontalValue += rect.right() - area.right(); horizontalScrollBar()->setValue(horizontalValue); } QModelIndex KrInterBriefView::indexAt(const QPoint& p) const { int x = p.x() + horizontalOffset(); int y = p.y() + verticalOffset(); int itemWidth = (viewport()->width()) / _numOfColumns; if ((viewport()->width()) % _numOfColumns) itemWidth++; int itemHeight = getItemHeight(); int numRows = viewport()->height() / itemHeight; if (numRows == 0) numRows++; int row = y / itemHeight; int col = x / itemWidth; int numColsTotal = _model->rowCount() / numRows; if(_model->rowCount() % numRows) numColsTotal++; if(row < numRows && col < numColsTotal) return _model->index((col * numRows) + row, 0); return QModelIndex(); } QModelIndex KrInterBriefView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers) { if (_model->rowCount() == 0) return QModelIndex(); QModelIndex current = currentIndex(); if (!current.isValid()) return _model->index(0, 0); switch (cursorAction) { case MoveLeft: case MovePageDown: { int newRow = current.row() - itemsPerPage(); if (newRow < 0) newRow = 0; return _model->index(newRow, 0); } case MoveRight: case MovePageUp: { int newRow = current.row() + itemsPerPage(); if (newRow >= _model->rowCount()) newRow = _model->rowCount() - 1; return _model->index(newRow, 0); } case MovePrevious: case MoveUp: { int newRow = current.row() - 1; if (newRow < 0) newRow = 0; return _model->index(newRow, 0); } case MoveNext: case MoveDown: { int newRow = current.row() + 1; if (newRow >= _model->rowCount()) newRow = _model->rowCount() - 1; return _model->index(newRow, 0); } case MoveHome: return _model->index(0, 0); case MoveEnd: return _model->index(_model->rowCount() - 1, 0); } return current; } int KrInterBriefView::horizontalOffset() const { return horizontalScrollBar()->value(); } int KrInterBriefView::verticalOffset() const { return 0; } bool KrInterBriefView::isIndexHidden(const QModelIndex&ndx) const { return ndx.column() != 0; } #if 0 QRegion KrInterBriefView::visualRegionForSelection(const QItemSelection &selection) const { if (selection.isEmpty()) return QRegion(); QRegion selectionRegion; for (int i = 0; i < selection.count(); ++i) { QItemSelectionRange range = selection.at(i); if (!range.isValid()) continue; QModelIndex leftIndex = range.topLeft(); if (!leftIndex.isValid()) continue; const QRect leftRect = visualRect(leftIndex); int top = leftRect.top(); QModelIndex rightIndex = range.bottomRight(); if (!rightIndex.isValid()) continue; const QRect rightRect = visualRect(rightIndex); int bottom = rightRect.bottom(); if (top > bottom) qSwap(top, bottom); int height = bottom - top + 1; QRect combined = leftRect | rightRect; combined.setX(range.left()); selectionRegion += combined; } return selectionRegion; } #endif void KrInterBriefView::paintEvent(QPaintEvent *e) { QStyleOptionViewItem option = viewOptions(); option.widget = this; option.decorationSize = QSize(_fileIconSize, _fileIconSize); option.decorationPosition = QStyleOptionViewItem::Left; QPainter painter(viewport()); QModelIndex curr = currentIndex(); QVector intersectVector; QRect area = e->rect(); area.adjust(horizontalOffset(), verticalOffset(), horizontalOffset(), verticalOffset()); intersectionSet(area, intersectVector); foreach(const QModelIndex &mndx, intersectVector) { option.state = QStyle::State_None; option.rect = visualRect(mndx); painter.save(); - bool focus = curr.isValid() && curr.row() == mndx.row() && hasFocus(); - itemDelegate()->paint(&painter, option, mndx); - if (focus) { + // (always) draw dashed line border around current item row + const bool isCurrent = curr.isValid() && curr.row() == mndx.row(); + if (isCurrent) { QStyleOptionFocusRect o; o.QStyleOption::operator=(option); QPalette::ColorGroup cg = QPalette::Normal; o.backgroundColor = option.palette.color(cg, QPalette::Background); + style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, &painter); } painter.restore(); } } int KrInterBriefView::getItemHeight() const { int textHeight = QFontMetrics(_viewFont).height(); int height = textHeight; int iconSize = 0; if (properties()->displayIcons) iconSize = _fileIconSize; if (iconSize > textHeight) height = iconSize; if (height == 0) height++; return height; } void KrInterBriefView::updateGeometries() { if (_header) { QSize hint = _header->sizeHint(); setViewportMargins(0, hint.height(), 0, 0); QRect vg = viewport()->geometry(); QRect geometryRect(vg.left(), vg.top() - hint.height(), vg.width(), hint.height()); _header->setGeometry(geometryRect); int items = 0; for (int i = 0; i != _header->count(); i++) if (!_header->isSectionHidden(i)) items++; if (items == 0) items++; int sectWidth = viewport()->width() / items; for (int i = 0; i != _header->count(); i++) if (!_header->isSectionHidden(i)) _header->resizeSection(i, sectWidth); QMetaObject::invokeMethod(_header, "updateGeometries"); } if (_model->rowCount() <= 0) horizontalScrollBar()->setRange(0, 0); else { int itemsPerColumn = viewport()->height() / getItemHeight(); if (itemsPerColumn <= 0) itemsPerColumn = 1; int columnWidth = (viewport()->width()) / _numOfColumns; if ((viewport()->width()) % _numOfColumns) columnWidth++; int maxWidth = _model->rowCount() / itemsPerColumn; if (_model->rowCount() % itemsPerColumn) maxWidth++; maxWidth *= columnWidth; if (maxWidth > viewport()->width()) { horizontalScrollBar()->setSingleStep(columnWidth); horizontalScrollBar()->setPageStep(columnWidth * _numOfColumns); horizontalScrollBar()->setRange(0, maxWidth - viewport()->width()); } else { horizontalScrollBar()->setRange(0, 0); } } QAbstractItemView::updateGeometries(); } void KrInterBriefView::setSortMode(KrViewProperties::ColumnType sortColumn, bool descending) { Qt::SortOrder sortDir = descending ? Qt::DescendingOrder : Qt::AscendingOrder; _header->setSortIndicator(sortColumn, sortDir); } int KrInterBriefView::elementWidth(const QModelIndex & index) { QString text = index.data(Qt::DisplayRole).toString(); int textWidth = QFontMetrics(_viewFont).width(text); const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; textWidth += 2 * textMargin; QVariant decor = index.data(Qt::DecorationRole); if (decor.isValid() && decor.type() == QVariant::Pixmap) { QPixmap p = decor.value(); textWidth += p.width() + 2 * textMargin; } return textWidth; } void KrInterBriefView::intersectionSet(const QRect &rect, QVector &ndxList) { int maxNdx = _model->rowCount(); int width = (viewport()->width()) / _numOfColumns; if ((viewport()->width()) % _numOfColumns) width++; int height = getItemHeight(); int items = viewport()->height() / height; if (items == 0) items++; int xmin = -1; int ymin = -1; int xmax = -1; int ymax = -1; xmin = rect.x() / width; ymin = rect.y() / height; xmax = (rect.x() + rect.width()) / width; if ((rect.x() + rect.width()) % width) xmax++; ymax = (rect.y() + rect.height()) / height; if ((rect.y() + rect.height()) % height) ymax++; for (int i = ymin; i < ymax; i++) for (int j = xmin; j < xmax; j++) { int ndx = j * items + i; if (ndx < maxNdx) ndxList.append(_model->index(ndx, 0)); } } QRect KrInterBriefView::itemRect(const vfile *vf) { return visualRect(_model->vfileIndex(vf)); } void KrInterBriefView::copySettingsFrom(KrView *other) { if(other->instance() == instance()) { // the other view is of the same type KrInterBriefView *v = static_cast(other); int column = v->_model->lastSortOrder(); Qt::SortOrder sortDir = v->_model->lastSortDir(); _header->setSortIndicator(column, sortDir); _model->sort(column, sortDir); setFileIconSize(v->fileIconSize()); } } void KrInterBriefView::setFileIconSize(int size) { KrView::setFileIconSize(size); setIconSize(QSize(fileIconSize(), fileIconSize())); updateGeometries(); } void KrInterBriefView::currentChanged(const QModelIndex & current, const QModelIndex & previous) { if (_model->ready()) { KrViewItem * item = getKrViewItem(currentIndex()); op()->emitCurrentChanged(item); } QAbstractItemView::currentChanged(current, previous); } void KrInterBriefView::renameCurrentItem() { QModelIndex cIndex = currentIndex(); QModelIndex nameIndex = _model->index(cIndex.row(), KrViewProperties::Name); edit(nameIndex); updateEditorData(); update(nameIndex); } bool KrInterBriefView::event(QEvent * e) { _mouseHandler->otherEvent(e); return QAbstractItemView::event(e); } void KrInterBriefView::mousePressEvent(QMouseEvent * ev) { if (!_mouseHandler->mousePressEvent(ev)) QAbstractItemView::mousePressEvent(ev); } void KrInterBriefView::mouseReleaseEvent(QMouseEvent * ev) { if (!_mouseHandler->mouseReleaseEvent(ev)) QAbstractItemView::mouseReleaseEvent(ev); } void KrInterBriefView::mouseDoubleClickEvent(QMouseEvent *ev) { if (!_mouseHandler->mouseDoubleClickEvent(ev)) QAbstractItemView::mouseDoubleClickEvent(ev); } void KrInterBriefView::mouseMoveEvent(QMouseEvent * ev) { if (!_mouseHandler->mouseMoveEvent(ev)) QAbstractItemView::mouseMoveEvent(ev); } void KrInterBriefView::dragEnterEvent(QDragEnterEvent *ev) { if (!_mouseHandler->dragEnterEvent(ev)) QAbstractItemView::dragEnterEvent(ev); } void KrInterBriefView::dragMoveEvent(QDragMoveEvent *ev) { QAbstractItemView::dragMoveEvent(ev); _mouseHandler->dragMoveEvent(ev); } void KrInterBriefView::dragLeaveEvent(QDragLeaveEvent *ev) { if (!_mouseHandler->dragLeaveEvent(ev)) QAbstractItemView::dragLeaveEvent(ev); } void KrInterBriefView::dropEvent(QDropEvent *ev) { if (!_mouseHandler->dropEvent(ev)) QAbstractItemView::dropEvent(ev); } bool KrInterBriefView::viewportEvent(QEvent * event) { if (event->type() == QEvent::ToolTip) { QHelpEvent *he = static_cast(event); const QModelIndex index = indexAt(he->pos()); if (index.isValid()) { int width = visualRect(index).width(); int textWidth = elementWidth(index); if (textWidth <= width) { event->accept(); return true; } } } return QAbstractItemView::viewportEvent(event); } QRect KrInterBriefView::mapToViewport(const QRect &rect) const { if (!rect.isValid()) return rect; QRect result = rect; int dx = -horizontalOffset(); int dy = -verticalOffset(); result.adjust(dx, dy, dx, dy); return result; } diff --git a/krusader/Panel/krinterdetailedview.cpp b/krusader/Panel/krinterdetailedview.cpp index 0e07d74a..2704d067 100644 --- a/krusader/Panel/krinterdetailedview.cpp +++ b/krusader/Panel/krinterdetailedview.cpp @@ -1,406 +1,423 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * 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 2 of the License, or * * (at your option) any later version. * * * * This package 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 package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krinterdetailedview.h" // QtCore #include #include // QtWidgets #include #include #include #include #include #include #include #include "krviewfactory.h" #include "krviewitemdelegate.h" #include "krviewitem.h" #include "krvfsmodel.h" #include "../VFS/krpermhandler.h" #include "../defaults.h" #include "../krglobal.h" #include "krmousehandler.h" #include "krcolorcache.h" #include "../GUI/krstyleproxy.h" KrInterDetailedView::KrInterDetailedView(QWidget *parent, KrViewInstance &instance, KConfig *cfg): QTreeView(parent), KrInterView(instance, cfg, this), _autoResizeColumns(true) { connect(_mouseHandler, SIGNAL(renameCurrentItem()), this, SLOT(renameCurrentItem())); setWidget(this); KConfigGroup group(krConfig, "Private"); KConfigGroup grpSvr(_config, "Look&Feel"); _viewFont = grpSvr.readEntry("Filelist Font", _FilelistFont); this->setModel(_model); this->setRootIsDecorated(false); setSelectionModel(new DummySelectionModel(_model, this)); header()->installEventFilter(this); setSelectionMode(QAbstractItemView::NoSelection); setAllColumnsShowFocus(true); setUniformRowHeights(true); KrStyleProxy *krstyle = new KrStyleProxy(); krstyle->setParent(this); setStyle(krstyle); setItemDelegate(new KrViewItemDelegate(this)); setMouseTracking(true); setAcceptDrops(true); setDropIndicatorShown(true); header()->setSectionResizeMode(QHeaderView::Interactive); header()->setStretchLastSection(false); connect(header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(sectionResized(int, int, int))); connect(header(), SIGNAL(sectionMoved(int, int, int)), this, SLOT(sectionMoved(int, int, int))); } KrInterDetailedView::~KrInterDetailedView() { delete _properties; _properties = 0; delete _operator; _operator = 0; } void KrInterDetailedView::currentChanged(const QModelIndex & current, const QModelIndex & previous) { if (_model->ready()) { KrViewItem * item = getKrViewItem(currentIndex()); op()->emitCurrentChanged(item); } QTreeView::currentChanged(current, previous); } void KrInterDetailedView::doRestoreSettings(KConfigGroup grp) { _autoResizeColumns = grp.readEntry("AutoResizeColumns", true); QByteArray savedState = grp.readEntry("Saved State", QByteArray()); if (savedState.isEmpty()) { hideColumn(KrViewProperties::Type); hideColumn(KrViewProperties::Permissions); hideColumn(KrViewProperties::Owner); hideColumn(KrViewProperties::Group); header()->resizeSection(KrViewProperties::Ext, QFontMetrics(_viewFont).width("tar.bz2 ")); header()->resizeSection(KrViewProperties::KrPermissions, QFontMetrics(_viewFont).width("rwx ")); header()->resizeSection(KrViewProperties::Size, QFontMetrics(_viewFont).width("9") * 10); QDateTime tmp(QDate(2099, 12, 29), QTime(23, 59)); QString desc = QLocale().toString(tmp, QLocale::ShortFormat) + " "; header()->resizeSection(KrViewProperties::Modified, QFontMetrics(_viewFont).width(desc)); } else { header()->restoreState(savedState); _model->setExtensionEnabled(!isColumnHidden(KrViewProperties::Ext)); } KrInterView::doRestoreSettings(grp); } void KrInterDetailedView::saveSettings(KConfigGroup grp, KrViewProperties::PropertyType properties) { KrInterView::saveSettings(grp, properties); grp.writeEntry("AutoResizeColumns", _autoResizeColumns); if(properties & KrViewProperties::PropColumns) { QByteArray state = header()->saveState(); grp.writeEntry("Saved State", state); } } int KrInterDetailedView::itemsPerPage() { QRect rect = visualRect(currentIndex()); if (!rect.isValid()) { for (int i = 0; i != _model->rowCount(); i++) { rect = visualRect(_model->index(i, 0)); if (rect.isValid()) break; } } if (!rect.isValid()) return 0; int size = (height() - header()->height()) / rect.height(); if (size < 0) size = 0; return size; } void KrInterDetailedView::updateView() { } void KrInterDetailedView::setup() { setSortMode(_properties->sortColumn, (_properties->sortOptions & KrViewProperties::Descending)); setSortingEnabled(true); } void KrInterDetailedView::keyPressEvent(QKeyEvent *e) { if (!e || !_model->ready()) return ; // subclass bug if (handleKeyEvent(e)) // did the view class handled the event? return; QTreeView::keyPressEvent(e); } void KrInterDetailedView::mousePressEvent(QMouseEvent * ev) { if (!_mouseHandler->mousePressEvent(ev)) QTreeView::mousePressEvent(ev); } void KrInterDetailedView::mouseReleaseEvent(QMouseEvent * ev) { if (!_mouseHandler->mouseReleaseEvent(ev)) QTreeView::mouseReleaseEvent(ev); } void KrInterDetailedView::mouseDoubleClickEvent(QMouseEvent *ev) { if (!_mouseHandler->mouseDoubleClickEvent(ev)) QTreeView::mouseDoubleClickEvent(ev); } void KrInterDetailedView::mouseMoveEvent(QMouseEvent * ev) { if (!_mouseHandler->mouseMoveEvent(ev)) QTreeView::mouseMoveEvent(ev); } void KrInterDetailedView::wheelEvent(QWheelEvent *ev) { if (!_mouseHandler->wheelEvent(ev)) QTreeView::wheelEvent(ev); } void KrInterDetailedView::dragEnterEvent(QDragEnterEvent *ev) { if (!_mouseHandler->dragEnterEvent(ev)) QTreeView::dragEnterEvent(ev); } void KrInterDetailedView::dragMoveEvent(QDragMoveEvent *ev) { QTreeView::dragMoveEvent(ev); _mouseHandler->dragMoveEvent(ev); } void KrInterDetailedView::dragLeaveEvent(QDragLeaveEvent *ev) { if (!_mouseHandler->dragLeaveEvent(ev)) QTreeView::dragLeaveEvent(ev); } void KrInterDetailedView::dropEvent(QDropEvent *ev) { if (!_mouseHandler->dropEvent(ev)) QTreeView::dropEvent(ev); } bool KrInterDetailedView::event(QEvent * e) { _mouseHandler->otherEvent(e); return QTreeView::event(e); } void KrInterDetailedView::renameCurrentItem() { QModelIndex cIndex = currentIndex(); QModelIndex nameIndex = _model->index(cIndex.row(), KrViewProperties::Name); edit(nameIndex); updateEditorData(); update(nameIndex); } bool KrInterDetailedView::eventFilter(QObject *object, QEvent *event) { if (object == header()) { if (event->type() == QEvent::ContextMenu) { QContextMenuEvent *me = (QContextMenuEvent *)event; showContextMenu(me->globalPos()); return true; } else if (event->type() == QEvent::Resize) { recalculateColumnSizes(); return false; } } return false; } void KrInterDetailedView::showContextMenu(const QPoint & p) { QMenu popup(this); popup.setTitle(i18n("Columns")); QVector actions; for(int i = KrViewProperties::Ext; i < KrViewProperties::MAX_COLUMNS; i++) { QString text = (_model->headerData(i, Qt::Horizontal)).toString(); QAction *act = popup.addAction(text); act->setCheckable(true); act->setChecked(!header()->isSectionHidden(i)); act->setData(i); actions.append(act); } popup.addSeparator(); QAction *actAutoResize = popup.addAction(i18n("Automatically Resize Columns")); actAutoResize->setCheckable(true); actAutoResize->setChecked(_autoResizeColumns); QAction *res = popup.exec(p); if (res == 0) return; if(res == actAutoResize) { _autoResizeColumns = actAutoResize->isChecked(); recalculateColumnSizes(); } else { int column = res->data().toInt(); if(header()->isSectionHidden(column)) header()->showSection(column); else header()->hideSection(column); if(KrViewProperties::Ext == column) _model->setExtensionEnabled(!header()->isSectionHidden(KrViewProperties::Ext)); } op()->settingsChanged(KrViewProperties::PropColumns); } void KrInterDetailedView::sectionResized(int /*column*/, int oldSize, int newSize) { // *** taken from dolphin *** // If the user changes the size of the headers, the autoresize feature should be // turned off. As there is no dedicated interface to find out whether the header // section has been resized by the user or by a resize event, another approach is used. // Attention: Take care when changing the if-condition to verify that there is no // regression in combination with bug 178630 (see fix in comment #8). if ((QApplication::mouseButtons() & Qt::LeftButton) && header()->underMouse()) { _autoResizeColumns = false; op()->settingsChanged(KrViewProperties::PropColumns); } if (oldSize == newSize || !_model->ready()) return; recalculateColumnSizes(); } void KrInterDetailedView::sectionMoved(int /*logicalIndex*/, int /*oldVisualIndex*/, int /*newVisualIndex*/) { op()->settingsChanged(KrViewProperties::PropColumns); } void KrInterDetailedView::recalculateColumnSizes() { if(!_autoResizeColumns) return; int sum = 0; for (int i = 0; i != _model->columnCount(); i++) { if (!isColumnHidden(i)) sum += header()->sectionSize(i); } if (sum != header()->width()) { int delta = sum - header()->width(); int nameSize = header()->sectionSize(KrViewProperties::Name); if (nameSize - delta > 20) header()->resizeSection(KrViewProperties::Name, nameSize - delta); } } bool KrInterDetailedView::viewportEvent(QEvent * event) { if (event->type() == QEvent::ToolTip) { QHelpEvent *he = static_cast(event); const QModelIndex index = indexAt(he->pos()); if (index.isValid()) { int width = header()->sectionSize(index.column()); QString text = index.data(Qt::DisplayRole).toString(); int textWidth = QFontMetrics(_viewFont).width(text); const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; textWidth += 2 * textMargin; QVariant decor = index.data(Qt::DecorationRole); if (decor.isValid() && decor.type() == QVariant::Pixmap) { QPixmap p = decor.value(); textWidth += p.width() + 2 * textMargin; } if (textWidth <= width) { event->accept(); return true; } } } return QTreeView::viewportEvent(event); } +void KrInterDetailedView::drawRow(QPainter *painter, const QStyleOptionViewItem &options, + const QModelIndex &index) const +{ + QTreeView::drawRow(painter, options, index); + // (always) draw dashed line border around current item row. This is done internally in + // QTreeView::drawRow() only when panel is focused, we have to repeat it here. + if (index == currentIndex()) { + QStyleOptionFocusRect o; + o.backgroundColor = options.palette.color(QPalette::Normal, QPalette::Background); + + const QRect focusRect(0, options.rect.y(), header()->length(), options.rect.height()); + o.rect = style()->visualRect(layoutDirection(), viewport()->rect(), focusRect); + + style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter); + } +} + void KrInterDetailedView::setSortMode(KrViewProperties::ColumnType sortColumn, bool descending) { Qt::SortOrder sortDir = descending ? Qt::DescendingOrder : Qt::AscendingOrder; sortByColumn(sortColumn, sortDir); } void KrInterDetailedView::setFileIconSize(int size) { KrView::setFileIconSize(size); setIconSize(QSize(fileIconSize(), fileIconSize())); } QRect KrInterDetailedView::itemRect(const vfile *vf) { QRect r = visualRect(_model->vfileIndex(vf)); r.setLeft(0); r.setWidth(header()->length()); return r; } void KrInterDetailedView::copySettingsFrom(KrView *other) { if(other->instance() == instance()) { // the other view is of the same type KrInterDetailedView *v = static_cast(other); _autoResizeColumns = v->_autoResizeColumns; header()->restoreState(v->header()->saveState()); _model->setExtensionEnabled(!isColumnHidden(KrViewProperties::Ext)); recalculateColumnSizes(); setFileIconSize(v->fileIconSize()); } } diff --git a/krusader/Panel/krinterdetailedview.h b/krusader/Panel/krinterdetailedview.h index a37dc92d..663fa0ef 100644 --- a/krusader/Panel/krinterdetailedview.h +++ b/krusader/Panel/krinterdetailedview.h @@ -1,92 +1,94 @@ /***************************************************************************** * Copyright (C) 2002 Shie Erlich * * Copyright (C) 2002 Rafi Yanai * * * * 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 2 of the License, or * * (at your option) any later version. * * * * This package 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 package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef KRINTERDETAILEDVIEW_H #define KRINTERDETAILEDVIEW_H // QtCore #include // QtGui #include // QtWidgets #include #include "krinterview.h" class QMouseEvent; class QKeyEvent; class QDragEnterEvent; class KrInterDetailedView : public QTreeView, public KrInterView { Q_OBJECT public: KrInterDetailedView(QWidget *parent, KrViewInstance &instance, KConfig *cfg); virtual ~KrInterDetailedView(); void updateView() Q_DECL_OVERRIDE; bool ensureVisibilityAfterSelect() Q_DECL_OVERRIDE { return false; } int itemsPerPage() Q_DECL_OVERRIDE; void setSortMode(KrViewProperties::ColumnType sortColumn, bool descending) Q_DECL_OVERRIDE; void setFileIconSize(int size) Q_DECL_OVERRIDE; void doRestoreSettings(KConfigGroup grp) Q_DECL_OVERRIDE; protected slots: void renameCurrentItem() Q_DECL_OVERRIDE; void sectionResized(int, int, int); void sectionMoved(int, int, int); void currentChanged(const QModelIndex & current, const QModelIndex & previous) Q_DECL_OVERRIDE; protected: void setup() Q_DECL_OVERRIDE; void copySettingsFrom(KrView *other) Q_DECL_OVERRIDE; void saveSettings(KConfigGroup grp, KrViewProperties::PropertyType properties) Q_DECL_OVERRIDE; // Don't do anything, selections are handled by the mouse handler void setSelection(const QRect &, QItemSelectionModel::SelectionFlags) Q_DECL_OVERRIDE {} void selectAll() Q_DECL_OVERRIDE {} void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mouseDoubleClickEvent(QMouseEvent *ev) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *) Q_DECL_OVERRIDE; bool event(QEvent * e) Q_DECL_OVERRIDE; void dragEnterEvent(QDragEnterEvent *e) Q_DECL_OVERRIDE; void dragMoveEvent(QDragMoveEvent *e) Q_DECL_OVERRIDE; void dragLeaveEvent(QDragLeaveEvent *e) Q_DECL_OVERRIDE; void dropEvent(QDropEvent *) Q_DECL_OVERRIDE; bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; bool viewportEvent(QEvent * event) Q_DECL_OVERRIDE; + void drawRow(QPainter *painter, const QStyleOptionViewItem &options, + const QModelIndex &index) const Q_DECL_OVERRIDE; QRect itemRect(const vfile *vf) Q_DECL_OVERRIDE; void showContextMenu(const QPoint & p) Q_DECL_OVERRIDE; void recalculateColumnSizes(); private: QFont _viewFont; bool _autoResizeColumns; }; #endif // __krinterview__