#include <KToggleAction>
#include <KUrl>
-#include "additionalinfoaccessor.h"
#include "dolphindirlister.h"
#include "dolphinnewfilemenuobserver.h"
#include "dolphin_detailsmodesettings.h"
namespace {
const int MaxModeEnum = DolphinView::CompactView;
- const int MaxSortingEnum = DolphinView::SortByPath;
};
DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
m_tabsForFiles(false),
m_assureVisibleCurrentIndex(false),
m_isFolderWritable(true),
+ m_dragging(false),
m_url(url),
m_mode(DolphinView::IconsView),
- m_additionalInfoList(),
+ m_visibleRoles(),
m_topLayout(0),
m_dirLister(0),
m_container(0),
m_container->setVisibleRoles(QList<QByteArray>() << "name");
m_container->installEventFilter(this);
setFocusProxy(m_container);
+ connect(m_container->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip()));
+ connect(m_container->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip()));
KItemListController* controller = m_container->controller();
controller->setSelectionBehavior(KItemListController::MultiSelection);
- connect(controller, SIGNAL(itemActivated(int)),
- this, SLOT(slotItemActivated(int)));
+ connect(controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int)));
+ connect(controller, SIGNAL(itemsActivated(QSet<int>)), this, SLOT(slotItemsActivated(QSet<int>)));
connect(controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int)));
connect(controller, SIGNAL(itemContextMenuRequested(int,QPointF)), this, SLOT(slotItemContextMenuRequested(int,QPointF)));
connect(controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF)));
connect(controller, SIGNAL(headerContextMenuRequested(QPointF)), this, SLOT(slotHeaderContextMenuRequested(QPointF)));
- connect(controller, SIGNAL(itemExpansionToggleClicked(int)), this, SLOT(slotItemExpansionToggleClicked(int)));
+ connect(controller, SIGNAL(itemPressed(int,Qt::MouseButton)), this, SLOT(hideToolTip()));
connect(controller, SIGNAL(itemHovered(int)), this, SLOT(slotItemHovered(int)));
connect(controller, SIGNAL(itemUnhovered(int)), this, SLOT(slotItemUnhovered(int)));
connect(controller, SIGNAL(itemDropEvent(int,QGraphicsSceneDragDropEvent*)), this, SLOT(slotItemDropEvent(int,QGraphicsSceneDragDropEvent*)));
connect(model, SIGNAL(loadingCompleted()), this, SLOT(slotLoadingCompleted()));
}
+ KItemListView* view = controller->view();
+ view->installEventFilter(this);
+ connect(view, SIGNAL(sortOrderChanged(Qt::SortOrder,Qt::SortOrder)),
+ this, SLOT(slotSortOrderChangedByHeader(Qt::SortOrder,Qt::SortOrder)));
+ connect(view, SIGNAL(sortRoleChanged(QByteArray,QByteArray)),
+ this, SLOT(slotSortRoleChangedByHeader(QByteArray,QByteArray)));
+ connect(view, SIGNAL(visibleRolesChanged(QList<QByteArray>,QList<QByteArray>)),
+ this, SLOT(slotVisibleRolesChangedByHeader(QList<QByteArray>,QList<QByteArray>)));
+
KItemListSelectionManager* selectionManager = controller->selectionManager();
connect(selectionManager, SIGNAL(selectionChanged(QSet<int>,QSet<int>)),
this, SLOT(slotSelectionChanged(QSet<int>,QSet<int>)));
ViewProperties props(url());
props.setHiddenFilesShown(show);
- m_dirLister->setShowingDotFiles(show);
- m_dirLister->emitChanges();
+ fileItemModel()->setShowHiddenFiles(show);
emit hiddenFilesShownChanged(show);
}
const KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
const QSet<int> selectedIndexes = selectionManager->selectedItems();
- QList<int> sortedIndexes = selectedIndexes.toList();
- qSort(sortedIndexes);
-
KFileItemList selectedItems;
- QListIterator<int> it(sortedIndexes);
+ QSetIterator<int> it(selectedIndexes);
while (it.hasNext()) {
const int index = it.next();
selectedItems.append(model->fileItem(index));
for (int index = 0; index < model->count(); index++) {
const KFileItem item = model->fileItem(index);
- if (pattern.exactMatch(item.name())) {
+ if (pattern.exactMatch(item.text())) {
// An alternative approach would be to store the matching items in a QSet<int> and
// select them in one go after the loop, but we'd need a new function
// KItemListSelectionManager::setSelected(QSet<int>, SelectionMode mode)
return m_container->zoomLevel();
}
-void DolphinView::setSorting(Sorting sorting)
+void DolphinView::setSortRole(const QByteArray& role)
{
- if (sorting != this->sorting()) {
- updateSorting(sorting);
+ if (role != sortRole()) {
+ updateSortRole(role);
}
}
-DolphinView::Sorting DolphinView::sorting() const
+QByteArray DolphinView::sortRole() const
{
- KItemModelBase* model = m_container->controller()->model();
- return sortingForSortRole(model->sortRole());
+ const KItemModelBase* model = m_container->controller()->model();
+ return model->sortRole();
}
void DolphinView::setSortOrder(Qt::SortOrder order)
return model->sortFoldersFirst();
}
-void DolphinView::setAdditionalInfoList(const QList<AdditionalInfo>& info)
+void DolphinView::setVisibleRoles(const QList<QByteArray>& roles)
{
- const QList<AdditionalInfo> previousList = info;
+ const QList<QByteArray> previousRoles = roles;
ViewProperties props(url());
- props.setAdditionalInfoList(info);
+ props.setVisibleRoles(roles);
- m_additionalInfoList = info;
- applyAdditionalInfoListToView();
+ m_visibleRoles = roles;
+ m_container->setVisibleRoles(roles);
- emit additionalInfoListChanged(m_additionalInfoList, previousList);
+ emit visibleRolesChanged(m_visibleRoles, previousRoles);
}
-QList<DolphinView::AdditionalInfo> DolphinView::additionalInfoList() const
+QList<QByteArray> DolphinView::visibleRoles() const
{
- return m_additionalInfoList;
+ return m_visibleRoles;
}
void DolphinView::reload()
m_dirLister->stop();
}
-void DolphinView::refresh()
+void DolphinView::readSettings()
{
- const bool oldActivationState = m_active;
- const int oldZoomLevel = zoomLevel();
- m_active = true;
+ const int oldZoomLevel = m_container->zoomLevel();
+ GeneralSettings::self()->readConfig();
+ m_container->readSettings();
applyViewProperties();
- reload();
- setActive(oldActivationState);
- updateZoomLevel(oldZoomLevel);
+ const int newZoomLevel = m_container->zoomLevel();
+ if (newZoomLevel != oldZoomLevel) {
+ emit zoomLevelChanged(newZoomLevel, oldZoomLevel);
+ }
+}
+
+void DolphinView::writeSettings()
+{
+ GeneralSettings::self()->writeConfig();
+ m_container->writeSettings();
}
void DolphinView::setNameFilter(const QString& nameFilter)
{
- Q_UNUSED(nameFilter);
- //m_viewModeController->setNameFilter(nameFilter);
+ fileItemModel()->setNameFilter(nameFilter);
}
QString DolphinView::nameFilter() const
{
- return QString(); //m_viewModeController->nameFilter();
+ return fileItemModel()->nameFilter();
}
void DolphinView::calculateItemCount(int& fileCount,
emit urlAboutToBeChanged(url);
m_url = url;
- if (GeneralSettings::showToolTips()) {
- m_toolTipManager->hideToolTip();
- }
+ hideToolTip();
// It is important to clear the items from the model before
// applying the view properties, otherwise expensive operations
}
break;
+ case QEvent::GraphicsSceneDragEnter:
+ if (watched == m_container->controller()->view()) {
+ m_dragging = true;
+ }
+ break;
+
+ case QEvent::GraphicsSceneDragLeave:
+ if (watched == m_container->controller()->view()) {
+ m_dragging = false;
+ }
+ break;
+
+ case QEvent::GraphicsSceneDrop:
+ if (watched == m_container->controller()->view()) {
+ m_dragging = false;
+ }
default:
break;
}
}
}
+void DolphinView::hideEvent(QHideEvent* event)
+{
+ hideToolTip();
+ QWidget::hideEvent(event);
+}
+
void DolphinView::activate()
{
setActive(true);
void DolphinView::slotItemActivated(int index)
{
- Q_UNUSED(index);
+ const KFileItem item = fileItemModel()->fileItem(index);
+ if (!item.isNull()) {
+ emit itemActivated(item);
+ }
+}
- const KFileItemList items = selectedItems();
- if (items.isEmpty()) {
- return;
+void DolphinView::slotItemsActivated(const QSet<int>& indexes)
+{
+ Q_ASSERT(indexes.count() >= 2);
+
+ KFileItemList items;
+
+ KFileItemModel* model = fileItemModel();
+ QSetIterator<int> it(indexes);
+ while (it.hasNext()) {
+ const int index = it.next();
+ items.append(model->fileItem(index));
}
- if (items.count() == 1) {
- emit itemActivated(items.at(0)); // caught by DolphinViewContainer or DolphinPart
- } else {
- foreach (const KFileItem& item, items) {
- if (item.isDir()) {
- emit tabRequested(item.url());
- } else {
- emit itemActivated(item);
- }
+ foreach (const KFileItem& item, items) {
+ if (item.isDir()) {
+ emit tabRequested(item.url());
+ } else {
+ emit itemActivated(item);
}
}
}
void DolphinView::slotItemContextMenuRequested(int index, const QPointF& pos)
{
- if (GeneralSettings::showToolTips()) {
- m_toolTipManager->hideToolTip();
- }
const KFileItem item = fileItemModel()->fileItem(index);
emit requestContextMenu(pos.toPoint(), item, url(), QList<QAction*>());
}
void DolphinView::slotViewContextMenuRequested(const QPointF& pos)
{
- if (GeneralSettings::showToolTips()) {
- m_toolTipManager->hideToolTip();
- }
emit requestContextMenu(pos.toPoint(), KFileItem(), url(), QList<QAction*>());
}
KItemListView* view = m_container->controller()->view();
const QSet<QByteArray> visibleRolesSet = view->visibleRoles().toSet();
+ QString groupName;
+ QMenu* groupMenu = 0;
+
// Add all roles to the menu that can be shown or hidden by the user
- const AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance();
- const QList<DolphinView::AdditionalInfo> keys = infoAccessor.keys();
- foreach (const DolphinView::AdditionalInfo info, keys) {
- const QByteArray& role = infoAccessor.role(info);
- if (role != "name") {
- const QString text = fileItemModel()->roleDescription(role);
-
- QAction* action = menu.data()->addAction(text);
- action->setCheckable(true);
- action->setChecked(visibleRolesSet.contains(role));
- action->setData(info);
+ const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation();
+ foreach (const KFileItemModel::RoleInfo& info, rolesInfo) {
+ if (info.role == "name") {
+ // It should not be possible to hide the "name" role
+ continue;
+ }
+
+ const QString text = fileItemModel()->roleDescription(info.role);
+ QAction* action = 0;
+ if (info.group.isEmpty()) {
+ action = menu.data()->addAction(text);
+ } else {
+ if (!groupMenu || info.group != groupName) {
+ groupName = info.group;
+ groupMenu = menu.data()->addMenu(groupName);
+ }
+
+ action = groupMenu->addAction(text);
}
+
+ action->setCheckable(true);
+ action->setChecked(visibleRolesSet.contains(info.role));
+ action->setData(info.role);
}
QAction* action = menu.data()->exec(pos.toPoint());
if (action) {
// Show or hide the selected role
- const DolphinView::AdditionalInfo info =
- static_cast<DolphinView::AdditionalInfo>(action->data().toInt());
+ const QByteArray selectedRole = action->data().toByteArray();
ViewProperties props(url());
- QList<DolphinView::AdditionalInfo> infoList = props.additionalInfoList();
-
- const QByteArray selectedRole = infoAccessor.role(info);
QList<QByteArray> visibleRoles = view->visibleRoles();
-
if (action->isChecked()) {
- const int index = keys.indexOf(info) + 1;
- visibleRoles.insert(index, selectedRole);
- infoList.insert(index, info);
+ visibleRoles.append(selectedRole);
} else {
visibleRoles.removeOne(selectedRole);
- infoList.removeOne(info);
}
view->setVisibleRoles(visibleRoles);
- props.setAdditionalInfoList(infoList);
+ props.setVisibleRoles(visibleRoles);
}
delete menu.data();
}
-void DolphinView::slotItemExpansionToggleClicked(int index)
-{
- // TODO: When doing a model->setExpanded(false) it should
- // be checked here whether the current index is part of the
- // closed sub-tree. If this is the case, the current index
- // should be adjusted to the parent index.
- KFileItemModel* model = fileItemModel();
- const bool expanded = model->isExpanded(index);
- model->setExpanded(index, !expanded);
-}
-
void DolphinView::slotItemHovered(int index)
{
const KFileItem item = fileItemModel()->fileItem(index);
- if (GeneralSettings::showToolTips()) {
- QRectF itemRect = m_container->controller()->view()->itemRect(index);
+ if (GeneralSettings::showToolTips() && !m_dragging) {
+ QRectF itemRect = m_container->controller()->view()->itemContextRect(index);
const QPoint pos = m_container->mapToGlobal(itemRect.topLeft().toPoint());
itemRect.moveTo(pos);
void DolphinView::slotItemUnhovered(int index)
{
Q_UNUSED(index);
- if (GeneralSettings::showToolTips()) {
- m_toolTipManager->hideToolTip();
- }
+ hideToolTip();
emit requestItemInfo(KFileItem());
}
void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event)
{
- const KFileItem destItem = fileItemModel()->fileItem(index);
+ KUrl destUrl;
+ KFileItem destItem = fileItemModel()->fileItem(index);
+ if (destItem.isNull() || (!destItem.isDir() && !destItem.isDesktopFile())) {
+ // Use the URL of the view as drop target if the item is no directory
+ // or desktop-file
+ destItem = fileItemModel()->rootItem();
+ destUrl = url();
+ } else {
+ // The item represents a directory or desktop-file
+ destUrl = destItem.url();
+ }
QDropEvent dropEvent(event->pos().toPoint(),
event->possibleActions(),
event->buttons(),
event->modifiers());
- DragAndDropHelper::dropUrls(destItem, url(), &dropEvent, this);
+ const QString error = DragAndDropHelper::dropUrls(destItem, destUrl, &dropEvent);
+ if (!error.isEmpty()) {
+ emit errorMessage(error);
+ }
}
void DolphinView::slotModelChanged(KItemModelBase* current, KItemModelBase* previous)
emit selectionChanged(selectedItems());
}
-void DolphinView::dropUrls(const KFileItem& destItem,
- const KUrl& destPath,
- QDropEvent* event)
-{
- Q_UNUSED(destItem);
- Q_UNUSED(destPath);
- markPastedUrlsAsSelected(event->mimeData());
- //DragAndDropHelper::instance().dropUrls(destItem, destPath, event, this);
-}
-
-void DolphinView::updateSorting(DolphinView::Sorting sorting)
+void DolphinView::updateSortRole(const QByteArray& role)
{
ViewProperties props(url());
- props.setSorting(sorting);
+ props.setSortRole(role);
KItemModelBase* model = m_container->controller()->model();
- model->setSortRole(sortRoleForSorting(sorting));
+ model->setSortRole(role);
- emit sortingChanged(sorting);
+ emit sortRoleChanged(role);
}
void DolphinView::updateSortOrder(Qt::SortOrder order)
// Restore expanded folders (only relevant for the details view - will be ignored by the view in other view modes)
QSet<KUrl> urls;
stream >> urls;
- fileItemModel()->setExpanded(urls);
+ fileItemModel()->restoreExpandedUrls(urls);
}
void DolphinView::saveState(QDataStream& stream)
const int currentIndex = m_container->controller()->selectionManager()->currentItem();
if (currentIndex != -1) {
KFileItem item = fileItemModel()->fileItem(currentIndex);
+ Q_ASSERT(!item.isNull()); // If the current index is valid a item must exist
KUrl currentItemUrl = item.url();
stream << currentItemUrl;
} else {
}
}
+void DolphinView::hideToolTip()
+{
+ if (GeneralSettings::showToolTips()) {
+ m_toolTipManager->hideToolTip();
+ }
+}
+
void DolphinView::showHoverInformation(const KFileItem& item)
{
emit requestItemInfo(item);
}
}
+void DolphinView::slotSortOrderChangedByHeader(Qt::SortOrder current, Qt::SortOrder previous)
+{
+ Q_UNUSED(previous);
+ Q_ASSERT(fileItemModel()->sortOrder() == current);
+
+ ViewProperties props(url());
+ props.setSortOrder(current);
+
+ emit sortOrderChanged(current);
+}
+
+void DolphinView::slotSortRoleChangedByHeader(const QByteArray& current, const QByteArray& previous)
+{
+ Q_UNUSED(previous);
+ Q_ASSERT(fileItemModel()->sortRole() == current);
+
+ ViewProperties props(url());
+ props.setSortRole(current);
+
+ emit sortRoleChanged(current);
+}
+
+void DolphinView::slotVisibleRolesChangedByHeader(const QList<QByteArray>& current,
+ const QList<QByteArray>& previous)
+{
+ Q_UNUSED(previous);
+ Q_ASSERT(m_container->controller()->view()->visibleRoles() == current);
+
+ const QList<QByteArray> previousVisibleRoles = m_visibleRoles;
+
+ m_visibleRoles = current;
+
+ ViewProperties props(url());
+ props.setVisibleRoles(m_visibleRoles);
+
+ emit visibleRolesChanged(m_visibleRoles, previousVisibleRoles);
+}
+
KFileItemModel* DolphinView::fileItemModel() const
{
return static_cast<KFileItemModel*>(m_container->controller()->model());
m_container->beginTransaction();
const ViewProperties props(url());
+ KFileItemModel* model = fileItemModel();
const Mode mode = props.viewMode();
if (m_mode != mode) {
}
const bool hiddenFilesShown = props.hiddenFilesShown();
- if (hiddenFilesShown != m_dirLister->showingDotFiles()) {
- m_dirLister->setShowingDotFiles(hiddenFilesShown);
- m_dirLister->emitChanges();
+ if (hiddenFilesShown != model->showHiddenFiles()) {
+ model->setShowHiddenFiles(hiddenFilesShown);
emit hiddenFilesShownChanged(hiddenFilesShown);
}
- KFileItemModel* model = fileItemModel();
-
const bool groupedSorting = props.groupedSorting();
if (groupedSorting != model->groupedSorting()) {
model->setGroupedSorting(groupedSorting);
emit groupedSortingChanged(groupedSorting);
}
- const DolphinView::Sorting sorting = props.sorting();
- const QByteArray newSortRole = sortRoleForSorting(sorting);
- if (newSortRole != model->sortRole()) {
- model->setSortRole(newSortRole);
- emit sortingChanged(sorting);
+ const QByteArray sortRole = props.sortRole();
+ if (sortRole != model->sortRole()) {
+ model->setSortRole(sortRole);
+ emit sortRoleChanged(sortRole);
}
const Qt::SortOrder sortOrder = props.sortOrder();
emit sortFoldersFirstChanged(sortFoldersFirst);
}
- const QList<DolphinView::AdditionalInfo> infoList = props.additionalInfoList();
- if (infoList != m_additionalInfoList) {
- const QList<DolphinView::AdditionalInfo> previousList = m_additionalInfoList;
- m_additionalInfoList = infoList;
- applyAdditionalInfoListToView();
- emit additionalInfoListChanged(m_additionalInfoList, previousList);
+ const QList<QByteArray> visibleRoles = props.visibleRoles();
+ if (visibleRoles != m_visibleRoles) {
+ const QList<QByteArray> previousVisibleRoles = m_visibleRoles;
+ m_visibleRoles = visibleRoles;
+ m_container->setVisibleRoles(visibleRoles);
+ emit visibleRolesChanged(m_visibleRoles, previousVisibleRoles);
}
const bool previewsShown = props.previewsShown();
m_container->endTransaction();
}
-void DolphinView::applyAdditionalInfoListToView()
-{
- const AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance();
-
- QList<QByteArray> visibleRoles;
- visibleRoles.reserve(m_additionalInfoList.count() + 1);
- visibleRoles.append("name");
-
- foreach (AdditionalInfo info, m_additionalInfoList) {
- visibleRoles.append(infoAccessor.role(info));
- }
-
- m_container->setVisibleRoles(visibleRoles);
-}
-
void DolphinView::pasteToUrl(const KUrl& url)
{
markPastedUrlsAsSelected(QApplication::clipboard()->mimeData());
KonqOperations::doPaste(this, url);
}
-void DolphinView::updateZoomLevel(int oldZoomLevel)
-{
- Q_UNUSED(oldZoomLevel);
- /* const int newZoomLevel = ZoomLevelInfo::zoomLevelForIconSize(m_viewAccessor.itemView()->iconSize());
- if (oldZoomLevel != newZoomLevel) {
- m_viewModeController->setZoomLevel(newZoomLevel);
- emit zoomLevelChanged(newZoomLevel);
- }*/
-}
-
KUrl::List DolphinView::simplifiedSelectedUrls() const
{
KUrl::List urls;
}
}
-QByteArray DolphinView::sortRoleForSorting(Sorting sorting) const
-{
- switch (sorting) {
- case SortByName: return "name";
- case SortBySize: return "size";
- case SortByDate: return "date";
- case SortByPermissions: return "permissions";
- case SortByOwner: return "owner";
- case SortByGroup: return "group";
- case SortByType: return "type";
- case SortByDestination: return "destination";
- case SortByPath: return "path";
- default: break;
- }
-
- return QByteArray();
-}
-
-DolphinView::Sorting DolphinView::sortingForSortRole(const QByteArray& sortRole) const
-{
- static QHash<QByteArray, DolphinView::Sorting> sortHash;
- if (sortHash.isEmpty()) {
- sortHash.insert("name", SortByName);
- sortHash.insert("size", SortBySize);
- sortHash.insert("date", SortByDate);
- sortHash.insert("permissions", SortByPermissions);
- sortHash.insert("owner", SortByOwner);
- sortHash.insert("group", SortByGroup);
- sortHash.insert("type", SortByType);
- sortHash.insert("destination", SortByDestination);
- sortHash.insert("path", SortByPath);
- }
- return sortHash.value(sortRole);
-}
-
QString DolphinView::fileSizeText(KIO::filesize_t fileSize)
{
const KLocale* locale = KGlobal::locale();