diff options
Diffstat (limited to 'src')
24 files changed, 910 insertions, 51 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8f7f4db77..60d97d46f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ configure_file(config-nepomuk.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-nepomuk macro_bool_to_01(X11_Xrender_FOUND HAVE_XRENDER) configure_file(config-X11.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-X11.h ) -include_directories( ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ) +include_directories( ${KACTIVITIES_INCLUDE_DIRS} ) if (Nepomuk_FOUND) # Yes, Soprano includes is what we need here @@ -29,12 +29,13 @@ set(dolphinprivate_LIB_SRCS kitemviews/kitemlistselectionmanager.cpp kitemviews/kitemliststyleoption.cpp kitemviews/kitemlistview.cpp + kitemviews/kitemlistviewaccessible.cpp kitemviews/kitemlistwidget.cpp kitemviews/kitemmodelbase.cpp kitemviews/kstandarditem.cpp kitemviews/kstandarditemlistgroupheader.cpp - kitemviews/kstandarditemlistview.cpp kitemviews/kstandarditemlistwidget.cpp + kitemviews/kstandarditemlistview.cpp kitemviews/kstandarditemmodel.cpp kitemviews/private/kfileitemclipboard.cpp kitemviews/private/kfileitemmodeldirlister.cpp @@ -243,6 +244,13 @@ if (Nepomuk_FOUND) ) endif (Nepomuk_FOUND) +if (KActivities_FOUND) + target_link_libraries( + kdeinit_dolphin + ${KACTIVITIES_LIBRARY} + ) +endif (KActivities_FOUND) + install(TARGETS kdeinit_dolphin ${INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS dolphin ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 17268297c..3bf3b3f55 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -1560,12 +1560,12 @@ void DolphinMainWindow::setupActions() KToggleAction* editableLocation = actionCollection()->add<KToggleAction>("editable_location"); editableLocation->setText(i18nc("@action:inmenu Navigation Bar", "Editable Location")); - editableLocation->setShortcut(Qt::CTRL | Qt::Key_L); + editableLocation->setShortcut(Qt::Key_F6); connect(editableLocation, SIGNAL(triggered()), this, SLOT(toggleEditLocation())); KAction* replaceLocation = actionCollection()->addAction("replace_location"); replaceLocation->setText(i18nc("@action:inmenu Navigation Bar", "Replace Location")); - replaceLocation->setShortcut(Qt::Key_F6); + replaceLocation->setShortcut(Qt::CTRL | Qt::Key_L); connect(replaceLocation, SIGNAL(triggered()), this, SLOT(replaceLocation())); // setup 'Go' menu @@ -1704,7 +1704,7 @@ void DolphinMainWindow::setupDockWidgets() connect(foldersPanel, SIGNAL(folderActivated(KUrl)), this, SLOT(changeUrl(KUrl))); connect(foldersPanel, SIGNAL(folderMiddleClicked(KUrl)), - this, SLOT(openNewActivatedTab(KUrl))); + this, SLOT(openNewTab(KUrl))); connect(foldersPanel, SIGNAL(errorMessage(QString)), this, SLOT(slotPanelErrorMessage(QString))); @@ -1756,13 +1756,15 @@ void DolphinMainWindow::setupDockWidgets() connect(placesPanel, SIGNAL(placeActivated(KUrl)), this, SLOT(changeUrl(KUrl))); connect(placesPanel, SIGNAL(placeMiddleClicked(KUrl)), - this, SLOT(openNewActivatedTab(KUrl))); + this, SLOT(openNewTab(KUrl))); connect(placesPanel, SIGNAL(errorMessage(QString)), this, SLOT(slotPanelErrorMessage(QString))); connect(this, SIGNAL(urlChanged(KUrl)), placesPanel, SLOT(setUrl(KUrl))); connect(placesDock, SIGNAL(visibilityChanged(bool)), this, SLOT(slotPlacesPanelVisibilityChanged(bool))); + connect(this, SIGNAL(settingsChanged()), + placesPanel, SLOT(readSettings())); // Add actions into the "Panels" menu KActionMenu* panelsMenu = new KActionMenu(i18nc("@action:inmenu View", "Panels"), this); @@ -1953,6 +1955,8 @@ void DolphinMainWindow::refreshViews() toggleSplitView(); } } + + emit settingsChanged(); } void DolphinMainWindow::clearStatusBar() diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index ab79fb0e6..7da5801ff 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -151,6 +151,11 @@ signals: */ void requestItemInfo(const KFileItem& item); + /** + * Is emitted if the settings have been changed. + */ + void settingsChanged(); + protected: /** @see QWidget::showEvent() */ virtual void showEvent(QShowEvent* event); diff --git a/src/dolphinnewfilemenu.cpp b/src/dolphinnewfilemenu.cpp index 30d79c670..9d9baabe2 100644 --- a/src/dolphinnewfilemenu.cpp +++ b/src/dolphinnewfilemenu.cpp @@ -22,7 +22,6 @@ #include "dolphinmainwindow.h" #include "dolphinviewcontainer.h" -#include "statusbar/dolphinstatusbar.h" #include "views/dolphinnewfilemenuobserver.h" #include "views/dolphinview.h" diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 31c82d606..8a566cffd 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -44,6 +44,10 @@ #include <KUrlNavigator> #include <KRun> +#ifdef KActivities_FOUND +#include <KActivities/ResourceInstance> +#endif + #include "dolphin_generalsettings.h" #include "filterbar/filterbar.h" #include "search/dolphinsearchbox.h" @@ -64,6 +68,9 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : m_statusBarTimer(0), m_statusBarTimestamp(), m_autoGrabFocus(true) +#ifdef KActivities_FOUND + , m_activityResourceInstance(0) +#endif { hide(); @@ -157,6 +164,14 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : m_topLayout->addWidget(m_statusBar); setSearchModeEnabled(isSearchUrl(url)); + + // Initialize kactivities resource instance + + #ifdef KActivities_FOUND + m_activityResourceInstance = new KActivities::ResourceInstance( + window()->winId(), url); + m_activityResourceInstance->setParent(this); + #endif } DolphinViewContainer::~DolphinViewContainer() @@ -172,6 +187,14 @@ void DolphinViewContainer::setActive(bool active) { m_urlNavigator->setActive(active); m_view->setActive(active); + + #ifdef KActivities_FOUND + if (active) { + m_activityResourceInstance->notifyFocusedIn(); + } else { + m_activityResourceInstance->notifyFocusedOut(); + } + #endif } bool DolphinViewContainer::isActive() const @@ -338,6 +361,10 @@ void DolphinViewContainer::setUrl(const KUrl& newUrl) if (newUrl != m_urlNavigator->locationUrl()) { m_urlNavigator->setLocationUrl(newUrl); } + + #ifdef KActivities_FOUND + m_activityResourceInstance->setUri(newUrl); + #endif } void DolphinViewContainer::setFilterBarVisible(bool visible) diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h index fd52806d9..8a0309b0c 100644 --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -31,6 +31,13 @@ #include <QWidget> #include <views/dolphinview.h> +#include <config-apps.h> + +#ifdef KActivities_FOUND +namespace KActivities { + class ResourceInstance; +} +#endif class FilterBar; class KMessageWidget; @@ -308,6 +315,11 @@ private: QTimer* m_statusBarTimer; // Triggers a delayed update QElapsedTimer m_statusBarTimestamp; // Time in ms since last update bool m_autoGrabFocus; + +#ifdef KActivities_FOUND +private: + KActivities::ResourceInstance * m_activityResourceInstance; +#endif }; #endif // DOLPHINVIEWCONTAINER_H diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index f5de6b6dd..5d6bdda9c 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -92,7 +92,6 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO , m_nepomukResourceWatcher(0), m_nepomukUriItems() #endif - { Q_ASSERT(model); @@ -542,11 +541,10 @@ void KFileItemModelRolesUpdater::resolveNextPendingRoles() bool changed = false; for (int i = 0; i <= 1; ++i) { QSet<KFileItem>& pendingItems = (i == 0) ? m_pendingVisibleItems : m_pendingInvisibleItems; - QSetIterator<KFileItem> it(pendingItems); - while (it.hasNext() && !changed && resolvedCount < MaxResolveItemsCount) { - const KFileItem item = it.next(); - pendingItems.remove(item); - changed = applyResolvedRoles(item, ResolveAll); + QSet<KFileItem>::iterator it = pendingItems.begin(); + while (it != pendingItems.end() && !changed && resolvedCount < MaxResolveItemsCount) { + changed = applyResolvedRoles(*it, ResolveAll); + it = pendingItems.erase(it); ++resolvedCount; } } @@ -656,13 +654,15 @@ void KFileItemModelRolesUpdater::startUpdating(const KItemRangeList& itemRanges) if (hasValidIndexRange) { // Move all current pending visible items that are not visible anymore // to the pending invisible items. - QSetIterator<KFileItem> it(m_pendingVisibleItems); - while (it.hasNext()) { - const KFileItem item = it.next(); + QSet<KFileItem>::iterator it = m_pendingVisibleItems.begin(); + while (it != m_pendingVisibleItems.end()) { + const KFileItem item = *it; const int index = m_model->index(item); if (index < m_firstVisibleIndex || index > m_lastVisibleIndex) { - m_pendingVisibleItems.remove(item); + it = m_pendingVisibleItems.erase(it); m_pendingInvisibleItems.insert(item); + } else { + ++it; } } } @@ -709,11 +709,14 @@ void KFileItemModelRolesUpdater::startPreviewJob(const KFileItemList& items) // MIME-type in a fast way. QElapsedTimer timer; timer.start(); + KFileItemList itemSubSet; - for (int i = 0; i < items.count(); ++i) { + const int count = items.count(); + itemSubSet.reserve(count); + for (int i = 0; i < count; ++i) { KFileItem item = items.at(i); item.determineMimeType(); - itemSubSet.append(items.at(i)); + itemSubSet.append(item); if (timer.elapsed() > MaxBlockTimeout) { #ifdef KFILEITEMMODELROLESUPDATER_DEBUG kDebug() << "Maximum time of" << MaxBlockTimeout << "ms exceeded, creating only previews for" @@ -768,13 +771,15 @@ void KFileItemModelRolesUpdater::resolvePendingRoles() timer.start(); // Resolve the MIME type of all visible items - QSetIterator<KFileItem> visibleIt(m_pendingVisibleItems); - while (visibleIt.hasNext()) { - const KFileItem item = visibleIt.next(); + QSet<KFileItem>::iterator visibleIt = m_pendingVisibleItems.begin(); + while (visibleIt != m_pendingVisibleItems.end()) { + const KFileItem item = *visibleIt; if (!hasSlowRoles) { Q_ASSERT(!m_pendingInvisibleItems.contains(item)); // All roles will be resolved by applyResolvedRoles() - m_pendingVisibleItems.remove(item); + visibleIt = m_pendingVisibleItems.erase(visibleIt); + } else { + ++visibleIt; } applyResolvedRoles(item, resolveHint); ++resolvedCount; @@ -872,7 +877,8 @@ void KFileItemModelRolesUpdater::sortAndResolveAllRoles() m_pendingInvisibleItems.insert(item); } } - for (int i = m_lastVisibleIndex + 1; i < m_model->count(); ++i) { + const int count = m_model->count(); + for (int i = m_lastVisibleIndex + 1; i < count; ++i) { const KFileItem item = m_model->fileItem(i); if (!item.isNull()) { m_pendingInvisibleItems.insert(item); @@ -895,26 +901,42 @@ void KFileItemModelRolesUpdater::sortAndResolvePendingRoles() // Trigger a preview generation of all pending items. Assure that the visible // pending items get generated first. - QSet<KFileItem> pendingItems; - pendingItems += m_pendingVisibleItems; - pendingItems += m_pendingInvisibleItems; - resetPendingRoles(); - Q_ASSERT(m_pendingVisibleItems.isEmpty()); - Q_ASSERT(m_pendingInvisibleItems.isEmpty()); + // Step 1: Check if any items in m_pendingVisibleItems are not visible any more + // and move them to m_pendingInvisibleItems. + QSet<KFileItem>::iterator itVisible = m_pendingVisibleItems.begin(); + while (itVisible != m_pendingVisibleItems.end()) { + const KFileItem item = *itVisible; + if (item.isNull()) { + itVisible = m_pendingVisibleItems.erase(itVisible); + continue; + } - QSetIterator<KFileItem> it(pendingItems); - while (it.hasNext()) { - const KFileItem item = it.next(); + const int index = m_model->index(item); + if (!hasValidIndexRange || (index >= m_firstVisibleIndex && index <= m_lastVisibleIndex)) { + ++itVisible; + } else { + itVisible = m_pendingVisibleItems.erase(itVisible); + m_pendingInvisibleItems.insert(item); + } + } + + // Step 2: Check if any items in m_pendingInvisibleItems have become visible + // and move them to m_pendingVisibleItems. + QSet<KFileItem>::iterator itInvisible = m_pendingInvisibleItems.begin(); + while (itInvisible != m_pendingInvisibleItems.end()) { + const KFileItem item = *itInvisible; if (item.isNull()) { + itInvisible = m_pendingInvisibleItems.erase(itInvisible); continue; } const int index = m_model->index(item); if (!hasValidIndexRange || (index >= m_firstVisibleIndex && index <= m_lastVisibleIndex)) { + itInvisible = m_pendingInvisibleItems.erase(itInvisible); m_pendingVisibleItems.insert(item); } else { - m_pendingInvisibleItems.insert(item); + ++itInvisible; } } diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 5a7175e4c..c16488f9e 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -40,6 +40,7 @@ #include <QGraphicsView> #include <QMimeData> #include <QTimer> +#include <QAccessible> KItemListController::KItemListController(KItemModelBase* model, KItemListView* view, QObject* parent) : QObject(parent), @@ -887,6 +888,8 @@ bool KItemListController::dropEvent(QGraphicsSceneDragDropEvent* event, const QT emit itemDropEvent(m_view->itemAt(pos), event); } + QAccessible::updateAccessibility(view(), 0, QAccessible::DragDropEnd); + return true; } @@ -1134,6 +1137,7 @@ void KItemListController::startDragging() drag->setHotSpot(hotSpot); drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::CopyAction); + QAccessible::updateAccessibility(view(), 0, QAccessible::DragDropStart); } KItemListWidget* KItemListController::hoveredWidget() const diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 05f2f697f..369906878 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -23,6 +23,7 @@ #include "kitemlistview.h" #include <KDebug> +#include "kitemlistcontainer.h" #include "kitemlistcontroller.h" #include "kitemlistheader.h" #include "kitemlistselectionmanager.h" @@ -43,6 +44,8 @@ #include <QStyleOptionRubberBand> #include <QTimer> +#include "kitemlistviewaccessible.h" + namespace { // Time in ms until reaching the autoscroll margin triggers // an initial autoscrolling @@ -52,6 +55,21 @@ namespace { const int RepeatingAutoScrollDelay = 1000 / 60; } +#ifndef QT_NO_ACCESSIBILITY +QAccessibleInterface* accessibleInterfaceFactory(const QString &key, QObject *object) +{ + Q_UNUSED(key) + + if (KItemListContainer* container = qobject_cast<KItemListContainer*>(object)) { + return new KItemListContainerAccessible(container); + } else if (KItemListView* view = qobject_cast<KItemListView*>(object)) { + return new KItemListViewAccessible(view); + } + + return 0; +} +#endif + KItemListView::KItemListView(QGraphicsWidget* parent) : QGraphicsWidget(parent), m_enabledSelectionToggles(false), @@ -110,6 +128,11 @@ KItemListView::KItemListView(QGraphicsWidget* parent) : m_headerWidget->setVisible(false); m_header = new KItemListHeader(this); + +#ifndef QT_NO_ACCESSIBILITY + QAccessible::installFactory(accessibleInterfaceFactory); +#endif + } KItemListView::~KItemListView() @@ -1191,6 +1214,7 @@ void KItemListView::slotItemsChanged(const KItemRangeList& itemRanges, doLayout(NoAnimation); } } + QAccessible::updateAccessibility(this, 0, QAccessible::TableModelChanged); } void KItemListView::slotGroupedSortingChanged(bool current) @@ -1253,6 +1277,7 @@ void KItemListView::slotCurrentChanged(int current, int previous) if (currentWidget) { currentWidget->setCurrent(true); } + QAccessible::updateAccessibility(this, current+1, QAccessible::Focus); } void KItemListView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous) diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 5723b9aaa..ca17053a3 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -742,6 +742,8 @@ private: friend class KItemListHeader; // Accesses m_headerWidget friend class KItemListController; friend class KItemListControllerTest; + friend class KItemListViewAccessible; + friend class KItemListAccessibleCell; }; /** diff --git a/src/kitemviews/kitemlistviewaccessible.cpp b/src/kitemviews/kitemlistviewaccessible.cpp new file mode 100644 index 000000000..a9ec69b43 --- /dev/null +++ b/src/kitemviews/kitemlistviewaccessible.cpp @@ -0,0 +1,539 @@ +/*************************************************************************** + * Copyright (C) 2012 by Amandeep Singh <[email protected]> * + * * + * 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 program 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 program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef QT_NO_ACCESSIBILITY + +#include "kitemlistviewaccessible.h" + +#include "kitemlistcontainer.h" +#include "kitemlistcontroller.h" +#include "kitemlistselectionmanager.h" +#include "kitemlistview.h" +#include "private/kitemlistviewlayouter.h" + +#include <QtGui/qaccessible2.h> +#include <qgraphicsscene.h> +#include <qgraphicsview.h> + +#include <KDebug> +#include <QHash> + +KItemListView* KItemListViewAccessible::view() const +{ + return qobject_cast<KItemListView*>(object()); +} + +KItemListViewAccessible::KItemListViewAccessible(KItemListView* view_) : + QAccessibleObjectEx(view_) +{ + Q_ASSERT(view()); +} + +void KItemListViewAccessible::modelReset() +{ +} + +QAccessible::Role KItemListViewAccessible::cellRole() const +{ + return QAccessible::Cell; +} + +QAccessibleTable2CellInterface* KItemListViewAccessible::cell(int index) const +{ + if (index < 0 || index >= view()->model()->count()) { + return 0; + } else { + return new KItemListAccessibleCell(view(), index); + } +} + +QVariant KItemListViewAccessible::invokeMethodEx(Method, int, const QVariantList&) +{ + return QVariant(); +} + +QAccessibleTable2CellInterface* KItemListViewAccessible::cellAt(int row, int column) const +{ + return cell(columnCount() * row + column); +} + +QAccessibleInterface* KItemListViewAccessible::caption() const +{ + return 0; +} + +QString KItemListViewAccessible::columnDescription(int) const +{ + return QString(); +} + +int KItemListViewAccessible::columnCount() const +{ + return view()->m_layouter->columnCount(); +} + +int KItemListViewAccessible::rowCount() const +{ + if (columnCount() <= 0) { + return 0; + } + + int itemCount = view()->model()->count(); + int rowCount = itemCount / columnCount(); + + if (rowCount <= 0) { + return 0; + } + + if (itemCount % columnCount()) { + ++rowCount; + } + return rowCount; +} + +int KItemListViewAccessible::selectedCellCount() const +{ + return view()->controller()->selectionManager()->selectedItems().size(); +} + +int KItemListViewAccessible::selectedColumnCount() const +{ + return 0; +} + +int KItemListViewAccessible::selectedRowCount() const +{ + return 0; +} + +QString KItemListViewAccessible::rowDescription(int) const +{ + return QString(); +} + +QList<QAccessibleTable2CellInterface*> KItemListViewAccessible::selectedCells() const +{ + QList<QAccessibleTable2CellInterface*> cells; + Q_FOREACH (int index, view()->controller()->selectionManager()->selectedItems()) { + cells.append(cell(index)); + } + return cells; +} + +QList<int> KItemListViewAccessible::selectedColumns() const +{ + return QList<int>(); +} + +QList<int> KItemListViewAccessible::selectedRows() const +{ + return QList<int>(); +} + +QAccessibleInterface* KItemListViewAccessible::summary() const +{ + return 0; +} + +bool KItemListViewAccessible::isColumnSelected(int) const +{ + return false; +} + +bool KItemListViewAccessible::isRowSelected(int) const +{ + return false; +} + +bool KItemListViewAccessible::selectRow(int) +{ + return true; +} + +bool KItemListViewAccessible::selectColumn(int) +{ + return true; +} + +bool KItemListViewAccessible::unselectRow(int) +{ + return true; +} + +bool KItemListViewAccessible::unselectColumn(int) +{ + return true; +} + +QAccessible2::TableModelChange KItemListViewAccessible::modelChange() const +{ + QAccessible2::TableModelChange change; + change.lastRow = rowCount(); + change.lastColumn = columnCount(); + return change; +} + +QAccessible::Role KItemListViewAccessible::role(int child) const +{ + Q_ASSERT(child >= 0); + + if (child > 0) { + return QAccessible::Cell; + } else { + return QAccessible::Table; + } +} + +QAccessible::State KItemListViewAccessible::state(int child) const +{ + if (child) { + QAccessibleInterface* interface = 0; + navigate(Child, child, &interface); + if (interface) { + return interface->state(0); + } + } + + return QAccessible::Normal | QAccessible::HasInvokeExtension; +} + +int KItemListViewAccessible::childAt(int x, int y) const +{ + const QPointF point = QPointF(x,y); + return view()->itemAt(view()->mapFromScene(point)); +} + +int KItemListViewAccessible::childCount() const +{ + return view()->model()->count(); +} + +int KItemListViewAccessible::indexOfChild(const QAccessibleInterface* interface) const +{ + const KItemListAccessibleCell* widget = static_cast<const KItemListAccessibleCell*>(interface); + return widget->index() + 1; +} + +QString KItemListViewAccessible::text(Text, int child) const +{ + Q_ASSERT(child == 0); + return QString(); +} + +QRect KItemListViewAccessible::rect(int child) const +{ + Q_UNUSED(child) + if (!view()->isVisible()) { + return QRect(); + } + const QPoint origin = view()->scene()->views()[0]->mapToGlobal(QPoint(0, 0)); + const QRect viewRect = view()->geometry().toRect(); + return viewRect.translated(origin); +} + +int KItemListViewAccessible::navigate(RelationFlag relation, int index, QAccessibleInterface** interface) const +{ + *interface = 0; + + switch (relation) { + case QAccessible::Child: + Q_ASSERT(index > 0); + *interface = cell(index - 1); + if (*interface) { + return 0; + } + break; + + default: + break; + } + + return -1; +} + +QAccessible::Relation KItemListViewAccessible::relationTo(int, const QAccessibleInterface*, int) const +{ + return QAccessible::Unrelated; +} + +#ifndef QT_NO_ACTION + +int KItemListViewAccessible::userActionCount(int) const +{ + return 0; +} + +QString KItemListViewAccessible::actionText(int, Text, int) const +{ + return QString(); +} + +bool KItemListViewAccessible::doAction(int, int, const QVariantList&) +{ + return false; +} + +#endif + +// Table Cell + +KItemListAccessibleCell::KItemListAccessibleCell(KItemListView* view, int index) : + m_view(view), + m_index(index) +{ + Q_ASSERT(index >= 0 && index < view->model()->count()); +} + +int KItemListAccessibleCell::columnExtent() const +{ + return 1; +} + +int KItemListAccessibleCell::rowExtent() const +{ + return 1; +} + +QList<QAccessibleInterface*> KItemListAccessibleCell::rowHeaderCells() const +{ + return QList<QAccessibleInterface*>(); +} + +QList<QAccessibleInterface*> KItemListAccessibleCell::columnHeaderCells() const +{ + return QList<QAccessibleInterface*>(); +} + +int KItemListAccessibleCell::columnIndex() const +{ + return m_view->m_layouter->itemColumn(m_index); +} + +int KItemListAccessibleCell::rowIndex() const +{ + return m_view->m_layouter->itemRow(m_index); +} + +bool KItemListAccessibleCell::isSelected() const +{ + return m_view->controller()->selectionManager()->isSelected(m_index); +} + +void KItemListAccessibleCell::rowColumnExtents(int* row, int* column, int* rowExtents, int* columnExtents, bool* selected) const +{ + const KItemListViewLayouter* layouter = m_view->m_layouter; + *row = layouter->itemRow(m_index); + *column = layouter->itemColumn(m_index); + *rowExtents = 1; + *columnExtents = 1; + *selected = isSelected(); +} + +QAccessibleTable2Interface* KItemListAccessibleCell::table() const +{ + return QAccessible::queryAccessibleInterface(m_view)->table2Interface(); +} + +QAccessible::Role KItemListAccessibleCell::role(int child) const +{ + Q_ASSERT(child == 0); + return QAccessible::Cell; +} + +QAccessible::State KItemListAccessibleCell::state(int child) const +{ + Q_ASSERT(child == 0); + QAccessible::State state = Normal; + + if (isSelected()) { + state |= Selected; + } + + if (m_view->controller()->selectionManager()->currentItem() == m_index) { + state |= Focused; + } + + state |= Selectable; + state |= Focusable; + + if (m_view->controller()->selectionBehavior() == KItemListController::MultiSelection) { + state |= MultiSelectable; + } + + if (m_view->model()->isExpandable(m_index)) { + if (m_view->model()->isExpanded(m_index)) { + state |= Expanded; + } else { + state |= Collapsed; + } + } + + return state; +} + +bool KItemListAccessibleCell::isExpandable() const +{ + return m_view->model()->isExpandable(m_index); +} + +QRect KItemListAccessibleCell::rect(int) const +{ + QRect rect = m_view->itemRect(m_index).toRect(); + + if (rect.isNull()) { + return QRect(); + } + + rect.translate(m_view->mapToScene(QPointF(0.0, 0.0)).toPoint()); + rect.translate(m_view->scene()->views()[0]->mapToGlobal(QPoint(0, 0))); + return rect; +} + +QString KItemListAccessibleCell::text(QAccessible::Text t, int child) const +{ + Q_ASSERT(child == 0); + Q_UNUSED(child) + + switch (t) { + case QAccessible::Value: + case QAccessible::Name: { + const QHash<QByteArray, QVariant> data = m_view->model()->data(m_index); + return data["text"].toString(); + } + + default: + break; + } + + return QString(); +} + +void KItemListAccessibleCell::setText(QAccessible::Text, int child, const QString&) +{ + Q_ASSERT(child == 0); +} + +bool KItemListAccessibleCell::isValid() const +{ + return m_view && (m_index >= 0) && (m_index < m_view->model()->count()); +} + +int KItemListAccessibleCell::childAt(int, int) const +{ + return 0; +} + +int KItemListAccessibleCell::childCount() const +{ + return 0; +} + +int KItemListAccessibleCell::indexOfChild(const QAccessibleInterface* child) const +{ + Q_UNUSED(child); + return -1; +} + +int KItemListAccessibleCell::navigate(RelationFlag relation, int index, QAccessibleInterface** interface) const +{ + if (relation == Ancestor && index == 1) { + *interface = new KItemListViewAccessible(m_view); + return 0; + } + + *interface = 0; + return -1; +} + +QAccessible::Relation KItemListAccessibleCell::relationTo(int child, const QAccessibleInterface* , int otherChild) const +{ + Q_ASSERT(child == 0); + Q_ASSERT(otherChild == 0); + return QAccessible::Unrelated; +} + +#ifndef QT_NO_ACTION + +int KItemListAccessibleCell::userActionCount(int) const +{ + return 0; +} + +QString KItemListAccessibleCell::actionText(int, Text, int) const +{ + return QString(); +} + +bool KItemListAccessibleCell::doAction(int, int, const QVariantList&) +{ + return false; +} + +#endif + +int KItemListAccessibleCell::index() const +{ + return m_index; +} + +QObject* KItemListAccessibleCell::object() const +{ + return 0; +} + +// Container Interface +KItemListContainerAccessible::KItemListContainerAccessible(KItemListContainer* container) : + QAccessibleWidgetEx(container) +{ +} + +KItemListContainerAccessible::~KItemListContainerAccessible() +{ +} + +int KItemListContainerAccessible::childCount() const +{ + return 1; +} + +int KItemListContainerAccessible::indexOfChild(const QAccessibleInterface* child) const +{ + if (child->object() == container()->controller()->view()) { + return 1; + } else { + return -1; + } +} + +int KItemListContainerAccessible::navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface** target) const +{ + if (relation == QAccessible::Child) { + *target = new KItemListViewAccessible(container()->controller()->view()); + return 0; + } else { + return QAccessibleWidgetEx::navigate(relation, index, target); + } +} + +const KItemListContainer* KItemListContainerAccessible::container() const +{ + return qobject_cast<KItemListContainer*>(object()); +} + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/kitemviews/kitemlistviewaccessible.h b/src/kitemviews/kitemlistviewaccessible.h new file mode 100644 index 000000000..c2213cd67 --- /dev/null +++ b/src/kitemviews/kitemlistviewaccessible.h @@ -0,0 +1,163 @@ +/*************************************************************************** + * Copyright (C) 2012 by Amandeep Singh <[email protected]> * + * * + * 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 program 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 program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef KITEMLISTVIEWACCESSIBLE_H +#define KITEMLISTVIEWACCESSIBLE_H + +#ifndef QT_NO_ACCESSIBILITY + +#include <QtCore/qpointer.h> +#include <QtGui/qaccessible.h> +#include <QtGui/qaccessible2.h> +#include <QtGui/qaccessiblewidget.h> +#include <QtGui/qaccessibleobject.h> + +class KItemListView; +class KItemListContainer; + +class KItemListViewAccessible: public QAccessibleTable2Interface, public QAccessibleObjectEx +{ + Q_ACCESSIBLE_OBJECT + +public: + explicit KItemListViewAccessible(KItemListView* view); + + Role role(int child) const; + State state(int child) const; + QString text(Text t, int child) const; + QRect rect(int child) const; + + int childAt(int x, int y) const; + int childCount() const; + int indexOfChild(const QAccessibleInterface*) const; + + int navigate(RelationFlag relation, int index, QAccessibleInterface** interface) const; + Relation relationTo(int child, const QAccessibleInterface* other, int otherChild) const; + +#ifndef QT_NO_ACTION + int userActionCount(int child) const; + QString actionText(int action, Text t, int child) const; + bool doAction(int action, int child, const QVariantList& params); +#endif + QVariant invokeMethodEx(Method, int, const QVariantList&); + + // Table2 interface + virtual QAccessibleTable2CellInterface* cellAt(int row, int column) const; + virtual QAccessibleInterface* caption() const; + virtual QAccessibleInterface* summary() const; + virtual QString columnDescription(int column) const; + virtual QString rowDescription(int row) const; + virtual int columnCount() const; + virtual int rowCount() const; + virtual QAccessible2::TableModelChange modelChange() const; + virtual void rowsInserted(const QModelIndex&, int, int) {} + virtual void rowsRemoved(const QModelIndex&, int, int) {} + virtual void columnsInserted(const QModelIndex&, int, int) {} + virtual void columnsRemoved(const QModelIndex&, int, int) {} + virtual void rowsMoved(const QModelIndex&, int, int, const QModelIndex&, int) {} + virtual void columnsMoved(const QModelIndex&, int, int, const QModelIndex&, int) {} + + // Selection + virtual int selectedCellCount() const; + virtual int selectedColumnCount() const; + virtual int selectedRowCount() const; + virtual QList<QAccessibleTable2CellInterface*> selectedCells() const; + virtual QList<int> selectedColumns() const; + virtual QList<int> selectedRows() const; + virtual bool isColumnSelected(int column) const; + virtual bool isRowSelected(int row) const; + virtual bool selectRow(int row); + virtual bool selectColumn(int column); + virtual bool unselectRow(int row); + virtual bool unselectColumn(int column); + + KItemListView* view() const; + +protected: + virtual void modelReset(); + /** + * Create an QAccessibleTable2CellInterface representing the table + * cell at the @index. Index is 0-based. + */ + inline QAccessibleTable2CellInterface* cell(int index) const; + inline QAccessible::Role cellRole() const; +}; + +class KItemListAccessibleCell: public QAccessibleTable2CellInterface +{ +public: + KItemListAccessibleCell(KItemListView* view, int m_index); + + QObject* object() const; + Role role(int) const; + State state(int) const; + QRect rect(int) const; + bool isValid() const; + int childAt(int, int) const; + int childCount() const; + int indexOfChild(const QAccessibleInterface*) const; + QString text(Text t, int child) const; + void setText(Text t, int child, const QString& text); + int navigate(RelationFlag relation, int m_index, QAccessibleInterface** interface) const; + Relation relationTo(int child, const QAccessibleInterface* other, int otherChild) const; + bool isExpandable() const; + +#ifndef QT_NO_ACTION + int userActionCount(int child) const; + QString actionText(int action, Text t, int child) const; + bool doAction(int action, int child, const QVariantList& params); +#endif + + // Cell Interface + virtual int columnExtent() const; + virtual QList<QAccessibleInterface*> columnHeaderCells() const; + virtual int columnIndex() const; + virtual int rowExtent() const; + virtual QList<QAccessibleInterface*> rowHeaderCells() const; + virtual int rowIndex() const; + virtual bool isSelected() const; + virtual void rowColumnExtents(int* row, int* column, int* rowExtents, int* columnExtents, bool* selected) const; + virtual QAccessibleTable2Interface* table() const; + + inline int index() const; + +private: + QPointer<KItemListView> m_view; + int m_index; +}; + +class KItemListContainerAccessible : public QAccessibleWidgetEx +{ + Q_ACCESSIBLE_OBJECT + +public: + explicit KItemListContainerAccessible(KItemListContainer* container); + virtual ~KItemListContainerAccessible(); + + int childCount() const; + int indexOfChild(const QAccessibleInterface* child) const; + int navigate(RelationFlag relation, int entry, QAccessibleInterface** target) const; + +private: + const KItemListContainer* container() const; +}; + +#endif // QT_NO_ACCESSIBILITY + +#endif diff --git a/src/kitemviews/private/kitemlistviewlayouter.h b/src/kitemviews/private/kitemlistviewlayouter.h index da5bd1d7d..5ca73e1ad 100644 --- a/src/kitemviews/private/kitemlistviewlayouter.h +++ b/src/kitemviews/private/kitemlistviewlayouter.h @@ -164,6 +164,11 @@ public: */ void markAsDirty(); + inline int columnCount() const + { + return m_columnCount; + } + #ifndef QT_NO_DEBUG /** * @return True if the layouter has been marked as dirty and hence has diff --git a/src/main.cpp b/src/main.cpp index 39ecee8b8..cfaaa7480 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,14 +36,14 @@ KDE_EXPORT int kdemain(int argc, char **argv) "2.1", ki18nc("@title", "File Manager"), KAboutData::License_GPL, - ki18nc("@info:credit", "(C) 2006-2012 Peter Penz")); + ki18nc("@info:credit", "(C) 2006-2012 Peter Penz and Frank Reininghaus")); about.setHomepage("http://dolphin.kde.org"); - about.addAuthor(ki18nc("@info:credit", "Peter Penz"), - ki18nc("@info:credit", "Maintainer and developer"), - "[email protected]"); about.addAuthor(ki18nc("@info:credit", "Frank Reininghaus"), - ki18nc("@info:credit", "Developer"), + ki18nc("@info:credit", "Maintainer (since 2012) and developer"), + about.addAuthor(ki18nc("@info:credit", "Peter Penz"), + ki18nc("@info:credit", "Maintainer and developer (2006-2012)"), + "[email protected]"); about.addAuthor(ki18nc("@info:credit", "Sebastian Trüg"), ki18nc("@info:credit", "Developer"), diff --git a/src/panels/panel.cpp b/src/panels/panel.cpp index c2681ecfb..14b7c0230 100644 --- a/src/panels/panel.cpp +++ b/src/panels/panel.cpp @@ -71,4 +71,9 @@ void Panel::setUrl(const KUrl& url) } } +void Panel::readSettings() +{ + +} + #include "panel.moc" diff --git a/src/panels/panel.h b/src/panels/panel.h index 064e1f362..a0b25d6cc 100644 --- a/src/panels/panel.h +++ b/src/panels/panel.h @@ -60,6 +60,11 @@ public slots: */ void setUrl(const KUrl& url); + /** + * Refreshes the view to get synchronized with the settings. + */ + virtual void readSettings(); + protected: /** * Must be implemented by derived classes and is invoked when diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp index a81b99770..3c7f2bb9b 100644 --- a/src/panels/places/placespanel.cpp +++ b/src/panels/places/placespanel.cpp @@ -23,6 +23,8 @@ #include "placespanel.h" +#include "dolphin_generalsettings.h" + #include <KDebug> #include <KDirNotify> #include <KIcon> @@ -78,6 +80,14 @@ bool PlacesPanel::urlChanged() return true; } +void PlacesPanel::readSettings() +{ + if (m_controller) { + const int delay = GeneralSettings::autoExpandFolders() ? 750 : -1; + m_controller->setAutoActivationDelay(delay); + } +} + void PlacesPanel::showEvent(QShowEvent* event) { if (event->spontaneous()) { @@ -101,6 +111,9 @@ void PlacesPanel::showEvent(QShowEvent* event) m_controller = new KItemListController(m_model, view, this); m_controller->setSelectionBehavior(KItemListController::SingleSelection); m_controller->setSingleClickActivation(true); + + readSettings(); + connect(m_controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int))); connect(m_controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int))); connect(m_controller, SIGNAL(itemContextMenuRequested(int,QPointF)), this, SLOT(slotItemContextMenuRequested(int,QPointF))); diff --git a/src/panels/places/placespanel.h b/src/panels/places/placespanel.h index 989a0916b..7951cdd9c 100644 --- a/src/panels/places/placespanel.h +++ b/src/panels/places/placespanel.h @@ -50,6 +50,9 @@ protected: virtual bool urlChanged(); virtual void showEvent(QShowEvent* event); +public slots: + virtual void readSettings(); + private slots: void slotItemActivated(int index); void slotItemMiddleClicked(int index); diff --git a/src/search/dolphinsearchbox.cpp b/src/search/dolphinsearchbox.cpp index 28f1f1af5..6f1c736b0 100644 --- a/src/search/dolphinsearchbox.cpp +++ b/src/search/dolphinsearchbox.cpp @@ -239,10 +239,9 @@ void DolphinSearchBox::slotReturnPressed(const QString& text) void DolphinSearchBox::slotFacetsButtonToggled() { - const bool visible = !m_facetsWidget->isVisible(); - m_facetsWidget->setVisible(visible); - SearchSettings::setShowFacetsWidget(visible); - updateFacetsToggleButtonIcon(); + const bool facetsIsVisible = !m_facetsWidget->isVisible(); + m_facetsWidget->setVisible(facetsIsVisible); + updateFacetsToggleButton(); } void DolphinSearchBox::slotFacetChanged() @@ -281,6 +280,7 @@ void DolphinSearchBox::saveSettings() { SearchSettings::setLocation(m_fromHereButton->isChecked() ? "FromHere" : "Everywhere"); SearchSettings::setWhat(m_fileNameButton->isChecked() ? "FileName" : "Content"); + SearchSettings::setShowFacetsWidget(m_facetsToggleButton->isChecked()); SearchSettings::self()->writeConfig(); } @@ -343,7 +343,8 @@ void DolphinSearchBox::init() // Create "Facets" widgets m_facetsToggleButton = new QToolButton(this); - m_facetsToggleButton->setAutoRaise(true); + m_facetsToggleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + initButton(m_facetsToggleButton); connect(m_facetsToggleButton, SIGNAL(clicked()), this, SLOT(slotFacetsButtonToggled())); m_facetsWidget = new DolphinFacetsWidget(this); @@ -390,7 +391,7 @@ void DolphinSearchBox::init() m_startSearchTimer->setInterval(1000); connect(m_startSearchTimer, SIGNAL(timeout()), this, SLOT(emitSearchRequest())); - updateFacetsToggleButtonIcon(); + updateFacetsToggleButton(); applyReadOnlyState(); } @@ -467,10 +468,12 @@ void DolphinSearchBox::applyReadOnlyState() } } -void DolphinSearchBox::updateFacetsToggleButtonIcon() +void DolphinSearchBox::updateFacetsToggleButton() { - const bool visible = SearchSettings::showFacetsWidget(); - m_facetsToggleButton->setIcon(KIcon(visible ? "list-remove" : "list-add")); + const bool facetsIsVisible = SearchSettings::showFacetsWidget(); + m_facetsToggleButton->setChecked(facetsIsVisible ? true : false); + m_facetsToggleButton->setIcon(KIcon(facetsIsVisible ? "arrow-up-double" : "arrow-down-double")); + m_facetsToggleButton->setText(facetsIsVisible ? i18nc("action:button", "Less Options") : i18nc("action:button", "More Options")); } #include "dolphinsearchbox.moc" diff --git a/src/search/dolphinsearchbox.h b/src/search/dolphinsearchbox.h index ee9987a38..f3cc535d6 100644 --- a/src/search/dolphinsearchbox.h +++ b/src/search/dolphinsearchbox.h @@ -133,8 +133,7 @@ private: void applyReadOnlyState(); - void updateFacetsToggleButtonIcon(); - + void updateFacetsToggleButton(); private: bool m_startedSearching; bool m_readOnly; diff --git a/src/settings/startup/startupsettingspage.cpp b/src/settings/startup/startupsettingspage.cpp index 43c176560..633cdacad 100644 --- a/src/settings/startup/startupsettingspage.cpp +++ b/src/settings/startup/startupsettingspage.cpp @@ -65,6 +65,11 @@ StartupSettingsPage::StartupSettingsPage(const KUrl& url, QWidget* parent) : m_homeUrl->setClearButtonShown(true); QPushButton* selectHomeUrlButton = new QPushButton(KIcon("folder-open"), QString(), homeUrlBox); + +#ifndef QT_NO_ACCESSIBILITY + selectHomeUrlButton->setAccessibleName(i18nc("@action:button", "Select Home Location")); +#endif + connect(selectHomeUrlButton, SIGNAL(clicked()), this, SLOT(selectHomeUrl())); diff --git a/src/statusbar/dolphinstatusbar.cpp b/src/statusbar/dolphinstatusbar.cpp index c19c0fe52..068b6325a 100644 --- a/src/statusbar/dolphinstatusbar.cpp +++ b/src/statusbar/dolphinstatusbar.cpp @@ -66,7 +66,8 @@ DolphinStatusBar::DolphinStatusBar(QWidget* parent) : // Initialize zoom widget m_zoomSlider = new QSlider(Qt::Horizontal, this); - m_zoomSlider->setAccessibleName(i18n("Zoom slider")); + m_zoomSlider->setAccessibleName(i18n("Zoom")); + m_zoomSlider->setAccessibleDescription(i18nc("Description for zoom-slider (accessibility)", "Sets the size of the file icons.")); m_zoomSlider->setPageStep(1); m_zoomSlider->setRange(ZoomLevelInfo::minimumLevel(), ZoomLevelInfo::maximumLevel()); diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 3f906d187..e1202ec12 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -20,6 +20,7 @@ set(kitemlistcontrollertest_SRCS ../kitemviews/kfileitemlistview.cpp ../kitemviews/kitemmodelbase.cpp ../kitemviews/kitemlistview.cpp + ../kitemviews/kitemlistviewaccessible.cpp ) kde4_add_unit_test(kitemlistcontrollertest TEST ${kitemlistcontrollertest_SRCS}) target_link_libraries(kitemlistcontrollertest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) @@ -32,6 +33,7 @@ set(kfileitemlistviewtest_SRCS ../kitemviews/kfileitemlistview.cpp ../kitemviews/kitemmodelbase.cpp ../kitemviews/kitemlistview.cpp + ../kitemviews/kitemlistviewaccessible.cpp ) kde4_add_unit_test(kfileitemlistviewtest TEST ${kfileitemlistviewtest_SRCS}) target_link_libraries(kfileitemlistviewtest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index f0dc3caba..05849729f 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -792,6 +792,14 @@ void DolphinView::slotItemsActivated(const QSet<int>& indexes) items.append(m_model->fileItem(index)); } + if (items.count() > 5) { + QString question = QString("Are you sure you want to open %1 items?").arg(items.count()); + const int answer = KMessageBox::warningYesNo(this, question); + if (answer != KMessageBox::Yes) { + return; + } + } + foreach (const KFileItem& item, items) { if (item.isDir()) { emit tabRequested(item.url()); |
