24 #include <QtCore/QTimeLine>
25 #include <QtCore/QTimer>
26 #include <QtGui/QPainter>
27 #include <QtGui/QAbstractItemDelegate>
28 #include <QtGui/QKeyEvent>
29 #include <QtGui/QApplication>
30 #include <QtGui/QScrollBar>
56 #define LATERAL_MARGIN 4
57 #define CAPACITYBAR_HEIGHT 6
59 class KFilePlacesViewDelegate :
public QAbstractItemDelegate
63 virtual ~KFilePlacesViewDelegate();
64 virtual QSize sizeHint(
const QStyleOptionViewItem &option,
65 const QModelIndex &index)
const;
66 virtual void paint(QPainter *painter,
67 const QStyleOptionViewItem &option,
68 const QModelIndex &index)
const;
71 void setIconSize(
int newSize);
73 void addAppearingItem(
const QModelIndex &index);
74 void setAppearingItemProgress(qreal value);
75 void addDisappearingItem(
const QModelIndex &index);
76 void setDisappearingItemProgress(qreal value);
78 void setShowHoverIndication(
bool show);
80 void addFadeAnimation(
const QModelIndex &index, QTimeLine *timeLine);
81 void removeFadeAnimation(
const QModelIndex &index);
82 QModelIndex indexForFadeAnimation(QTimeLine *timeLine)
const;
83 QTimeLine *fadeAnimationForIndex(
const QModelIndex &index)
const;
85 qreal contentsOpacity(
const QModelIndex &index)
const;
92 int m_appearingIconSize;
93 qreal m_appearingOpacity;
96 int m_disappearingIconSize;
97 qreal m_disappearingOpacity;
99 bool m_showHoverIndication;
105 KFilePlacesViewDelegate::KFilePlacesViewDelegate(
KFilePlacesView *parent) :
106 QAbstractItemDelegate(parent),
109 m_appearingIconSize(0),
110 m_appearingOpacity(0.0),
111 m_disappearingIconSize(0),
112 m_disappearingOpacity(0.0),
113 m_showHoverIndication(true)
117 KFilePlacesViewDelegate::~KFilePlacesViewDelegate()
121 QSize KFilePlacesViewDelegate::sizeHint(
const QStyleOptionViewItem &option,
122 const QModelIndex &index)
const
124 int iconSize = m_iconSize;
125 if (m_appearingItems.contains(index)) {
126 iconSize = m_appearingIconSize;
127 }
else if (m_disappearingItems.contains(index)) {
128 iconSize = m_disappearingIconSize;
134 return QSize(option.rect.width(), option.fontMetrics.height() / 2 + qMax(iconSize, option.fontMetrics.height()));
137 void KFilePlacesViewDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index)
const
141 if (m_appearingItems.contains(index)) {
142 painter->setOpacity(m_appearingOpacity);
143 }
else if (m_disappearingItems.contains(index)) {
144 painter->setOpacity(m_disappearingOpacity);
147 QStyleOptionViewItemV4 opt = option;
148 if (!m_showHoverIndication) {
149 opt.state &= ~QStyle::State_MouseOver;
151 QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter);
154 bool isLTR = option.direction == Qt::LeftToRight;
156 QIcon icon = index.model()->
data(index, Qt::DecorationRole).value<QIcon>();
157 QPixmap pm = icon.pixmap(m_iconSize, m_iconSize);
159 : option.rect.right() -
LATERAL_MARGIN - m_iconSize, option.rect.top() + (option.rect.height() - m_iconSize) / 2);
160 painter->drawPixmap(point, pm);
162 if (option.state & QStyle::State_Selected) {
163 QPalette::ColorGroup cg = QPalette::Active;
164 if (!(option.state & QStyle::State_Enabled)) {
165 cg = QPalette::Disabled;
166 }
else if (!(option.state & QStyle::State_Active)) {
167 cg = QPalette::Inactive;
169 painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
174 const KUrl url = placesModel->
url(index);
175 bool drawCapacityBar =
false;
178 const KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(mountPointPath);
179 drawCapacityBar = info.size() != 0 &&
182 if (drawCapacityBar && contentsOpacity(index) > 0)
185 painter->setOpacity(painter->opacity() * contentsOpacity(index));
189 : 0, option.rect.top() + (option.rect.height() / 2 - height / 2), option.rect.width() - m_iconSize -
LATERAL_MARGIN * 2, option.fontMetrics.height());
190 painter->drawText(rectText, Qt::AlignLeft | Qt::AlignTop, option.fontMetrics.elidedText(index.model()->data(index).toString(), Qt::ElideRight, rectText.width()));
193 capacityBar.setValue((info.used() * 100) / info.size());
194 capacityBar.drawCapacityBar(painter, capacityRect);
199 painter->setOpacity(painter->opacity() * (1 - contentsOpacity(index)));
203 rectText =
QRect(isLTR ? m_iconSize + LATERAL_MARGIN * 2 + option.rect.left()
204 : 0, option.rect.top(), option.rect.width() - m_iconSize - LATERAL_MARGIN * 2, option.rect.height());
205 painter->drawText(rectText, Qt::AlignLeft | Qt::AlignVCenter, option.fontMetrics.elidedText(index.model()->data(index).toString(), Qt::ElideRight, rectText.width()));
207 if (drawCapacityBar && contentsOpacity(index) > 0) {
214 int KFilePlacesViewDelegate::iconSize()
const
219 void KFilePlacesViewDelegate::setIconSize(
int newSize)
221 m_iconSize = newSize;
224 void KFilePlacesViewDelegate::addAppearingItem(
const QModelIndex &index)
226 m_appearingItems << index;
229 void KFilePlacesViewDelegate::setAppearingItemProgress(qreal value)
232 m_appearingOpacity = 0.0;
233 m_appearingIconSize = iconSize()*value*4;
235 if (m_appearingIconSize>=m_iconSize) {
236 m_appearingIconSize = m_iconSize;
239 m_appearingIconSize = m_iconSize;
240 m_appearingOpacity = (value-0.25)*4/3;
243 m_appearingItems.clear();
248 void KFilePlacesViewDelegate::addDisappearingItem(
const QModelIndex &index)
250 m_disappearingItems << index;
253 void KFilePlacesViewDelegate::setDisappearingItemProgress(qreal value)
258 m_disappearingOpacity = 0.0;
259 m_disappearingIconSize = iconSize()*value*4;
261 if (m_disappearingIconSize>=m_iconSize) {
262 m_disappearingIconSize = m_iconSize;
266 m_disappearingItems.clear();
269 m_disappearingIconSize = m_iconSize;
270 m_disappearingOpacity = (value-0.25)*4/3;
274 void KFilePlacesViewDelegate::setShowHoverIndication(
bool show)
276 m_showHoverIndication = show;
279 void KFilePlacesViewDelegate::addFadeAnimation(
const QModelIndex &index, QTimeLine *timeLine)
281 m_timeLineMap.insert(index, timeLine);
282 m_timeLineInverseMap.insert(timeLine, index);
285 void KFilePlacesViewDelegate::removeFadeAnimation(
const QModelIndex &index)
287 QTimeLine *timeLine = m_timeLineMap.value(index, 0);
288 m_timeLineMap.remove(index);
289 m_timeLineInverseMap.remove(timeLine);
292 QModelIndex KFilePlacesViewDelegate::indexForFadeAnimation(QTimeLine *timeLine)
const
294 return m_timeLineInverseMap.value(timeLine, QModelIndex());
297 QTimeLine *KFilePlacesViewDelegate::fadeAnimationForIndex(
const QModelIndex &index)
const
299 return m_timeLineMap.value(index, 0);
302 qreal KFilePlacesViewDelegate::contentsOpacity(
const QModelIndex &index)
const
304 QTimeLine *timeLine = fadeAnimationForIndex(index);
306 return timeLine->currentValue();
324 bool autoResizeItems;
326 bool smoothItemResizing;
330 QPersistentModelIndex lastClickedIndex;
334 void setCurrentIndex(
const QModelIndex &index);
335 void adaptItemSize();
336 void updateHiddenRows();
337 bool insertAbove(
const QRect &itemRect,
const QPoint &pos)
const;
338 bool insertBelow(
const QRect &itemRect,
const QPoint &pos)
const;
339 int insertIndicatorHeight(
int itemHeight)
const;
340 void fadeCapacityBar(
const QModelIndex &index, FadeType fadeType);
342 void _k_placeClicked(
const QModelIndex &index);
343 void _k_placeEntered(
const QModelIndex &index);
344 void _k_placeLeft(
const QModelIndex &index);
345 void _k_storageSetupDone(
const QModelIndex &index,
bool success);
346 void _k_adaptItemsUpdate(qreal value);
347 void _k_itemAppearUpdate(qreal value);
348 void _k_itemDisappearUpdate(qreal value);
349 void _k_enableSmoothItemResizing();
350 void _k_trashUpdated(
KJob *job);
351 void _k_capacityBarFadeValueChanged();
352 void _k_triggerDevicePolling();
354 QTimeLine adaptItemsTimeline;
355 int oldSize, endSize;
357 QTimeLine itemAppearTimeline;
358 QTimeLine itemDisappearTimeline;
361 KFilePlacesViewDelegate *delegate;
363 int pollingRequestCount;
367 :
QListView(parent), d(new Private(this))
370 d->smoothItemResizing =
false;
371 d->dropOnPlace =
false;
372 d->autoResizeItems =
true;
374 d->lastClickedStorage = 0;
375 d->pollingRequestCount = 0;
376 d->delegate =
new KFilePlacesViewDelegate(
this);
378 setSelectionRectVisible(
false);
379 setSelectionMode(SingleSelection);
381 setDragEnabled(
true);
382 setAcceptDrops(
true);
383 setMouseTracking(
true);
384 setDropIndicatorShown(
false);
385 setFrameStyle(QFrame::NoFrame);
387 setResizeMode(Adjust);
388 setItemDelegate(d->delegate);
390 QPalette palette = viewport()->palette();
391 palette.setColor(viewport()->backgroundRole(), Qt::transparent);
392 palette.setColor(viewport()->foregroundRole(), palette.color(QPalette::WindowText));
393 viewport()->setPalette(palette);
395 connect(
this, SIGNAL(clicked(QModelIndex)),
396 this, SLOT(_k_placeClicked(QModelIndex)));
401 connect(&d->adaptItemsTimeline, SIGNAL(valueChanged(qreal)),
402 this, SLOT(_k_adaptItemsUpdate(qreal)));
403 d->adaptItemsTimeline.setDuration(500);
404 d->adaptItemsTimeline.setUpdateInterval(5);
405 d->adaptItemsTimeline.setCurveShape(QTimeLine::EaseInOutCurve);
407 connect(&d->itemAppearTimeline, SIGNAL(valueChanged(qreal)),
408 this, SLOT(_k_itemAppearUpdate(qreal)));
409 d->itemAppearTimeline.setDuration(500);
410 d->itemAppearTimeline.setUpdateInterval(5);
411 d->itemAppearTimeline.setCurveShape(QTimeLine::EaseInOutCurve);
413 connect(&d->itemDisappearTimeline, SIGNAL(valueChanged(qreal)),
414 this, SLOT(_k_itemDisappearUpdate(qreal)));
415 d->itemDisappearTimeline.setDuration(500);
416 d->itemDisappearTimeline.setUpdateInterval(5);
417 d->itemDisappearTimeline.setCurveShape(QTimeLine::EaseInOutCurve);
419 viewport()->installEventFilter(d->watcher);
420 connect(d->watcher, SIGNAL(entryEntered(QModelIndex)),
421 this, SLOT(_k_placeEntered(QModelIndex)));
422 connect(d->watcher, SIGNAL(entryLeft(QModelIndex)),
423 this, SLOT(_k_placeLeft(QModelIndex)));
425 d->pollDevices.setInterval(5000);
426 connect(&d->pollDevices, SIGNAL(
timeout()),
this, SLOT(_k_triggerDevicePolling()));
433 verticalScrollBar()->setAttribute(Qt::WA_OpaquePaintEvent,
false);
443 d->dropOnPlace = enabled;
448 return d->dropOnPlace;
453 d->autoResizeItems = enabled;
458 return d->autoResizeItems;
463 KUrl oldUrl = d->currentUrl;
466 if (placesModel==0)
return;
469 QModelIndex current = selectionModel()->currentIndex();
471 if (index.isValid()) {
472 if (current!=index && placesModel->
isHidden(current) && !d->showAll) {
473 KFilePlacesViewDelegate *delegate =
static_cast<KFilePlacesViewDelegate*
>(itemDelegate());
474 delegate->addDisappearingItem(current);
476 if (d->itemDisappearTimeline.state()!=QTimeLine::Running) {
477 delegate->setDisappearingItemProgress(0.0);
478 d->itemDisappearTimeline.start();
482 if (current!=index && placesModel->
isHidden(index) && !d->showAll) {
483 KFilePlacesViewDelegate *delegate =
static_cast<KFilePlacesViewDelegate*
>(itemDelegate());
484 delegate->addAppearingItem(index);
486 if (d->itemAppearTimeline.state()!=QTimeLine::Running) {
487 delegate->setAppearingItemProgress(0.0);
488 d->itemAppearTimeline.start();
491 setRowHidden(index.row(),
false);
495 selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
497 d->currentUrl =
KUrl();
498 selectionModel()->clear();
501 if (!current.isValid()) {
502 d->updateHiddenRows();
510 if (placesModel==0)
return;
512 d->showAll = showAll;
514 KFilePlacesViewDelegate *delegate =
static_cast<KFilePlacesViewDelegate*
>(itemDelegate());
516 int rowCount = placesModel->
rowCount();
517 QModelIndex current = placesModel->
closestItem(d->currentUrl);
520 d->updateHiddenRows();
522 for (
int i=0; i<rowCount; ++i) {
523 QModelIndex index = placesModel->
index(i, 0);
524 if (index!=current && placesModel->
isHidden(index)) {
525 delegate->addAppearingItem(index);
529 if (d->itemAppearTimeline.state()!=QTimeLine::Running) {
530 delegate->setAppearingItemProgress(0.0);
531 d->itemAppearTimeline.start();
534 for (
int i=0; i<rowCount; ++i) {
535 QModelIndex index = placesModel->
index(i, 0);
536 if (index!=current && placesModel->
isHidden(index)) {
537 delegate->addDisappearingItem(index);
541 if (d->itemDisappearTimeline.state()!=QTimeLine::Running) {
542 delegate->setDisappearingItemProgress(0.0);
543 d->itemDisappearTimeline.start();
550 QListView::keyPressEvent(event);
551 if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)) {
552 d->_k_placeClicked(currentIndex());
559 KFilePlacesViewDelegate *delegate =
dynamic_cast<KFilePlacesViewDelegate*
>(itemDelegate());
561 if (placesModel==0)
return;
563 QModelIndex index = indexAt(event->pos());
576 if (index.isValid()) {
577 if (!placesModel->
isDevice(index)) {
578 if (placesModel->
url(index) ==
KUrl(
"trash:/")) {
579 emptyTrash = menu.addAction(
KIcon(
"trash-empty"),
i18nc(
"@action:inmenu",
"Empty Trash"));
581 emptyTrash->setEnabled(!trashConfig.
group(
"Status").
readEntry(
"Empty",
true));
584 add = menu.addAction(
KIcon(
"document-new"),
i18n(
"Add Entry..."));
585 mainSeparator = menu.addSeparator();
586 edit = menu.addAction(
KIcon(
"document-properties"),
i18n(
"&Edit Entry '%1'...", label));
590 eject->setParent(&menu);
591 menu.addAction(eject);
596 teardown->setParent(&menu);
597 menu.addAction(teardown);
600 if (teardown!=0 || eject!=0) {
601 mainSeparator = menu.addSeparator();
605 add = menu.addAction(
KIcon(
"document-new"),
i18n(
"Add Entry..."));
608 hide = menu.addAction(
i18n(
"&Hide Entry '%1'", label));
609 hide->setCheckable(
true);
610 hide->setChecked(placesModel->
isHidden(index));
612 add = menu.addAction(
KIcon(
"document-new"),
i18n(
"Add Entry..."));
617 showAll =
new QAction(
i18n(
"&Show All Entries"), &menu);
618 showAll->setCheckable(
true);
619 showAll->setChecked(d->showAll);
620 if (mainSeparator == 0) {
621 mainSeparator = menu.addSeparator();
623 menu.insertAction(mainSeparator, showAll);
627 if (index.isValid() && !placesModel->
isDevice(index)) {
628 remove = menu.addAction(
KIcon(
"edit-delete"),
i18n(
"&Remove Entry '%1'", label));
631 menu.addActions(actions());
633 if (menu.isEmpty()) {
637 QAction *result = menu.exec(event->globalPos());
639 if (emptyTrash != 0 && result == emptyTrash) {
640 const QString text =
i18nc(
"@info",
"Do you really want to empty the Trash? All items will be deleted.");
648 QByteArray packedArgs;
649 QDataStream stream(&packedArgs, QIODevice::WriteOnly);
653 job->ui()->setWindow(parentWidget());
654 connect(job, SIGNAL(result(
KJob*)), SLOT(_k_trashUpdated(
KJob*)));
656 }
else if (edit != 0 && result == edit) {
661 bool appLocal = !bookmark.
metaDataItem(
"OnlyInApp").isEmpty();
664 iconName,
false, appLocal, 64,
this))
669 placesModel->
editPlace(index, label, url, iconName, appName);
672 }
else if (
remove != 0 && result ==
remove) {
674 }
else if (hide != 0 && result == hide) {
676 QModelIndex current = placesModel->
closestItem(d->currentUrl);
678 if (index!=current && !d->showAll && hide->isChecked()) {
679 delegate->addDisappearingItem(index);
681 if (d->itemDisappearTimeline.state()!=QTimeLine::Running) {
682 delegate->setDisappearingItemProgress(0.0);
683 d->itemDisappearTimeline.start();
686 }
else if (showAll != 0 && result == showAll) {
688 }
else if (teardown != 0 && result == teardown) {
690 }
else if (eject != 0 && result == eject) {
692 }
else if (add != 0 && result == add) {
693 KUrl url = d->currentUrl;
696 bool appLocal =
true;
698 iconName,
true, appLocal, 64,
this))
703 placesModel->
addPlace(label, url, iconName, appName, index);
708 selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
713 QListView::resizeEvent(event);
719 QListView::showEvent(event);
720 QTimer::singleShot(100,
this, SLOT(_k_enableSmoothItemResizing()));
725 QListView::hideEvent(event);
726 d->smoothItemResizing =
false;
731 QListView::dragEnterEvent(event);
734 KFilePlacesViewDelegate *delegate =
dynamic_cast<KFilePlacesViewDelegate*
>(itemDelegate());
735 delegate->setShowHoverIndication(
false);
737 d->dropRect =
QRect();
742 QListView::dragLeaveEvent(event);
745 KFilePlacesViewDelegate *delegate =
dynamic_cast<KFilePlacesViewDelegate*
>(itemDelegate());
746 delegate->setShowHoverIndication(
true);
748 setDirtyRegion(d->dropRect);
753 QListView::dragMoveEvent(event);
756 const QPoint pos =
event->pos();
757 const QModelIndex index = indexAt(pos);
758 setDirtyRegion(d->dropRect);
759 if (index.isValid()) {
760 const QRect rect = visualRect(index);
761 const int gap = d->insertIndicatorHeight(rect.height());
762 if (d->insertAbove(rect, pos)) {
764 d->dropRect =
QRect(rect.left(), rect.top() - gap / 2,
766 }
else if (d->insertBelow(rect, pos)) {
768 d->dropRect =
QRect(rect.left(), rect.bottom() + 1 - gap / 2,
776 setDirtyRegion(d->dropRect);
781 const QPoint pos =
event->pos();
782 const QModelIndex index = indexAt(pos);
783 if (index.isValid()) {
784 const QRect rect = visualRect(index);
785 if (!d->insertAbove(rect, pos) && !d->insertBelow(rect, pos)) {
787 Q_ASSERT(placesModel != 0);
789 event->acceptProposedAction();
793 QListView::dropEvent(event);
796 KFilePlacesViewDelegate *delegate =
dynamic_cast<KFilePlacesViewDelegate*
>(itemDelegate());
797 delegate->setShowHoverIndication(
true);
802 QListView::paintEvent(event);
803 if (d->dragging && !d->dropRect.isEmpty()) {
805 QPainter painter(viewport());
807 const QModelIndex index = indexAt(d->dropRect.topLeft());
808 const QRect itemRect = visualRect(index);
809 const bool drawInsertIndicator = !d->dropOnPlace ||
810 d->dropRect.height() <= d->insertIndicatorHeight(itemRect.height());
812 if (drawInsertIndicator) {
814 QBrush blendedBrush = viewOptions().palette.brush(QPalette::Normal, QPalette::Highlight);
815 QColor color = blendedBrush.color();
817 const int y = (d->dropRect.top() + d->dropRect.bottom()) / 2;
818 const int thickness = d->dropRect.height() / 2;
819 Q_ASSERT(thickness >= 1);
821 const int alphaDec = alpha / (thickness + 1);
822 for (
int i = 0; i < thickness; i++) {
823 color.setAlpha(alpha);
825 painter.setPen(color);
826 painter.drawLine(d->dropRect.left(), y - i, d->dropRect.right(), y - i);
827 painter.drawLine(d->dropRect.left(), y + i, d->dropRect.right(), y + i);
831 QStyleOptionViewItemV4 opt;
834 opt.state = QStyle::State_Enabled | QStyle::State_MouseOver;
835 style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &painter,
this);
842 QListView::setModel(model);
843 d->updateHiddenRows();
848 connect(model, SIGNAL(rowsRemoved(QModelIndex,
int,
int)),
849 this, SLOT(adaptItemSize()), Qt::QueuedConnection);
850 connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
851 d->watcher, SLOT(currentIndexChanged(QModelIndex)));
856 QListView::rowsInserted(parent, start, end);
859 KFilePlacesViewDelegate *delegate =
dynamic_cast<KFilePlacesViewDelegate*
>(itemDelegate());
862 for (
int i=start; i<=end; ++i) {
863 QModelIndex index = placesModel->
index(i, 0, parent);
864 if (d->showAll || !placesModel->
isHidden(index)) {
865 delegate->addAppearingItem(index);
867 setRowHidden(i,
true);
871 if (d->itemAppearTimeline.state()!=QTimeLine::Running) {
872 delegate->setAppearingItemProgress(0.0);
873 d->itemAppearTimeline.start();
883 return QListView::sizeHint();
885 const int height = QListView::sizeHint().height();
886 QFontMetrics fm = d->q->fontMetrics();
889 for (
int i=0; i<placesModel->
rowCount(); ++i) {
890 QModelIndex index = placesModel->
index(i, 0);
892 textWidth = qMax(textWidth,fm.width(index.data(Qt::DisplayRole).toString()));
896 return QSize(iconSize + textWidth + fm.height() / 2, height);
899 void KFilePlacesView::Private::setCurrentIndex(
const QModelIndex &index)
903 if (placesModel==0)
return;
905 KUrl url = placesModel->
url(index);
910 emit q->urlChanged(url);
912 q->setShowAll(
false);
915 q->setUrl(currentUrl);
919 void KFilePlacesView::Private::adaptItemSize()
921 KFilePlacesViewDelegate *delegate =
dynamic_cast<KFilePlacesViewDelegate*
>(q->itemDelegate());
922 if (!delegate)
return;
924 if (!autoResizeItems) {
925 int size = q->iconSize().width();
926 delegate->setIconSize(size);
927 q->scheduleDelayedItemsLayout();
933 if (placesModel==0)
return;
935 int rowCount = placesModel->
rowCount();
940 QModelIndex current = placesModel->
closestItem(currentUrl);
942 if (placesModel->
isHidden(current)) {
947 if (rowCount==0)
return;
950 const int maxSize = 64;
953 QFontMetrics fm = q->fontMetrics();
954 for (
int i=0; i<placesModel->
rowCount(); ++i) {
955 QModelIndex index = placesModel->
index(i, 0);
958 textWidth = qMax(textWidth,fm.width(index.data(Qt::DisplayRole).toString()));
961 const int margin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, q) + 1;
962 const int maxWidth = q->viewport()->width() - textWidth - 4 * margin - 1;
963 const int maxHeight = ((q->height() - (fm.height() / 2) * rowCount) / rowCount) - 1;
965 int size = qMin(maxHeight, maxWidth);
969 }
else if (size>maxSize) {
976 if (size==delegate->iconSize())
return;
978 if (smoothItemResizing) {
979 oldSize = delegate->iconSize();
981 if (adaptItemsTimeline.state()!=QTimeLine::Running) {
982 adaptItemsTimeline.start();
985 delegate->setIconSize(size);
986 q->scheduleDelayedItemsLayout();
990 void KFilePlacesView::Private::updateHiddenRows()
994 if (placesModel==0)
return;
996 int rowCount = placesModel->
rowCount();
997 QModelIndex current = placesModel->
closestItem(currentUrl);
999 for (
int i=0; i<rowCount; ++i) {
1000 QModelIndex index = placesModel->
index(i, 0);
1001 if (index!=current && placesModel->
isHidden(index) && !showAll) {
1002 q->setRowHidden(i,
true);
1004 q->setRowHidden(i,
false);
1011 bool KFilePlacesView::Private::insertAbove(
const QRect &itemRect,
const QPoint &pos)
const
1014 return pos.y() < itemRect.top() + insertIndicatorHeight(itemRect.height()) / 2;
1017 return pos.y() < itemRect.top() + (itemRect.height() / 2);
1020 bool KFilePlacesView::Private::insertBelow(
const QRect &itemRect,
const QPoint &pos)
const
1023 return pos.y() > itemRect.bottom() - insertIndicatorHeight(itemRect.height()) / 2;
1026 return pos.y() >= itemRect.top() + (itemRect.height() / 2);
1029 int KFilePlacesView::Private::insertIndicatorHeight(
int itemHeight)
const
1034 int height = itemHeight / 4;
1037 }
else if (height > max) {
1043 void KFilePlacesView::Private::fadeCapacityBar(
const QModelIndex &index, FadeType fadeType)
1045 QTimeLine *timeLine = delegate->fadeAnimationForIndex(index);
1047 delegate->removeFadeAnimation(index);
1048 timeLine =
new QTimeLine(250, q);
1049 connect(timeLine, SIGNAL(valueChanged(qreal)), q, SLOT(_k_capacityBarFadeValueChanged()));
1050 if (fadeType == FadeIn) {
1051 timeLine->setDirection(QTimeLine::Forward);
1052 timeLine->setCurrentTime(0);
1054 timeLine->setDirection(QTimeLine::Backward);
1055 timeLine->setCurrentTime(250);
1057 delegate->addFadeAnimation(index, timeLine);
1061 void KFilePlacesView::Private::_k_placeClicked(
const QModelIndex &index)
1065 if (placesModel==0)
return;
1067 lastClickedIndex = QPersistentModelIndex();
1070 QObject::connect(placesModel, SIGNAL(setupDone(QModelIndex,
bool)),
1071 q, SLOT(_k_storageSetupDone(QModelIndex,
bool)));
1073 lastClickedIndex = index;
1078 setCurrentIndex(index);
1081 void KFilePlacesView::Private::_k_placeEntered(
const QModelIndex &index)
1083 fadeCapacityBar(index, FadeIn);
1084 pollingRequestCount++;
1085 if (pollingRequestCount == 1) {
1086 pollDevices.start();
1090 void KFilePlacesView::Private::_k_placeLeft(
const QModelIndex &index)
1092 fadeCapacityBar(index, FadeOut);
1093 pollingRequestCount--;
1094 if (!pollingRequestCount) {
1099 void KFilePlacesView::Private::_k_storageSetupDone(
const QModelIndex &index,
bool success)
1101 if (index!=lastClickedIndex) {
1107 QObject::disconnect(placesModel, SIGNAL(setupDone(QModelIndex,
bool)),
1108 q, SLOT(_k_storageSetupDone(QModelIndex,
bool)));
1111 setCurrentIndex(lastClickedIndex);
1113 q->setUrl(currentUrl);
1116 lastClickedIndex = QPersistentModelIndex();
1119 void KFilePlacesView::Private::_k_adaptItemsUpdate(qreal value)
1121 int add = (endSize-oldSize)*value;
1123 int size = oldSize+add;
1125 KFilePlacesViewDelegate *delegate =
dynamic_cast<KFilePlacesViewDelegate*
>(q->itemDelegate());
1126 delegate->setIconSize(size);
1127 q->scheduleDelayedItemsLayout();
1130 void KFilePlacesView::Private::_k_itemAppearUpdate(qreal value)
1132 KFilePlacesViewDelegate *delegate =
dynamic_cast<KFilePlacesViewDelegate*
>(q->itemDelegate());
1134 delegate->setAppearingItemProgress(value);
1135 q->scheduleDelayedItemsLayout();
1138 void KFilePlacesView::Private::_k_itemDisappearUpdate(qreal value)
1140 KFilePlacesViewDelegate *delegate =
dynamic_cast<KFilePlacesViewDelegate*
>(q->itemDelegate());
1142 delegate->setDisappearingItemProgress(value);
1148 q->scheduleDelayedItemsLayout();
1151 void KFilePlacesView::Private::_k_enableSmoothItemResizing()
1153 smoothItemResizing =
true;
1156 void KFilePlacesView::Private::_k_trashUpdated(
KJob *job)
1159 static_cast<KIO::Job*
>(job)->ui()->showErrorMessage();
1161 org::kde::KDirNotify::emitFilesAdded(
"trash:/");
1164 void KFilePlacesView::Private::_k_capacityBarFadeValueChanged()
1166 const QModelIndex index = delegate->indexForFadeAnimation(static_cast<QTimeLine*>(q->sender()));
1167 if (!index.isValid()) {
1173 void KFilePlacesView::Private::_k_triggerDevicePolling()
1175 const QModelIndex hoveredIndex = watcher->hoveredIndex();
1176 if (hoveredIndex.isValid()) {
1178 if (placesModel->
isDevice(hoveredIndex)) {
1179 q->update(hoveredIndex);
1182 const QModelIndex focusedIndex = watcher->focusedIndex();
1183 if (focusedIndex.isValid() && focusedIndex != hoveredIndex) {
1185 if (placesModel->
isDevice(focusedIndex)) {
1186 q->update(focusedIndex);
1193 QListView::dataChanged(topLeft, bottomRight);
1197 #include "kfileplacesview.moc"
1198 #include "kfileplacesview_p.moc"
KUrl url(const QModelIndex &index) const
void urlsDropped(const KUrl &dest, QDropEvent *event, QWidget *parent)
Is emitted if items are dropped on the place dest.
QString i18n(const char *text)
SimpleJob * special(const KUrl &url, const QByteArray &data, JobFlags flags=DefaultFlags)
int currentSize(KIconLoader::Group group) const
virtual void dropEvent(QDropEvent *event)
int IconSize(KIconLoader::Group group)
void setPlaceHidden(const QModelIndex &index, bool hidden)
void requestSetup(const QModelIndex &index)
static bool getInformation(bool allowGlobal, KUrl &url, QString &label, QString &icon, bool isAddingNewPlace, bool &appLocal, int iconSize, QWidget *parent=0)
A convenience method to show the dialog and retrieve all the properties via the given parameters...
static KIconLoader * global()
bool isDevice(const QModelIndex &index) const
virtual void dragEnterEvent(QDragEnterEvent *event)
QString label(StandardShortcut id)
virtual void paintEvent(QPaintEvent *event)
virtual void dragLeaveEvent(QDragLeaveEvent *event)
This class allows to display a KFilePlacesModel.
void requestTeardown(const QModelIndex &index)
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Get the children model index for the given row and column.
bool isAutoResizeItemsEnabled() const
KConfigGroup group(const QByteArray &group)
QString text(const QModelIndex &index) const
void addPlace(const QString &text, const KUrl &url, const QString &iconName=QString(), const QString &appName=QString())
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
QAction * teardownActionForIndex(const QModelIndex &index) const
void requestEject(const QModelIndex &index)
bool setupNeeded(const QModelIndex &index) const
void rowsInserted(const QModelIndex &parent, int start, int end)
virtual QSize sizeHint() const
QVariant data(const QModelIndex &index, int role) const
Get a visible data based on Qt role for the given index.
int rowCount(const QModelIndex &parent=QModelIndex()) const
Get the number of rows for a model index.
QString i18nc(const char *ctxt, const char *text)
bool isHidden(const QModelIndex &index) const
void removePlace(const QModelIndex &index) const
QModelIndex closestItem(const KUrl &url) const
Returns the closest item for the URL url.
KBookmark bookmarkForIndex(const QModelIndex &index) const
Solid::Device deviceForIndex(const QModelIndex &index) const
QAction * ejectActionForIndex(const QModelIndex &index) const
virtual void showEvent(QShowEvent *event)
QString componentName() const
void setDropOnPlaceEnabled(bool enabled)
If enabled is true, it is allowed dropping items above a place for e.
virtual void dragMoveEvent(QDragMoveEvent *event)
QString metaDataItem(const QString &key) const
void editPlace(const QModelIndex &index, const QString &text, const KUrl &url, const QString &iconName=QString(), const QString &appName=QString())
bool isDropOnPlaceEnabled() const
static KNotification * event(const QString &eventId, const QString &title, const QString &text, const QPixmap &pixmap=QPixmap(), QWidget *widget=0L, const NotificationFlags &flags=CloseOnTimeout, const KComponentData &componentData=KComponentData())
virtual void contextMenuEvent(QContextMenuEvent *event)
void setShowAll(bool showAll)
virtual void resizeEvent(QResizeEvent *event)
virtual void setModel(QAbstractItemModel *model)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
virtual void keyPressEvent(QKeyEvent *event)
const KComponentData & mainComponent()
virtual void hideEvent(QHideEvent *event)
void setUrl(const KUrl &url)
KFilePlacesView(QWidget *parent=0)
#define CAPACITYBAR_HEIGHT
T readEntry(const QString &key, const T &aDefault) const
static int warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
void setAutoResizeItemsEnabled(bool enabled)
If enabled is true (the default), items will automatically resize themselves to fill the view...
This class is a list view model.