diff options
Diffstat (limited to 'src')
50 files changed, 1492 insertions, 2563 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b2cdfd582..f5a6c3ed9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,8 @@ add_subdirectory( pics ) add_subdirectory( tests ) +macro_optional_find_package(Soprano) + include_directories( ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${BLITZ_INCLUDES} ) if (Soprano_FOUND) include_directories( ${SOPRANO_INCLUDE_DIR} ) @@ -15,19 +17,20 @@ set(dolphinprivate_LIB_SRCS dolphiniconsview.cpp dolphincolumnview.cpp dolphincolumnwidget.cpp + dolphindropcontroller.cpp + dolphinsortfilterproxymodel.cpp draganddrophelper.cpp - kcategorizedview.cpp - kcategorydrawer.cpp dolphinmodel.cpp dolphinsettings.cpp dolphincategorydrawer.cpp - viewproperties.cpp - dolphinsortfilterproxymodel.cpp - renamedialog.cpp dolphinview.cpp dolphinviewactionhandler.cpp + iconmanager.cpp ratingpainter.cpp - dolphindropcontroller.cpp + renamedialog.cpp + selectiontoggle.cpp + selectionmanager.cpp + viewproperties.cpp ) kde4_add_kcfg_files(dolphinprivate_LIB_SRCS @@ -88,6 +91,7 @@ set(dolphin_SRCS dolphinstatusbar.cpp dolphindirlister.cpp dolphincontextmenu.cpp + dolphinfileplacesview.cpp dolphinsettingsdialog.cpp draganddrophelper.cpp filterbar.cpp @@ -101,6 +105,7 @@ set(dolphin_SRCS pixmapviewer.cpp settingspagebase.cpp sidebarpage.cpp + startupsettingspage.cpp statusbarspaceinfo.cpp statusbarmessagelabel.cpp terminalsidebarpage.cpp diff --git a/src/dolphin.desktop b/src/dolphin.desktop index 7bd80e9ab..f640ee49b 100644 --- a/src/dolphin.desktop +++ b/src/dolphin.desktop @@ -2,6 +2,7 @@ Name=Dolphin Name[ar]=الدولفين Name[hi]=डॉल्फ़िन +Name[kn]=ಡಾಲ್ಫಿನ್ Name[ne]=डल्फिन Name[pa]=ਡਾਲਫਿਨ Name[sr]=Делфин @@ -22,6 +23,7 @@ GenericName[csb]=Menadżer lopków GenericName[da]=Filhåndtering GenericName[de]=Dateimanager GenericName[el]=Διαχειριστής αρχείων +GenericName[eo]=Dosieradministrilo GenericName[es]=Gestor de archivos GenericName[et]=Failihaldur GenericName[eu]=Fitxategi kudeatzailea @@ -39,6 +41,7 @@ GenericName[it]=Gestione file GenericName[ja]=ファイルマネージャ GenericName[kk]=Файл менеджері GenericName[km]=កម្មវិធីគ្រប់គ្រងឯកសារ +GenericName[kn]=ಕಡತ ವ್ಯವಸ್ಥಾಪಕ GenericName[ko]=파일 관리자 GenericName[ku]=Rêveberê Pelan GenericName[lv]=Failu pārvaldnieks @@ -52,6 +55,7 @@ GenericName[pa]=ਫਾਇਲ ਮੈਨੇਜਰ GenericName[pl]=Menedżer plików GenericName[pt]=Gestor de Ficheiros GenericName[pt_BR]=Gerenciador de Arquivos +GenericName[ro]=Manager de fişiere GenericName[ru]=Файловый менеджер GenericName[se]=Fiilagieđahalli GenericName[sl]=Upravitelj datotek diff --git a/src/dolphin_generalsettings.kcfg b/src/dolphin_generalsettings.kcfg index 19474065a..6149480b3 100644 --- a/src/dolphin_generalsettings.kcfg +++ b/src/dolphin_generalsettings.kcfg @@ -27,6 +27,14 @@ <label context="@label">Should the view properties used for all directories</label> <default>false</default> </entry> + <entry name="BrowseThroughArchives" type="Bool"> + <label context="@label">Browse through archives</label> + <default>false</default> + </entry> + <entry name="ShowSelectionToggle" type="Bool"> + <label context="@label">Show selection toggle</label> + <default>true</default> + </entry> <entry name="ViewPropsTimestamp" type="DateTime" > <label context="@label">Timestamp since when the view properties are valid</label> </entry> diff --git a/src/dolphincategorydrawer.cpp b/src/dolphincategorydrawer.cpp index 8148a7b8e..6cf84560f 100644 --- a/src/dolphincategorydrawer.cpp +++ b/src/dolphincategorydrawer.cpp @@ -50,6 +50,8 @@ DolphinCategoryDrawer::~DolphinCategoryDrawer() void DolphinCategoryDrawer::drawCategory(const QModelIndex &index, int sortRole, const QStyleOption &option, QPainter *painter) const { + Q_UNUSED(sortRole); + QRect starRect = option.rect; int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small); diff --git a/src/dolphincategorydrawer.h b/src/dolphincategorydrawer.h index ea70a922b..1cccc620e 100644 --- a/src/dolphincategorydrawer.h +++ b/src/dolphincategorydrawer.h @@ -21,7 +21,7 @@ #ifndef DOLPHINCATEGORYDRAWER_H #define DOLPHINCATEGORYDRAWER_H -#include "kcategorydrawer.h" +#include <kcategorydrawer.h> #include <QStyleOption> #include <QModelIndex> diff --git a/src/dolphincolumnview.cpp b/src/dolphincolumnview.cpp index bfbc5d9f1..7e74b7e34 100644 --- a/src/dolphincolumnview.cpp +++ b/src/dolphincolumnview.cpp @@ -370,11 +370,13 @@ void DolphinColumnView::updateDecorationSize() { ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings(); const int iconSize = settings->iconSize(); + const QSize size(iconSize, iconSize); + setIconSize(size); foreach (QObject* object, viewport()->children()) { if (object->inherits("QListView")) { DolphinColumnWidget* widget = static_cast<DolphinColumnWidget*>(object); - widget->setDecorationSize(QSize(iconSize, iconSize)); + widget->setDecorationSize(size); } } @@ -393,8 +395,12 @@ void DolphinColumnView::updateColumnsBackground(bool active) m_active = active; // dim the background of the viewport - QPalette palette; - palette.setColor(viewport()->backgroundRole(), QColor(0, 0, 0, 0)); + const QPalette::ColorRole role = viewport()->backgroundRole(); + QColor background = viewport()->palette().color(role); + background.setAlpha(0); // make background transparent + + QPalette palette = viewport()->palette(); + palette.setColor(role, background); viewport()->setPalette(palette); foreach (DolphinColumnWidget* column, m_columns) { @@ -503,8 +509,9 @@ void DolphinColumnView::assureVisibleActiveColumn() } else { m_animation->setFrameRange(-m_contentX, -newContentX); } - if(m_animation->state() != QTimeLine::Running) + if (m_animation->state() != QTimeLine::Running) { m_animation->start(); + } } else if (x < 0) { const int newContentX = m_contentX - x; if (isRightToLeft()) { @@ -512,8 +519,9 @@ void DolphinColumnView::assureVisibleActiveColumn() } else { m_animation->setFrameRange(-m_contentX, -newContentX); } - if(m_animation->state() != QTimeLine::Running) + if (m_animation->state() != QTimeLine::Running) { m_animation->start(); + } } } diff --git a/src/dolphincolumnwidget.cpp b/src/dolphincolumnwidget.cpp index 7cff99398..c2ba385ad 100644 --- a/src/dolphincolumnwidget.cpp +++ b/src/dolphincolumnwidget.cpp @@ -26,7 +26,9 @@ #include "dolphinsortfilterproxymodel.h" #include "dolphinsettings.h" #include "dolphin_columnmodesettings.h" +#include "dolphin_generalsettings.h" #include "draganddrophelper.h" +#include "selectionmanager.h" #include <kcolorscheme.h> #include <kdirlister.h> @@ -37,6 +39,8 @@ #include <kmimetyperesolver.h> #include <konqmimedata.h> +#include "iconmanager.h" + #include <QApplication> #include <QClipboard> #include <QPainter> @@ -47,7 +51,6 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent, const KUrl& url) : QListView(parent), m_active(true), - m_showPreview(false), m_view(columnView), m_url(url), m_childUrl(), @@ -56,7 +59,7 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent, m_dirLister(0), m_dolphinModel(0), m_proxyModel(0), - m_previewJob(0), + m_iconManager(0), m_dragging(false), m_dropRect() { @@ -88,7 +91,7 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent, m_font.setBold(settings->boldFont()); const int iconSize = settings->iconSize(); - m_decorationSize = QSize(iconSize, iconSize); + setDecorationSize(QSize(iconSize, iconSize)); KFileItemDelegate* delegate = new KFileItemDelegate(this); setItemDelegate(delegate); @@ -107,8 +110,6 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent, m_dirLister->setDelayedMimeTypes(true); const bool showHiddenFiles = m_view->m_controller->dolphinView()->showHiddenFiles(); m_dirLister->setShowingDotFiles(showHiddenFiles); - connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)), - this, SLOT(generatePreviews(const KFileItemList&))); m_dolphinModel = new DolphinModel(this); m_dolphinModel->setDirLister(m_dirLister); @@ -119,7 +120,18 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent, m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); setModel(m_proxyModel); + const bool useSelManager = KGlobalSettings::singleClick() && + DolphinSettings::instance().generalSettings()->showSelectionToggle(); + if (useSelManager) { + SelectionManager* selManager = new SelectionManager(this); + connect(selManager, SIGNAL(selectionChanged()), + this, SLOT(requestActivation())); + connect(m_view->m_controller, SIGNAL(urlChanged(const KUrl&)), + selManager, SLOT(reset())); +} new KMimeTypeResolver(this, m_dolphinModel); + m_iconManager = new IconManager(this, m_proxyModel); + m_iconManager->setShowPreview(m_view->m_controller->dolphinView()->showPreview()); m_dirLister->openUrl(url, KDirLister::NoFlags); } @@ -131,15 +143,11 @@ DolphinColumnWidget::~DolphinColumnWidget() delete m_dolphinModel; m_dolphinModel = 0; m_dirLister = 0; // deleted by m_dolphinModel - - if (m_previewJob != 0) { - m_previewJob->kill(); - m_previewJob = 0; - } } void DolphinColumnWidget::setDecorationSize(const QSize& size) { + setIconSize(size); m_decorationSize = size; doItemsLayout(); } @@ -176,20 +184,24 @@ void DolphinColumnWidget::setShowHiddenFiles(bool show) void DolphinColumnWidget::setShowPreview(bool show) { - if (show != m_showPreview) { - m_dirLister->stop(); - m_dirLister->openUrl(m_url, KDirLister::Reload); - } + m_iconManager->setShowPreview(show); + + m_dirLister->stop(); + m_dirLister->openUrl(m_url, KDirLister::Reload); } void DolphinColumnWidget::updateBackground() { - QColor color = KColorScheme(QPalette::Active, KColorScheme::View).background().color(); - if (!m_active || !m_view->m_active) { - color.setAlpha(150); - } + // TODO: The alpha-value 150 is copied from DolphinView::setActive(). When + // cleaning up the cut-indication of DolphinColumnWidget with the code from + // DolphinView a common helper-class should be available which can be shared + // by all view implementations -> no hardcoded value anymore + const QPalette::ColorRole role = viewport()->backgroundRole(); + QColor color = viewport()->palette().color(role); + color.setAlpha((m_active && m_view->m_active) ? 255 : 150); + QPalette palette = viewport()->palette(); - palette.setColor(viewport()->backgroundRole(), color); + palette.setColor(role, color); viewport()->setPalette(palette); update(); @@ -303,12 +315,7 @@ void DolphinColumnWidget::paintEvent(QPaintEvent* event) void DolphinColumnWidget::mousePressEvent(QMouseEvent* event) { - m_view->m_controller->requestActivation(); - if (!m_active) { - m_view->requestActivation(this); - m_view->m_controller->triggerUrlChangeRequest(m_url); - } - + requestActivation(); QListView::mousePressEvent(event); } @@ -359,51 +366,6 @@ void DolphinColumnWidget::triggerItem(const QModelIndex& index) m_view->m_controller->triggerItem(item); } -void DolphinColumnWidget::generatePreviews(const KFileItemList& items) -{ - // TODO: same implementation as in DolphinView; create helper class - // for generatePreviews(), showPreview() and isCutItem() - - if (m_view->m_controller->dolphinView()->showPreview()) { - if (m_previewJob != 0) { - m_previewJob->kill(); - m_previewJob = 0; - } - - m_previewJob = KIO::filePreview(items, 128); - connect(m_previewJob, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)), - this, SLOT(replaceIcon(const KFileItem&, const QPixmap&))); - connect(m_previewJob, SIGNAL(finished(KJob*)), - this, SLOT(slotPreviewJobFinished(KJob*))); - } -} - -void DolphinColumnWidget::replaceIcon(const KFileItem& item, const QPixmap& pixmap) -{ - // TODO: same implementation as in DolphinView; create helper class - // for generatePreviews(), showPreview() and isCutItem() - - Q_ASSERT(!item.isNull()); - const bool showPreview = m_view->m_controller->dolphinView()->showPreview(); - if (!showPreview || (item.url().directory() != m_dirLister->url().path())) { - // the preview job is still working on items of an older URL, hence - // the item is not part of the directory model anymore - return; - } - - const QModelIndex idx = m_dolphinModel->indexForItem(item); - if (idx.isValid() && (idx.column() == 0)) { - const QMimeData* mimeData = QApplication::clipboard()->mimeData(); - if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) { - KIconEffect iconEffect; - const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState); - m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole); - } else { - m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole); - } - } -} - void DolphinColumnWidget::slotEntered(const QModelIndex& index) { const QModelIndex dirIndex = m_proxyModel->mapToSource(index); @@ -411,10 +373,14 @@ void DolphinColumnWidget::slotEntered(const QModelIndex& index) m_view->m_controller->emitItemEntered(item); } -void DolphinColumnWidget::slotPreviewJobFinished(KJob* job) +void DolphinColumnWidget::requestActivation() { - Q_ASSERT(job == m_previewJob); - m_previewJob = 0; + m_view->m_controller->requestActivation(); + if (!m_active) { + m_view->requestActivation(this); + m_view->m_controller->triggerUrlChangeRequest(m_url); + selectionModel()->clear(); + } } void DolphinColumnWidget::activate() @@ -432,6 +398,9 @@ void DolphinColumnWidget::activate() this, SLOT(triggerItem(const QModelIndex&))); } + if (selectionModel() && selectionModel()->currentIndex().isValid()) + selectionModel()->setCurrentIndex(selectionModel()->currentIndex(), QItemSelectionModel::SelectCurrent); + updateBackground(); } @@ -450,31 +419,12 @@ void DolphinColumnWidget::deactivate() this, SLOT(triggerItem(const QModelIndex&))); } + const QModelIndex current = selectionModel()->currentIndex(); selectionModel()->clear(); + selectionModel()->setCurrentIndex(current, QItemSelectionModel::NoUpdate); updateBackground(); } -bool DolphinColumnWidget::isCutItem(const KFileItem& item) const -{ - // TODO: same implementation as in DolphinView; create helper class - // for generatePreviews(), showPreview() and isCutItem() - - const QMimeData* mimeData = QApplication::clipboard()->mimeData(); - const KUrl::List cutUrls = KUrl::List::fromMimeData(mimeData); - - const KUrl& itemUrl = item.url(); - KUrl::List::const_iterator it = cutUrls.begin(); - const KUrl::List::const_iterator end = cutUrls.end(); - while (it != end) { - if (*it == itemUrl) { - return true; - } - ++it; - } - - return false; -} - KFileItem DolphinColumnWidget::itemForIndex(const QModelIndex& index) const { const QModelIndex dirIndex = m_proxyModel->mapToSource(index); diff --git a/src/dolphincolumnwidget.h b/src/dolphincolumnwidget.h index 870246269..87c7ab577 100644 --- a/src/dolphincolumnwidget.h +++ b/src/dolphincolumnwidget.h @@ -30,15 +30,12 @@ class DolphinColumnView; class DolphinModel; class DolphinSortFilterProxyModel; +class IconManager; class KDirLister; class KJob; class KFileItem; class KFileItemList; class QPixmap; -namespace KIO -{ - class PreviewJob; -} /** * Represents one column inside the DolphinColumnView and has been @@ -118,26 +115,9 @@ private slots: */ void triggerItem(const QModelIndex& index); - /** - * Generates a preview image for each file item in \a items. - * The current preview settings (maximum size, 'Show Preview' menu) - * are respected. - */ - void generatePreviews(const KFileItemList& items); - - /** - * Replaces the icon of the item \a item by the preview pixmap - * \a pixmap. - */ - void replaceIcon(const KFileItem& item, const QPixmap& pixmap); - void slotEntered(const QModelIndex& index); - /** - * Is invoked when the preview job has been finished and - * set m_previewJob to 0. - */ - void slotPreviewJobFinished(KJob* job); + void requestActivation(); private: /** Used by DolphinColumnWidget::setActive(). */ @@ -146,17 +126,10 @@ private: /** Used by DolphinColumnWidget::setActive(). */ void deactivate(); - /** - * Returns true, if the item \a item has been cut into - * the clipboard. - */ - bool isCutItem(const KFileItem& item) const; - KFileItem itemForIndex(const QModelIndex& index) const; private: bool m_active; - bool m_showPreview; DolphinColumnView* m_view; KUrl m_url; // URL of the directory that is shown KUrl m_childUrl; // URL of the next column that is shown @@ -168,7 +141,7 @@ private: DolphinModel* m_dolphinModel; DolphinSortFilterProxyModel* m_proxyModel; - KIO::PreviewJob* m_previewJob; + IconManager* m_iconManager; bool m_dragging; // TODO: remove this property when the issue #160611 is solved in Qt 4.4 QRect m_dropRect; // TODO: remove this property when the issue #160611 is solved in Qt 4.4 diff --git a/src/dolphincontextmenu.cpp b/src/dolphincontextmenu.cpp index 601e5f141..2dcb916a5 100644 --- a/src/dolphincontextmenu.cpp +++ b/src/dolphincontextmenu.cpp @@ -230,7 +230,7 @@ void DolphinContextMenu::openViewportContextMenu() popup->addMenu(newMenu->menu()); popup->addSeparator(); - QAction* pasteAction = m_mainWindow->actionCollection()->action(KStandardAction::stdName(KStandardAction::Paste)); + QAction* pasteAction = m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Paste)); popup->addAction(pasteAction); // setup 'View Mode' menu @@ -279,9 +279,9 @@ void DolphinContextMenu::insertDefaultItemActions(KMenu* popup) const KActionCollection* collection = m_mainWindow->actionCollection(); // insert 'Cut', 'Copy' and 'Paste' - QAction* cutAction = collection->action(KStandardAction::stdName(KStandardAction::Cut)); - QAction* copyAction = collection->action(KStandardAction::stdName(KStandardAction::Copy)); - QAction* pasteAction = collection->action(KStandardAction::stdName(KStandardAction::Paste)); + QAction* cutAction = collection->action(KStandardAction::name(KStandardAction::Cut)); + QAction* copyAction = collection->action(KStandardAction::name(KStandardAction::Copy)); + QAction* pasteAction = collection->action(KStandardAction::name(KStandardAction::Paste)); popup->addAction(cutAction); popup->addAction(copyAction); diff --git a/src/dolphindetailsview.cpp b/src/dolphindetailsview.cpp index 2861c134f..3be22fb42 100644 --- a/src/dolphindetailsview.cpp +++ b/src/dolphindetailsview.cpp @@ -25,9 +25,11 @@ #include "dolphinsettings.h" #include "dolphinsortfilterproxymodel.h" #include "draganddrophelper.h" +#include "selectionmanager.h" #include "viewproperties.h" #include "dolphin_detailsmodesettings.h" +#include "dolphin_generalsettings.h" #include <kdirmodel.h> #include <klocale.h> @@ -43,6 +45,7 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* controller) : QTreeView(parent), + m_autoResize(true), m_controller(controller), m_font(), m_decorationSize(), @@ -76,6 +79,10 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr headerView->setContextMenuPolicy(Qt::CustomContextMenu); connect(headerView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(configureColumns(const QPoint&))); + connect(headerView, SIGNAL(sectionResized(int, int, int)), + this, SLOT(slotHeaderSectionResized(int, int, int))); + connect(headerView, SIGNAL(sectionHandleDoubleClicked(int)), + this, SLOT(disableAutoResizing())); connect(parent, SIGNAL(sortingChanged(DolphinView::Sorting)), this, SLOT(setSortIndicatorSection(DolphinView::Sorting))); @@ -89,6 +96,13 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr if (KGlobalSettings::singleClick()) { connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(triggerItem(const QModelIndex&))); + if (DolphinSettings::instance().generalSettings()->showSelectionToggle()) { + SelectionManager* selManager = new SelectionManager(this); + connect(selManager, SIGNAL(selectionChanged()), + this, SLOT(requestActivation())); + connect(m_controller, SIGNAL(urlChanged(const KUrl&)), + selManager, SLOT(reset())); + } } else { connect(this, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(triggerItem(const QModelIndex&))); @@ -345,13 +359,7 @@ void DolphinDetailsView::keyPressEvent(QKeyEvent* event) void DolphinDetailsView::resizeEvent(QResizeEvent* event) { QTreeView::resizeEvent(event); - - // TODO: There seems to be no easy way to find out whether the resize event - // has been triggered because of resizing the window or by adjusting the column-width - // by a left mouse-click (the columns should only be resized automatically when the window - // size is adjusted). The following workaround works well, but it should be - // considered solving this in a more transparent way. - if (!(QApplication::mouseButtons() & Qt::LeftButton)) { + if (m_autoResize) { resizeColumns(); } } @@ -494,6 +502,26 @@ void DolphinDetailsView::updateColumnVisibility() resizeColumns(); } +void DolphinDetailsView::slotHeaderSectionResized(int logicalIndex, int oldSize, int newSize) +{ + Q_UNUSED(logicalIndex); + Q_UNUSED(oldSize); + Q_UNUSED(newSize); + if (QApplication::mouseButtons() & Qt::LeftButton) { + disableAutoResizing(); + } +} + +void DolphinDetailsView::disableAutoResizing() +{ + m_autoResize = false; +} + +void DolphinDetailsView::requestActivation() +{ + m_controller->requestActivation(); +} + bool DolphinDetailsView::isZoomInPossible() const { DetailsModeSettings* settings = DolphinSettings::instance().detailsModeSettings(); @@ -510,6 +538,7 @@ void DolphinDetailsView::updateDecorationSize() { DetailsModeSettings* settings = DolphinSettings::instance().detailsModeSettings(); const int iconSize = settings->iconSize(); + setIconSize(QSize(iconSize, iconSize)); m_decorationSize = QSize(iconSize, iconSize); m_controller->setZoomInPossible(isZoomInPossible()); diff --git a/src/dolphindetailsview.h b/src/dolphindetailsview.h index 086121f7a..316620a5a 100644 --- a/src/dolphindetailsview.h +++ b/src/dolphindetailsview.h @@ -118,6 +118,20 @@ private slots: void updateColumnVisibility(); + /** + * Disables the automatical resizing of columns, if the user has resized the columns + * with the mouse. + */ + void slotHeaderSectionResized(int logicalIndex, int oldSize, int newSize); + + /** + * Disables the automatical resizing of the columns. Per default all columns + * are resized to use the maximum available width of the view as good as possible. + */ + void disableAutoResizing(); + + void requestActivation(); + private: bool isZoomInPossible() const; bool isZoomOutPossible() const; @@ -143,6 +157,8 @@ private: void resizeColumns(); private: + bool m_autoResize; // if true, the columns are resized automatically to the available width + DolphinController* m_controller; QFont m_font; diff --git a/src/dolphindropcontroller.cpp b/src/dolphindropcontroller.cpp index 002c242ac..d322c593d 100644 --- a/src/dolphindropcontroller.cpp +++ b/src/dolphindropcontroller.cpp @@ -45,24 +45,23 @@ void DolphinDropController::dropUrls(const KUrl::List& urls, kDebug() << "Source" << urls; kDebug() << "Destination:" << destination; + if (destination.protocol() == "trash") { + KonqOperations::del(m_parentWidget, KonqOperations::TRASH, urls); + return; + } + Qt::DropAction action = Qt::CopyAction; Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers(); const bool shiftPressed = modifier & Qt::ShiftModifier; const bool controlPressed = modifier & Qt::ControlModifier; const bool altPressed = modifier & Qt::AltModifier; - if (shiftPressed && controlPressed) { - // shortcut for 'Link Here' is used + if ((shiftPressed && controlPressed) || altPressed) { action = Qt::LinkAction; - } else if (shiftPressed) { - // shortcut for 'Move Here' is used - action = Qt::MoveAction; } else if (controlPressed) { - // shortcut for 'Copy Here' is used action = Qt::CopyAction; - } else if (altPressed) { - // shortcut for 'Link Here' is used - action = Qt::LinkAction; + } else if (shiftPressed) { + action = Qt::MoveAction; } else { // open a context menu which offers the following actions: // - Move Here diff --git a/src/dolphinfileplacesview.cpp b/src/dolphinfileplacesview.cpp new file mode 100644 index 000000000..5dacae633 --- /dev/null +++ b/src/dolphinfileplacesview.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 * + ***************************************************************************/ + +#include "dolphinfileplacesview.h" +#include "dolphindropcontroller.h" +#include <konq_operations.h> + +DolphinFilePlacesView::DolphinFilePlacesView(QWidget* parent) : + KFilePlacesView(parent) +{ + setDropOnPlaceEnabled(true); + connect(this, SIGNAL(urlsDropped(const KUrl&, QDropEvent*, QWidget*)), + this, SLOT(slotUrlsDropped(const KUrl&, QDropEvent*, QWidget*))); +} + +DolphinFilePlacesView::~DolphinFilePlacesView() +{ +} + +void DolphinFilePlacesView::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent) +{ + const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); + + DolphinDropController dropController(parent); + // forward doingOperation signal up to the mainwindow + connect(&dropController, SIGNAL(doingOperation(KonqFileUndoManager::CommandType)), + this, SIGNAL(doingOperation(KonqFileUndoManager::CommandType))); + dropController.dropUrls(urls, dest); +} + +#include "dolphinfileplacesview.moc" diff --git a/src/dolphinfileplacesview.h b/src/dolphinfileplacesview.h new file mode 100644 index 000000000..8bad0fa5f --- /dev/null +++ b/src/dolphinfileplacesview.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 DOLPHINFILEPLACESVIEW_H +#define DOLPHINFILEPLACESVIEW_H + +#include <kfileplacesview.h> + +/** + * @brief Combines bookmarks and mounted devices as list which is + * embedded as panel. + */ +class DolphinFilePlacesView : public KFilePlacesView +{ + Q_OBJECT + +public: + DolphinFilePlacesView(QWidget* parent); + virtual ~DolphinFilePlacesView(); + +private slots: + void slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent); +}; + +#endif // DOLPHINFILEPLACESVIEW_H diff --git a/src/dolphiniconsview.cpp b/src/dolphiniconsview.cpp index d3d485f1a..ccf12a737 100644 --- a/src/dolphiniconsview.cpp +++ b/src/dolphiniconsview.cpp @@ -23,7 +23,9 @@ #include "dolphincontroller.h" #include "dolphinsettings.h" #include "dolphin_iconsmodesettings.h" +#include "dolphin_generalsettings.h" #include "draganddrophelper.h" +#include "selectionmanager.h" #include <kcategorizedsortfilterproxymodel.h> #include <kdialog.h> @@ -33,6 +35,7 @@ #include <QApplication> #include <QPainter> #include <QPoint> +#include <QScrollBar> DolphinIconsView::DolphinIconsView(QWidget* parent, DolphinController* controller) : KCategorizedView(parent), @@ -64,6 +67,13 @@ DolphinIconsView::DolphinIconsView(QWidget* parent, DolphinController* controlle if (KGlobalSettings::singleClick()) { connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(triggerItem(const QModelIndex&))); + if (DolphinSettings::instance().generalSettings()->showSelectionToggle()) { + SelectionManager* selManager = new SelectionManager(this); + connect(selManager, SIGNAL(selectionChanged()), + this, SLOT(requestActivation())); + connect(m_controller, SIGNAL(urlChanged(const KUrl&)), + selManager, SLOT(reset())); + } } else { connect(this, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(triggerItem(const QModelIndex&))); @@ -285,6 +295,34 @@ void DolphinIconsView::keyPressEvent(QKeyEvent* event) } } +void DolphinIconsView::wheelEvent(QWheelEvent* event) +{ + KCategorizedView::wheelEvent(event); + + if ((event->modifiers() & Qt::ControlModifier) == Qt::ControlModifier) { + int d = event->delta(); + if (d > 0) { + zoomIn(); + } else if (d < 0) { + zoomOut(); + } + } else { + // if the icons are aligned left to right, the vertical wheel event should + // be applied to the horizontal scrollbar + const IconsModeSettings* settings = DolphinSettings::instance().iconsModeSettings(); + const bool scrollHorizontal = (event->orientation() == Qt::Vertical) && + (settings->arrangement() == QListView::LeftToRight); + if (scrollHorizontal) { + QWheelEvent horizEvent(event->pos(), + event->delta(), + event->buttons(), + event->modifiers(), + Qt::Horizontal); + QApplication::sendEvent(horizontalScrollBar(), &horizEvent); + } + } +} + void DolphinIconsView::triggerItem(const QModelIndex& index) { m_controller->triggerItem(itemForIndex(index)); @@ -369,6 +407,11 @@ void DolphinIconsView::zoomOut() } } +void DolphinIconsView::requestActivation() +{ + m_controller->requestActivation(); +} + bool DolphinIconsView::isZoomInPossible() const { IconsModeSettings* settings = DolphinSettings::instance().iconsModeSettings(); @@ -431,6 +474,7 @@ void DolphinIconsView::updateGridSize(bool showPreview, int additionalInfoCount) size = previewSize; } + setIconSize(QSize(size, size)); Q_ASSERT(additionalInfoCount >= 0); itemHeight += additionalInfoCount * m_font.pointSize() * 2; diff --git a/src/dolphiniconsview.h b/src/dolphiniconsview.h index af65bbda8..05b21a2b0 100644 --- a/src/dolphiniconsview.h +++ b/src/dolphiniconsview.h @@ -62,6 +62,7 @@ protected: virtual void dropEvent(QDropEvent* event); virtual void paintEvent(QPaintEvent* event); virtual void keyPressEvent(QKeyEvent* event); + virtual void wheelEvent(QWheelEvent* event); private slots: void triggerItem(const QModelIndex& index); @@ -70,6 +71,7 @@ private slots: void slotAdditionalInfoChanged(); void zoomIn(); void zoomOut(); + void requestActivation(); private: bool isZoomInPossible() const; diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index c1d6cef39..160c423ec 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -26,6 +26,7 @@ #include <config-nepomuk.h> #include "dolphinapplication.h" +#include "dolphinfileplacesview.h" #include "dolphinnewmenu.h" #include "dolphinsettings.h" #include "dolphinsettingsdialog.h" @@ -36,11 +37,8 @@ #include "mainwindowadaptor.h" #include "terminalsidebarpage.h" #include "treeviewsidebarpage.h" -#include "kurlnavigator.h" #include "viewpropertiesdialog.h" #include "viewproperties.h" -#include "kfileplacesmodel.h" -#include "kfileplacesview.h" #include "dolphin_generalsettings.h" #include "dolphin_iconsmodesettings.h" @@ -51,6 +49,7 @@ #include <kdesktopfile.h> #include <kdeversion.h> #include <kfiledialog.h> +#include <kfileplacesmodel.h> #include <kglobal.h> #include <kicon.h> #include <kiconloader.h> @@ -60,6 +59,7 @@ #include <kmenu.h> #include <kmenubar.h> #include <kmessagebox.h> +#include <kurlnavigator.h> #include <konqmimedata.h> #include <kpropertiesdialog.h> #include <kprotocolinfo.h> @@ -224,6 +224,13 @@ void DolphinMainWindow::slotSortingChanged(DolphinView::Sorting sorting) } } +void DolphinMainWindow::slotEditableStateChanged(bool editable) +{ + KToggleAction* editableLocationAction = + static_cast<KToggleAction*>(actionCollection()->action("editable_location")); + editableLocationAction->setChecked(editable); +} + void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection) { updateEditActions(); @@ -368,7 +375,7 @@ void DolphinMainWindow::slotHandlePlacesError(const QString &message) void DolphinMainWindow::slotUndoAvailable(bool available) { - QAction* undoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Undo)); + QAction* undoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Undo)); if (undoAction != 0) { undoAction->setEnabled(available); } @@ -412,7 +419,7 @@ void DolphinMainWindow::slotUndoAvailable(bool available) void DolphinMainWindow::slotUndoTextChanged(const QString& text) { - QAction* undoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Undo)); + QAction* undoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Undo)); if (undoAction != 0) { undoAction->setText(text); } @@ -441,7 +448,7 @@ void DolphinMainWindow::paste() void DolphinMainWindow::updatePasteAction() { - QAction* pasteAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Paste)); + QAction* pasteAction = actionCollection()->action(KStandardAction::name(KStandardAction::Paste)); if (pasteAction == 0) { return; } @@ -815,8 +822,8 @@ void DolphinMainWindow::setupActions() SLOT(undo()), actionCollection()); - //Need to remove shift+del from cut action, else the shortcut for deletejob - //doesn't work + // need to remove shift+del from cut action, else the shortcut for deletejob + // doesn't work KAction* cut = KStandardAction::cut(this, SLOT(cut()), actionCollection()); KShortcut cutShortcut = cut->shortcut(); cutShortcut.remove(Qt::SHIFT + Qt::Key_Delete, KShortcut::KeepEmpty); @@ -932,9 +939,7 @@ void DolphinMainWindow::setupActions() stop->setIcon(KIcon("process-stop")); connect(stop, SIGNAL(triggered()), this, SLOT(stopLoading())); - // TODO: the URL navigator must emit a signal if the editable state has been - // changed, so that the corresponding showFullLocation action is updated. Also - // the naming "Show full Location" is currently confusing... + // TODO: the naming "Show full Location" is currently confusing... KToggleAction* showFullLocation = actionCollection()->add<KToggleAction>("editable_location"); showFullLocation->setText(i18nc("@action:inmenu Navigation Bar", "Show Full Location")); showFullLocation->setShortcut(Qt::CTRL | Qt::Key_L); @@ -1051,7 +1056,8 @@ void DolphinMainWindow::setupDockWidgets() QDockWidget* placesDock = new QDockWidget(i18nc("@title:window", "Places")); placesDock->setObjectName("placesDock"); placesDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - KFilePlacesView* placesView = new KFilePlacesView(placesDock); + + DolphinFilePlacesView* placesView = new DolphinFilePlacesView(placesDock); placesDock->setWidget(placesView); placesView->setModel(DolphinSettings::instance().placesModel()); placesView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -1139,7 +1145,7 @@ void DolphinMainWindow::updateViewActions() void DolphinMainWindow::updateGoActions() { - QAction* goUpAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Up)); + QAction* goUpAction = actionCollection()->action(KStandardAction::name(KStandardAction::Up)); const KUrl& currentUrl = m_activeViewContainer->url(); goUpAction->setEnabled(currentUrl.upUrl() != currentUrl); } @@ -1174,6 +1180,8 @@ void DolphinMainWindow::connectViewSignals(int viewIndex) this, SLOT(changeUrl(const KUrl&))); connect(navigator, SIGNAL(historyChanged()), this, SLOT(slotHistoryChanged())); + connect(navigator, SIGNAL(editableStateChanged(bool)), + this, SLOT(slotEditableStateChanged(bool))); } void DolphinMainWindow::updateSplitAction() diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index b1694c323..bddeba7b1 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -271,7 +271,7 @@ private slots: void toggleFilterBarVisibility(bool show); /** - * Toggles between edit and brose mode of the navigation bar. + * Toggles between edit and browse mode of the navigation bar. */ void toggleEditLocation(); @@ -320,6 +320,9 @@ private slots: /** Updates the state of the 'Sort by' actions. */ void slotSortingChanged(DolphinView::Sorting sorting); + /** Updates the state of the 'Show Full Location' action. */ + void slotEditableStateChanged(bool editable); + /** * Updates the state of the 'Edit' menu actions and emits * the signal selectionChanged(). diff --git a/src/dolphinmodel.cpp b/src/dolphinmodel.cpp index 1b94e0339..b0e5ef5c4 100644 --- a/src/dolphinmodel.cpp +++ b/src/dolphinmodel.cpp @@ -137,8 +137,7 @@ QVariant DolphinModel::data(const QModelIndex &index, int role) const } case KDirModel::ModifiedTime: { - KDateTime modifiedTime; - modifiedTime.setTime_t(item.time(KIO::UDSEntry::UDS_MODIFICATION_TIME)); + KDateTime modifiedTime = item.time(KFileItem::ModificationTime); modifiedTime = modifiedTime.toLocalZone(); retString = modifiedTime.toString(i18nc("Prints out the month and year: %B is full month name in current locale, and %Y is full year number", "%B, %Y")); @@ -266,8 +265,7 @@ QVariant DolphinModel::data(const QModelIndex &index, int role) const } case KDirModel::ModifiedTime: { - KDateTime modifiedTime; - modifiedTime.setTime_t(item.time(KIO::UDSEntry::UDS_MODIFICATION_TIME)); + KDateTime modifiedTime = item.time(KFileItem::ModificationTime); modifiedTime = modifiedTime.toLocalZone(); retVariant = -(modifiedTime.date().year() * 100 + modifiedTime.date().month()); diff --git a/src/dolphinpart.desktop b/src/dolphinpart.desktop index a8b9217cc..1a139f1cd 100644 --- a/src/dolphinpart.desktop +++ b/src/dolphinpart.desktop @@ -9,6 +9,7 @@ Name[csb]=Dolphin - kòmpònenta Name[da]=Dolphin-Part Name[de]=Dolphin-Komponente Name[el]=Τμήμα Dolphin +Name[eo]=Komponanto de Dolphin Name[es]=Part Dolphin Name[et]=Dolphini komponent Name[fi]=Dolphin osa @@ -23,6 +24,7 @@ Name[it]=Componente Dolphin Name[ja]=Dolphin パート Name[kk]=Dolphin бөлшегі Name[km]=ផ្នែករបស់ Dolphin +Name[kn]=ಡಾಲ್ಫಿನ್ ಭಾಗ Name[ko]=Dolphin 부분 Name[ku]=Parçeyê Bibîne Name[lv]=Dolphin daļa @@ -35,12 +37,14 @@ Name[pa]=ਡਾਲਫਿਨ ਭਾਗ Name[pl]=Moduł Dophina Name[pt]=Componente do Dolphin Name[pt_BR]=Componente Dolphin +Name[ro]=Componentă Dolphin Name[ru]=Встраиваемый компонент Dolphin Name[se]=Dolphin-oassi Name[sl]=Del Dolphin Name[sr]=Делфин део Name[sr@latin]=Dolphin deo Name[sv]=Dolphin-delprogram +Name[ta]=டால்பினின் பகுதி Name[tg]=Қисми Dolphin Name[tr]=Dolphin Parçacığı Name[uk]=Компонент Дельфіна diff --git a/src/dolphinpart.rc b/src/dolphinpart.rc index 35bde506e..2e3f63e5c 100644 --- a/src/dolphinpart.rc +++ b/src/dolphinpart.rc @@ -13,7 +13,7 @@ </Menu> <Menu name="view"> <Menu name="sort"> - <text context="@title:menu">Sort by</text> + <text context="@title:menu">Sort By</text> <Action name="sort_by_name" /> <Action name="sort_by_size" /> <Action name="sort_by_date" /> diff --git a/src/dolphinsettingsdialog.cpp b/src/dolphinsettingsdialog.cpp index 1bbbbde55..d3f387aa9 100644 --- a/src/dolphinsettingsdialog.cpp +++ b/src/dolphinsettingsdialog.cpp @@ -23,6 +23,7 @@ #include "dolphinapplication.h" #include "dolphinmainwindow.h" #include "generalsettingspage.h" +#include "startupsettingspage.h" #include "viewsettingspage.h" #include <klocale.h> @@ -30,7 +31,11 @@ #include <kicon.h> DolphinSettingsDialog::DolphinSettingsDialog(DolphinMainWindow* mainWindow) : - KPageDialog(mainWindow) + KPageDialog(mainWindow), + m_startupSettingsPage(0), + m_generalSettingsPage(0), + m_viewSettingsPage(0) + { const QSize minSize = minimumSize(); setMinimumSize(QSize(512, minSize.height())); @@ -40,16 +45,21 @@ DolphinSettingsDialog::DolphinSettingsDialog(DolphinMainWindow* mainWindow) : setButtons(Ok | Apply | Cancel | Default); setDefaultButton(Ok); - m_generalSettingsPage = new GeneralSettingsPage(mainWindow, this); - KPageWidgetItem* generalSettingsFrame = addPage(m_generalSettingsPage, - i18nc("@title:group", "General")); - generalSettingsFrame->setIcon(KIcon("system-run")); + m_startupSettingsPage = new StartupSettingsPage(mainWindow, this); + KPageWidgetItem* startupSettingsFrame = addPage(m_startupSettingsPage, + i18nc("@title:group", "Startup")); + startupSettingsFrame->setIcon(KIcon("go-home")); m_viewSettingsPage = new ViewSettingsPage(mainWindow, this); KPageWidgetItem* viewSettingsFrame = addPage(m_viewSettingsPage, i18nc("@title:group", "View Modes")); viewSettingsFrame->setIcon(KIcon("view-choose")); + m_generalSettingsPage = new GeneralSettingsPage(mainWindow, this); + KPageWidgetItem* generalSettingsFrame = addPage(m_generalSettingsPage, + i18nc("@title:group", "General")); + generalSettingsFrame->setIcon(KIcon("system-run")); + const KConfigGroup dialogConfig(KSharedConfig::openConfig("dolphinrc"), "SettingsDialog"); restoreDialogSize(dialogConfig); } @@ -76,6 +86,7 @@ void DolphinSettingsDialog::slotButtonClicked(int button) void DolphinSettingsDialog::applySettings() { + m_startupSettingsPage->applySettings(); m_generalSettingsPage->applySettings(); m_viewSettingsPage->applySettings(); DolphinApplication::app()->refreshMainWindows(); @@ -83,6 +94,7 @@ void DolphinSettingsDialog::applySettings() void DolphinSettingsDialog::restoreDefaults() { + m_startupSettingsPage->restoreDefaults(); m_generalSettingsPage->restoreDefaults(); m_viewSettingsPage->restoreDefaults(); DolphinApplication::app()->refreshMainWindows(); diff --git a/src/dolphinsettingsdialog.h b/src/dolphinsettingsdialog.h index e68d82798..2cb7fc78e 100644 --- a/src/dolphinsettingsdialog.h +++ b/src/dolphinsettingsdialog.h @@ -22,14 +22,16 @@ #define DOLPHINSETTINGSDIALOG_H #include <kpagedialog.h> + class GeneralSettingsPage; +class StartupSettingsPage; class ViewSettingsPage; class DolphinMainWindow; /** * @brief Settings dialog for Dolphin. * - * Contains the pages for general settings and view settings. + * Contains the pages for startup settings, general settings and view settings. * * @author Peter Penz <[email protected]> */ @@ -50,6 +52,7 @@ private: void restoreDefaults(); private: + StartupSettingsPage* m_startupSettingsPage; GeneralSettingsPage* m_generalSettingsPage; ViewSettingsPage* m_viewSettingsPage; }; diff --git a/src/dolphinui.rc b/src/dolphinui.rc index 1763aefda..8aaddcd26 100644 --- a/src/dolphinui.rc +++ b/src/dolphinui.rc @@ -23,7 +23,7 @@ <Action name="columns" /> </Menu> <Menu name="sort"> - <text context="@title:menu">Sort by</text> + <text context="@title:menu">Sort By</text> <Action name="sort_by_name" /> <Action name="sort_by_size" /> <Action name="sort_by_date" /> diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index 7979b06c3..1ed8310a6 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -32,16 +32,16 @@ #include <kcolorscheme.h> #include <kdirlister.h> #include <kfileitemdelegate.h> -#include <klocale.h> #include <kiconeffect.h> +#include <klocale.h> #include <kio/deletejob.h> #include <kio/netaccess.h> #include <kio/previewjob.h> #include <kjob.h> #include <kmenu.h> #include <kmimetyperesolver.h> -#include <konqmimedata.h> #include <konq_operations.h> +#include <konqmimedata.h> #include <ktoggleaction.h> #include <kurl.h> @@ -52,10 +52,11 @@ #include "dolphinsortfilterproxymodel.h" #include "dolphindetailsview.h" #include "dolphiniconsview.h" -#include "renamedialog.h" -#include "viewproperties.h" #include "dolphinsettings.h" #include "dolphin_generalsettings.h" +#include "iconmanager.h" +#include "renamedialog.h" +#include "viewproperties.h" DolphinView::DolphinView(QWidget* parent, const KUrl& url, @@ -78,21 +79,15 @@ DolphinView::DolphinView(QWidget* parent, m_dolphinModel(dolphinModel), m_dirLister(dirLister), m_proxyModel(proxyModel), - m_previewJob(0) + m_iconManager(0) { setFocusPolicy(Qt::StrongFocus); m_topLayout = new QVBoxLayout(this); m_topLayout->setSpacing(0); m_topLayout->setMargin(0); - QClipboard* clipboard = QApplication::clipboard(); - connect(clipboard, SIGNAL(dataChanged()), - this, SLOT(updateCutItems())); - connect(m_dirLister, SIGNAL(completed()), this, SLOT(updateCutItems())); - connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)), - this, SLOT(generatePreviews(const KFileItemList&))); m_controller = new DolphinController(this); m_controller->setUrl(url); @@ -131,10 +126,6 @@ DolphinView::DolphinView(QWidget* parent, DolphinView::~DolphinView() { - if (m_previewJob != 0) { - m_previewJob->kill(); - m_previewJob = 0; - } } const KUrl& DolphinView::url() const @@ -194,16 +185,6 @@ void DolphinView::setMode(Mode mode) m_mode = mode; - if (isColumnViewActive()) { - // When changing the mode in the column view, it makes sense - // to go back to the root URL of the column view automatically. - // Otherwise there it would not be possible to turn off the column view - // without focusing the first column. - const KUrl root = rootUrl(); - setUrl(root); - m_controller->setUrl(root); - } - deleteView(); const KUrl viewPropsUrl = viewPropertiesUrl(); @@ -246,7 +227,7 @@ void DolphinView::setShowPreview(bool show) props.setShowPreview(show); m_showPreview = show; - + m_iconManager->setShowPreview(show); emit showPreviewChanged(); loadDirectory(viewPropsUrl, true); @@ -419,11 +400,13 @@ QPoint DolphinView::contentsPosition() const void DolphinView::zoomIn() { m_controller->triggerZoomIn(); + reload(); } void DolphinView::zoomOut() { m_controller->triggerZoomOut(); + reload(); } bool DolphinView::isZoomInPossible() const @@ -575,45 +558,6 @@ void DolphinView::triggerItem(const KFileItem& item) emit itemTriggered(item); // caught by DolphinViewContainer or DolphinPart } -void DolphinView::generatePreviews(const KFileItemList& items) -{ - if (m_controller->dolphinView()->showPreview()) { - if (m_previewJob != 0) { - m_previewJob->kill(); - m_previewJob = 0; - } - - m_previewJob = KIO::filePreview(items, 128); - connect(m_previewJob, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)), - this, SLOT(replaceIcon(const KFileItem&, const QPixmap&))); - connect(m_previewJob, SIGNAL(finished(KJob*)), - this, SLOT(slotPreviewJobFinished(KJob*))); - } -} - -void DolphinView::replaceIcon(const KFileItem& item, const QPixmap& pixmap) -{ - Q_ASSERT(!item.isNull()); - if (!m_showPreview || (item.url().directory() != m_dirLister->url().path())) { - // the preview has been deactivated in the meanwhile or the preview - // job is still working on items of an older URL, hence - // the item is not part of the directory model anymore - return; - } - - const QModelIndex idx = m_dolphinModel->indexForItem(item); - if (idx.isValid() && (idx.column() == 0)) { - const QMimeData* mimeData = QApplication::clipboard()->mimeData(); - if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) { - KIconEffect iconEffect; - const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState); - m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole); - } else { - m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole); - } - } -} - void DolphinView::emitSelectionChangedSignal() { emit selectionChanged(DolphinView::selectedItems()); @@ -631,7 +575,6 @@ void DolphinView::loadDirectory(const KUrl& url, bool reload) return; } - m_cutItemsCache.clear(); m_loadingDirectory = true; m_dirLister->stop(); @@ -714,6 +657,7 @@ void DolphinView::applyViewProperties(const KUrl& url) const bool showPreview = props.showPreview(); if (showPreview != m_showPreview) { m_showPreview = showPreview; + m_iconManager->setShowPreview(showPreview); emit showPreviewChanged(); } } @@ -899,25 +843,6 @@ void DolphinView::emitContentsMoved() } } -void DolphinView::updateCutItems() -{ - // restore the icons of all previously selected items to the - // original state... - QList<CutItem>::const_iterator it = m_cutItemsCache.begin(); - QList<CutItem>::const_iterator end = m_cutItemsCache.end(); - while (it != end) { - const QModelIndex index = m_dolphinModel->indexForUrl((*it).url); - if (index.isValid()) { - m_dolphinModel->setData(index, QIcon((*it).pixmap), Qt::DecorationRole); - } - ++it; - } - m_cutItemsCache.clear(); - - // ... and apply an item effect to all currently cut items - applyCutItemEffect(); -} - void DolphinView::showHoverInformation(const KFileItem& item) { if (hasSelection() || !m_active) { @@ -934,7 +859,6 @@ void DolphinView::clearHoverInformation() } } - void DolphinView::createView() { deleteView(); @@ -980,6 +904,9 @@ void DolphinView::createView() view->setSelectionMode(QAbstractItemView::ExtendedSelection); new KMimeTypeResolver(view, m_dolphinModel); + m_iconManager = new IconManager(view, m_proxyModel); + m_iconManager->setShowPreview(m_showPreview); + m_topLayout->insertWidget(1, view); connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), @@ -1002,6 +929,7 @@ void DolphinView::deleteView() m_detailsView = 0; m_columnView = 0; m_fileItemDelegate = 0; + m_iconManager = 0; } } @@ -1034,42 +962,6 @@ bool DolphinView::isCutItem(const KFileItem& item) const return false; } -void DolphinView::applyCutItemEffect() -{ - const QMimeData* mimeData = QApplication::clipboard()->mimeData(); - if (!KonqMimeData::decodeIsCutSelection(mimeData)) { - return; - } - - KFileItemList items(m_dirLister->items()); - KFileItemList::const_iterator it = items.begin(); - const KFileItemList::const_iterator end = items.end(); - while (it != end) { - const KFileItem item = *it; - if (isCutItem(item)) { - const QModelIndex index = m_dolphinModel->indexForItem(item); - const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole); - if (value.type() == QVariant::Icon) { - const QIcon icon(qvariant_cast<QIcon>(value)); - QPixmap pixmap = icon.pixmap(128, 128); - - // remember current pixmap for the item to be able - // to restore it when other items get cut - CutItem cutItem; - cutItem.url = item.url(); - cutItem.pixmap = pixmap; - m_cutItemsCache.append(cutItem); - - // apply icon effect to the cut item - KIconEffect iconEffect; - pixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState); - m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole); - } - } - ++it; - } -} - KToggleAction* DolphinView::iconsModeAction(KActionCollection* actionCollection) { KToggleAction* iconsView = actionCollection->add<KToggleAction>("icons"); @@ -1133,19 +1025,14 @@ void DolphinView::renameSelectedItems() Q_ASSERT(newName.contains('#')); // iterate through all selected items and rename them... - const int replaceIndex = newName.indexOf('#'); - Q_ASSERT(replaceIndex >= 0); int index = 1; - - KFileItemList::const_iterator it = items.begin(); - const KFileItemList::const_iterator end = items.end(); - while (it != end) { - const KUrl& oldUrl = (*it).url(); + foreach (KFileItem item, items) { + const KUrl& oldUrl = item.url(); QString number; number.setNum(index++); - QString name(newName); - name.replace(replaceIndex, 1, number); + QString name = newName; + name.replace('#', number); if (oldUrl.fileName() != name) { KUrl newUrl = oldUrl; @@ -1153,7 +1040,6 @@ void DolphinView::renameSelectedItems() KonqOperations::rename(this, oldUrl, newUrl); emit doingOperation(KonqFileUndoManager::RENAME); } - ++it; } } } else { @@ -1212,12 +1098,6 @@ void DolphinView::slotDeleteFileFinished(KJob* job) } } -void DolphinView::slotPreviewJobFinished(KJob* job) -{ - Q_ASSERT(job == m_previewJob); - m_previewJob = 0; -} - void DolphinView::cutSelectedItems() { QMimeData* mimeData = new QMimeData(); diff --git a/src/dolphinview.h b/src/dolphinview.h index 6f0289f62..215a2a23c 100644 --- a/src/dolphinview.h +++ b/src/dolphinview.h @@ -39,24 +39,22 @@ #include <QWidget> class QActionGroup; -class KAction; -class KToggleAction; class DolphinController; -class KDirLister; -class KFileItemDelegate; -class KUrl; -class DolphinModel; class DolphinColumnView; class DolphinDetailsView; class DolphinIconsView; class DolphinMainWindow; +class DolphinModel; class DolphinSortFilterProxyModel; +class IconManager; +class KAction; +class KActionCollection; +class KDirLister; +class KFileItemDelegate; +class KUrl; +class KToggleAction; class QModelIndex; class ViewProperties; -namespace KIO -{ - class PreviewJob; -} /** * @short Represents a view for the directory content. @@ -529,19 +527,6 @@ private slots: */ void triggerItem(const KFileItem& index); - /** - * Generates a preview image for each file item in \a items. - * The current preview settings (maximum size, 'Show Preview' menu) - * are respected. - */ - void generatePreviews(const KFileItemList& items); - - /** - * Replaces the icon of the item \a item by the preview pixmap - * \a pixmap. - */ - void replaceIcon(const KFileItem& item, const QPixmap& pixmap); - void emitSelectionChangedSignal(); /** @@ -590,9 +575,6 @@ private slots: */ void emitContentsMoved(); - /** Applies an item effect to all cut items of the clipboard. */ - void updateCutItems(); - /** * Updates the status bar to show hover information for the * item \a item. If currently other items are selected, @@ -613,12 +595,6 @@ private slots: */ void slotDeleteFileFinished(KJob* job); - /** - * Is invoked when the preview job has been finished and - * set m_previewJob to 0. - */ - void slotPreviewJobFinished(KJob* job); - private: void loadDirectory(const KUrl& url, bool reload = false); @@ -657,9 +633,6 @@ private: */ bool isCutItem(const KFileItem& item) const; - /** Applies an item effect to all cut items. */ - void applyCutItemEffect(); - /** * Returns true, if the ColumnView is activated. As the column view * requires some special handling for iterating through directories, @@ -671,16 +644,6 @@ private: } private: - /** - * Remembers the original pixmap for an item before - * the cut effect is applied. - */ - struct CutItem - { - KUrl url; - QPixmap pixmap; - }; - bool m_active; bool m_showPreview; bool m_loadingDirectory; @@ -701,9 +664,7 @@ private: KDirLister* m_dirLister; DolphinSortFilterProxyModel* m_proxyModel; - KIO::PreviewJob* m_previewJob; - - QList<CutItem> m_cutItemsCache; + IconManager* m_iconManager; KUrl m_rootUrl; }; diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index a1846dc75..e6966affb 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -398,10 +398,13 @@ void DolphinViewContainer::slotItemTriggered(const KFileItem& item) if (item.isDir()) { m_view->setUrl(url); - } else if (item.isFile() && url.isLocalFile()) { - // allow to browse through ZIP and tar files - // TODO: make this configurable for Dolphin in KDE 4.1 + return; + } + const GeneralSettings* settings = DolphinSettings::instance().generalSettings(); + const bool browseThroughArchives = settings->browseThroughArchives() && + item.isFile() && url.isLocalFile(); + if (browseThroughArchives) { KMimeType::Ptr mime = item.mimeTypePtr(); // Don't use mime->is("application/zip"), as this would @@ -409,19 +412,21 @@ void DolphinViewContainer::slotItemTriggered(const KFileItem& item) if (mime->name() == "application/zip") { url.setProtocol("zip"); m_view->setUrl(url); - } else if (mime->is("application/x-tar") || - mime->is("application/x-tarz") || - mime->is("application/x-bzip-compressed-tar") || - mime->is("application/x-compressed-tar") || - mime->is("application/x-tzo")) { + return; + } + + if (mime->is("application/x-tar") || + mime->is("application/x-tarz") || + mime->is("application/x-bzip-compressed-tar") || + mime->is("application/x-compressed-tar") || + mime->is("application/x-tzo")) { url.setProtocol("tar"); m_view->setUrl(url); - } else { - item.run(); + return; } - } else { - item.run(); } + + item.run(); } #include "dolphinviewcontainer.moc" diff --git a/src/generalsettingspage.cpp b/src/generalsettingspage.cpp index f856de1b1..04863c037 100644 --- a/src/generalsettingspage.cpp +++ b/src/generalsettingspage.cpp @@ -21,80 +21,33 @@ #include "generalsettingspage.h" #include "dolphinsettings.h" -#include "dolphinmainwindow.h" -#include "dolphinview.h" -#include "dolphinviewcontainer.h" #include "dolphin_generalsettings.h" #include <kdialog.h> -#include <kfiledialog.h> #include <klocale.h> #include <kvbox.h> #include <QCheckBox> #include <QGroupBox> #include <QLabel> -#include <QLineEdit> -#include <QPushButton> -#include <QRadioButton> +#include <QVBoxLayout> GeneralSettingsPage::GeneralSettingsPage(DolphinMainWindow* mainWin, QWidget* parent) : SettingsPageBase(parent), - m_mainWindow(mainWin), - m_homeUrl(0), - m_splitView(0), - m_editableUrl(0), - m_filterBar(0), m_showDeleteCommand(0), m_confirmMoveToTrash(0), - m_confirmDelete(0) + m_confirmDelete(0), + m_browseThroughArchives(0) { + Q_UNUSED(mainWin); + const int spacing = KDialog::spacingHint(); QVBoxLayout* topLayout = new QVBoxLayout(this); KVBox* vBox = new KVBox(this); vBox->setSpacing(spacing); - // create 'Home URL' editor - QGroupBox* homeBox = new QGroupBox(i18nc("@title:group", "Home Folder"), vBox); - - KHBox* homeUrlBox = new KHBox(homeBox); - homeUrlBox->setSpacing(spacing); - - new QLabel(i18nc("@label:textbox", "Location:"), homeUrlBox); - m_homeUrl = new QLineEdit(homeUrlBox); - - QPushButton* selectHomeUrlButton = new QPushButton(KIcon("folder-open"), QString(), homeUrlBox); - connect(selectHomeUrlButton, SIGNAL(clicked()), - this, SLOT(selectHomeUrl())); - - KHBox* buttonBox = new KHBox(homeBox); - buttonBox->setSpacing(spacing); - - QPushButton* useCurrentButton = new QPushButton(i18nc("@action:button", "Use Current Location"), buttonBox); - connect(useCurrentButton, SIGNAL(clicked()), - this, SLOT(useCurrentLocation())); - QPushButton* useDefaultButton = new QPushButton(i18nc("@action:button", "Use Default Location"), buttonBox); - connect(useDefaultButton, SIGNAL(clicked()), - this, SLOT(useDefaultLocation())); - - QVBoxLayout* homeBoxLayout = new QVBoxLayout(homeBox); - homeBoxLayout->addWidget(homeUrlBox); - homeBoxLayout->addWidget(buttonBox); - - QGroupBox* startBox = new QGroupBox(i18nc("@title:group", "Startup Settings"), vBox); - - // create 'Split view', 'Editable location' and 'Filter bar' checkboxes - m_splitView = new QCheckBox(i18nc("@option:check Startup Settings", "Split view mode"), startBox); - m_editableUrl = new QCheckBox(i18nc("@option:check Startup Settings", "Editable location bar"), startBox); - m_filterBar = new QCheckBox(i18nc("@option:check Startup Settings", "Show filter bar"),startBox); - - QVBoxLayout* startBoxLayout = new QVBoxLayout(startBox); - startBoxLayout->addWidget(m_splitView); - startBoxLayout->addWidget(m_editableUrl); - startBoxLayout->addWidget(m_filterBar); - // create 'Ask Confirmation For' group QGroupBox* confirmBox = new QGroupBox(i18nc("@title:group", "Ask For Confirmation When"), vBox); m_confirmMoveToTrash = new QCheckBox(i18nc("@option:check Ask for Confirmation When", @@ -109,6 +62,8 @@ GeneralSettingsPage::GeneralSettingsPage(DolphinMainWindow* mainWin, QWidget* pa // create 'Show the command 'Delete' in context menu' checkbox m_showDeleteCommand = new QCheckBox(i18nc("@option:check", "Show 'Delete' command in context menu"), vBox); + m_browseThroughArchives = new QCheckBox(i18nc("option:check", "Browse through archives"), vBox); + // Add a dummy widget with no restriction regarding // a vertical resizing. This assures that the dialog layout // is not stretched vertically. @@ -127,16 +82,6 @@ void GeneralSettingsPage::applySettings() { GeneralSettings* settings = DolphinSettings::instance().generalSettings(); - const KUrl url(m_homeUrl->text()); - KFileItem fileItem(S_IFDIR, KFileItem::Unknown, url); - if (url.isValid() && fileItem.isDir()) { - settings->setHomeUrl(url.prettyUrl()); - } - - settings->setSplitView(m_splitView->isChecked()); - settings->setEditableUrl(m_editableUrl->isChecked()); - settings->setFilterBar(m_filterBar->isChecked()); - KSharedConfig::Ptr konqConfig = KSharedConfig::openConfig("konquerorrc", KConfig::IncludeGlobals); KConfigGroup trashConfig(konqConfig, "Trash"); trashConfig.writeEntry("ConfirmTrash", m_confirmMoveToTrash->isChecked()); @@ -146,6 +91,8 @@ void GeneralSettingsPage::applySettings() KConfigGroup kdeConfig(KGlobal::config(), "KDE"); kdeConfig.writeEntry("ShowDeleteCommand", m_showDeleteCommand->isChecked()); kdeConfig.sync(); + + settings->setBrowseThroughArchives(m_browseThroughArchives->isChecked()); } void GeneralSettingsPage::restoreDefaults() @@ -158,34 +105,8 @@ void GeneralSettingsPage::restoreDefaults() loadSettings(); } -void GeneralSettingsPage::selectHomeUrl() -{ - const QString homeUrl(m_homeUrl->text()); - KUrl url(KFileDialog::getExistingDirectoryUrl(homeUrl)); - if (!url.isEmpty()) { - m_homeUrl->setText(url.prettyUrl()); - } -} - -void GeneralSettingsPage::useCurrentLocation() -{ - const DolphinView* view = m_mainWindow->activeViewContainer()->view(); - m_homeUrl->setText(view->url().prettyUrl()); -} - -void GeneralSettingsPage::useDefaultLocation() -{ - m_homeUrl->setText("file://" + QDir::homePath()); -} - void GeneralSettingsPage::loadSettings() { - GeneralSettings* settings = DolphinSettings::instance().generalSettings(); - m_homeUrl->setText(settings->homeUrl()); - m_splitView->setChecked(settings->splitView()); - m_editableUrl->setChecked(settings->editableUrl()); - m_filterBar->setChecked(settings->filterBar()); - KSharedConfig::Ptr konqConfig = KSharedConfig::openConfig("konquerorrc", KConfig::IncludeGlobals); const KConfigGroup trashConfig(konqConfig, "Trash"); m_confirmMoveToTrash->setChecked(trashConfig.readEntry("ConfirmTrash", false)); @@ -193,6 +114,9 @@ void GeneralSettingsPage::loadSettings() const KConfigGroup kdeConfig(KGlobal::config(), "KDE"); m_showDeleteCommand->setChecked(kdeConfig.readEntry("ShowDeleteCommand", false)); + + GeneralSettings* settings = DolphinSettings::instance().generalSettings(); + m_browseThroughArchives->setChecked(settings->browseThroughArchives()); } #include "generalsettingspage.moc" diff --git a/src/generalsettingspage.h b/src/generalsettingspage.h index 7bcf75c9e..df713ad47 100644 --- a/src/generalsettingspage.h +++ b/src/generalsettingspage.h @@ -28,9 +28,6 @@ class QCheckBox; /** * @brief Page for the 'General' settings of the Dolphin settings dialog. - * - * The general settings allow to set the home URL and to configure the - * state of the view mode, split mode and the filter bar when starting Dolphin. */ class GeneralSettingsPage : public SettingsPageBase { @@ -46,25 +43,15 @@ public: /** @see SettingsPageBase::restoreDefaults() */ virtual void restoreDefaults(); -private slots: - void selectHomeUrl(); - void useCurrentLocation(); - void useDefaultLocation(); - private: void loadSettings(); private: - DolphinMainWindow* m_mainWindow; - QLineEdit* m_homeUrl; - - QCheckBox* m_splitView; - QCheckBox* m_editableUrl; - QCheckBox* m_filterBar; - QCheckBox* m_showDeleteCommand; QCheckBox* m_confirmMoveToTrash; QCheckBox* m_confirmDelete; + + QCheckBox* m_browseThroughArchives; }; #endif diff --git a/src/generalviewsettingspage.cpp b/src/generalviewsettingspage.cpp index 2d815d3d2..ebf235f2a 100644 --- a/src/generalviewsettingspage.cpp +++ b/src/generalviewsettingspage.cpp @@ -47,7 +47,8 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(DolphinMainWindow* mainWindow, m_globalProps(0), m_maxPreviewSize(0), m_spinBox(0), - m_useFileThumbnails(0) + m_useFileThumbnails(0), + m_showSelectionToggle(0) { const int spacing = KDialog::spacingHint(); const int margin = KDialog::marginHint(); @@ -71,7 +72,7 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(DolphinMainWindow* mainWindow, KHBox* vBox = new KHBox(previewBox); vBox->setSpacing(spacing); - QLabel* maxFileSize = new QLabel(i18nc("@label:slider", "Maximum file size:"), vBox); + new QLabel(i18nc("@label:slider", "Maximum file size:"), vBox); m_maxPreviewSize = new QSlider(Qt::Horizontal, vBox); m_spinBox = new QSpinBox(vBox); @@ -87,6 +88,8 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(DolphinMainWindow* mainWindow, previewBoxLayout->addWidget(vBox); previewBoxLayout->addWidget(m_useFileThumbnails); + m_showSelectionToggle = new QCheckBox(i18nc("option:check", "Show selection toggle"), this); + // Add a dummy widget with no restriction regarding // a vertical resizing. This assures that the dialog layout // is not stretched vertically. @@ -128,6 +131,8 @@ void GeneralViewSettingsPage::applySettings() m_useFileThumbnails->isChecked(), KConfigBase::Normal | KConfigBase::Global); globalConfig.sync(); + + settings->setShowSelectionToggle(m_showSelectionToggle->isChecked()); } void GeneralViewSettingsPage::restoreDefaults() @@ -154,6 +159,9 @@ void GeneralViewSettingsPage::loadSettings() m_maxPreviewSize->setTickPosition(QSlider::TicksBelow); KConfigGroup globalConfig(KGlobal::config(), "PreviewSettings"); + // TODO: The default value of 5 MB must match with the default value inside + // kdelibs/kio/kio/previewjob.cpp. Maybe a static getter method in PreviewJob + // should be added for getting the default size? const int maxByteSize = globalConfig.readEntry("MaximumSize", 5 * 1024 * 1024 /* 5 MB */); int maxMByteSize = maxByteSize / (1024 * 1024); if (maxMByteSize < 1) { @@ -171,6 +179,8 @@ void GeneralViewSettingsPage::loadSettings() const bool useFileThumbnails = globalConfig.readEntry("UseFileThumbnails", true); m_useFileThumbnails->setChecked(useFileThumbnails); + + m_showSelectionToggle->setChecked(settings->showSelectionToggle()); } #include "generalviewsettingspage.moc" diff --git a/src/generalviewsettingspage.h b/src/generalviewsettingspage.h index 5aad4be4f..c84335dc1 100644 --- a/src/generalviewsettingspage.h +++ b/src/generalviewsettingspage.h @@ -60,6 +60,7 @@ private: QSlider* m_maxPreviewSize; QSpinBox* m_spinBox; QCheckBox* m_useFileThumbnails; + QCheckBox* m_showSelectionToggle; }; #endif diff --git a/src/iconmanager.cpp b/src/iconmanager.cpp new file mode 100644 index 000000000..5940c909e --- /dev/null +++ b/src/iconmanager.cpp @@ -0,0 +1,232 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 * + ***************************************************************************/ + +#include "iconmanager.h" + +#include "dolphinmodel.h" +#include "dolphinsortfilterproxymodel.h" + +#include <kiconeffect.h> +#include <kio/previewjob.h> +#include <kdebug.h> +#include <kdirlister.h> +#include <konqmimedata.h> + +#include <QApplication> +#include <QAbstractItemView> +#include <QClipboard> +#include <QColor> +#include <QIcon> + +IconManager::IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* model) : + QObject(parent), + m_showPreview(false), + m_view(parent), + m_previewJobs(), + m_dolphinModel(0), + m_proxyModel(model), + m_cutItemsCache() +{ + Q_ASSERT(m_view->iconSize().isValid()); // each view must provide its current icon size + + m_dolphinModel = static_cast<DolphinModel*>(m_proxyModel->sourceModel()); + connect(m_dolphinModel->dirLister(), SIGNAL(newItems(const KFileItemList&)), + this, SLOT(updateIcons(const KFileItemList&))); + + QClipboard* clipboard = QApplication::clipboard(); + connect(clipboard, SIGNAL(dataChanged()), + this, SLOT(updateCutItems())); +} + +IconManager::~IconManager() +{ + foreach (KJob* job, m_previewJobs) { + Q_ASSERT(job != 0); + job->kill(); + } + m_previewJobs.clear(); +} + + +void IconManager::setShowPreview(bool show) +{ + if (m_showPreview != show) { + m_showPreview = show; + m_cutItemsCache.clear(); + updateCutItems(); + } +} + +void IconManager::updateIcons(const KFileItemList& items) +{ + // make the icons of all hidden files semitransparent + foreach (KFileItem item, items) { + if (item.isHidden()) { + applyHiddenItemEffect(item); + } + } + + if (!m_showPreview) { + return; + } + + // generate previews + const QRect visibleArea = m_view->viewport()->rect(); + + // Order the items in a way that the preview for the visible items + // is generated first, as this improves the feeled performance a lot. + KFileItemList orderedItems; + foreach (KFileItem item, items) { + const QModelIndex dirIndex = m_dolphinModel->indexForItem(item); + const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex); + const QRect itemRect = m_view->visualRect(proxyIndex); + if (itemRect.intersects(visibleArea)) { + orderedItems.insert(0, item); + } else { + orderedItems.append(item); + } + } + + const QSize size = m_view->iconSize(); + KIO::PreviewJob* job = KIO::filePreview(orderedItems, size.width(), size.height()); + connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)), + this, SLOT(replaceIcon(const KFileItem&, const QPixmap&))); + connect(job, SIGNAL(finished(KJob*)), + this, SLOT(slotPreviewJobFinished(KJob*))); + + m_previewJobs.append(job); +} + +void IconManager::replaceIcon(const KFileItem& item, const QPixmap& pixmap) +{ + Q_ASSERT(!item.isNull()); + KDirLister* dirLister = m_dolphinModel->dirLister(); + if (!m_showPreview || (item.url().directory() != dirLister->url().path())) { + // the preview has been canceled in the meanwhile or the preview + // job is still working on items of an older URL, hence + // the item is not part of the directory model anymore + return; + } + + const QModelIndex idx = m_dolphinModel->indexForItem(item); + if (idx.isValid() && (idx.column() == 0)) { + QPixmap icon = pixmap; + if (item.isHidden()) { + if (!icon.hasAlpha()) { + // the semitransparent operation requires having an alpha mask + QPixmap alphaMask(icon.width(), icon.height()); + alphaMask.fill(); + icon.setAlphaChannel(alphaMask); + } + KIconEffect::semiTransparent(icon); + } + + const QMimeData* mimeData = QApplication::clipboard()->mimeData(); + if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) { + KIconEffect iconEffect; + icon = iconEffect.apply(icon, KIconLoader::Desktop, KIconLoader::DisabledState); + m_dolphinModel->setData(idx, QIcon(icon), Qt::DecorationRole); + } else { + m_dolphinModel->setData(idx, QIcon(icon), Qt::DecorationRole); + } + } +} + +void IconManager::slotPreviewJobFinished(KJob* job) +{ + const int index = m_previewJobs.indexOf(job); + m_previewJobs.removeAt(index); +} + +void IconManager::updateCutItems() +{ + // restore the icons of all previously selected items to the + // original state... + foreach (CutItem cutItem, m_cutItemsCache) { + const QModelIndex index = m_dolphinModel->indexForUrl(cutItem.url); + if (index.isValid()) { + m_dolphinModel->setData(index, QIcon(cutItem.pixmap), Qt::DecorationRole); + } + } + m_cutItemsCache.clear(); + + // ... and apply an item effect to all currently cut items + applyCutItemEffect(); +} + +bool IconManager::isCutItem(const KFileItem& item) const +{ + const QMimeData* mimeData = QApplication::clipboard()->mimeData(); + const KUrl::List cutUrls = KUrl::List::fromMimeData(mimeData); + + const KUrl& itemUrl = item.url(); + foreach (KUrl url, cutUrls) { + if (url == itemUrl) { + return true; + } + } + + return false; +} + +void IconManager::applyCutItemEffect() +{ + const QMimeData* mimeData = QApplication::clipboard()->mimeData(); + if (!KonqMimeData::decodeIsCutSelection(mimeData)) { + return; + } + + const KFileItemList items(m_dolphinModel->dirLister()->items()); + foreach (KFileItem item, items) { + if (isCutItem(item)) { + const QModelIndex index = m_dolphinModel->indexForItem(item); + const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole); + if (value.type() == QVariant::Icon) { + const QIcon icon(qvariant_cast<QIcon>(value)); + QPixmap pixmap = icon.pixmap(m_view->iconSize()); + + // remember current pixmap for the item to be able + // to restore it when other items get cut + CutItem cutItem; + cutItem.url = item.url(); + cutItem.pixmap = pixmap; + m_cutItemsCache.append(cutItem); + + // apply icon effect to the cut item + KIconEffect iconEffect; + pixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState); + m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole); + } + } + } +} + +void IconManager::applyHiddenItemEffect(const KFileItem& hiddenItem) +{ + const QModelIndex index = m_dolphinModel->indexForItem(hiddenItem); + const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole); + if (value.type() == QVariant::Icon) { + const QIcon icon(qvariant_cast<QIcon>(value)); + QPixmap pixmap = icon.pixmap(m_view->iconSize()); + KIconEffect::semiTransparent(pixmap); + m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole); + } +} + +#include "iconmanager.moc" diff --git a/src/iconmanager.h b/src/iconmanager.h new file mode 100644 index 000000000..d6cf5332b --- /dev/null +++ b/src/iconmanager.h @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 ICONMANAGER_H +#define ICONMANAGER_H + +#include <kfileitem.h> +#include <kurl.h> + +#include <QList> +#include <QObject> +#include <QPixmap> + +class DolphinModel; +class DolphinSortFilterProxyModel; +class KJob; +class QAbstractItemView; + +/** + * @brief Manages the icon state of a directory model. + * + * Per default a preview is generated for each item. + * Additionally the clipboard is checked for cut items. + * The icon state for cut items gets dimmed automatically. + */ +class IconManager : public QObject +{ + Q_OBJECT + +public: + IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* model); + virtual ~IconManager(); + void setShowPreview(bool show); + bool showPreview() const; + +private slots: + /** + * Updates the icons of for each item in \a items by making hidden + * items semitransparent and generating previews. The current preview + * settings (maximum size, 'Show Preview' menu) are respected. + */ + void updateIcons(const KFileItemList& items); + + /** + * Replaces the icon of the item \a item by the preview pixmap + * \a pixmap. + */ + void replaceIcon(const KFileItem& item, const QPixmap& pixmap); + + /** + * Is invoked when the preview job has been finished and + * set m_previewJob to 0. + */ + void slotPreviewJobFinished(KJob* job); + + /** Synchronizes the item icon with the clipboard of cut items. */ + void updateCutItems(); + +private: + /** + * Returns true, if the item \a item has been cut into + * the clipboard. + */ + bool isCutItem(const KFileItem& item) const; + + /** Applies an item effect to all cut items. */ + void applyCutItemEffect(); + + /** Applies an item effect to the hidden item \a hiddenItem. */ + void applyHiddenItemEffect(const KFileItem& hiddenItem); + +private: + /** + * Remembers the original pixmap for an item before + * the cut effect is applied. + */ + struct CutItem + { + KUrl url; + QPixmap pixmap; + }; + + bool m_showPreview; + + QAbstractItemView* m_view; + QList<KJob*> m_previewJobs; + DolphinModel* m_dolphinModel; + DolphinSortFilterProxyModel* m_proxyModel; + + QList<CutItem> m_cutItemsCache; +}; + +inline bool IconManager::showPreview() const +{ + return m_showPreview; +} + +#endif diff --git a/src/infosidebarpage.cpp b/src/infosidebarpage.cpp index bcb28aa19..30c4467b4 100644 --- a/src/infosidebarpage.cpp +++ b/src/infosidebarpage.cpp @@ -69,7 +69,7 @@ InfoSidebarPage::InfoSidebarPage(QWidget* parent) : // preview m_preview = new PixmapViewer(this); m_preview->setMinimumWidth(KIconLoader::SizeEnormous); - m_preview->setFixedHeight(KIconLoader::SizeEnormous); + m_preview->setMinimumHeight(KIconLoader::SizeEnormous); // name m_nameLabel = new QLabel(this); @@ -169,6 +169,12 @@ void InfoSidebarPage::resizeEvent(QResizeEvent* event) const int maxWidth = event->size().width() - KDialog::spacingHint() * 4; m_nameLabel->setMaximumWidth(maxWidth); m_infoLabel->setMaximumWidth(maxWidth); + + // try to increase the preview as large as possible + m_preview->setSizeHint(QSize(maxWidth, maxWidth)); + m_urlCandidate = m_shownUrl; // reset the URL candidate if a resizing is done + m_timer->start(TimerDelay); + SidebarPage::resizeEvent(event); } @@ -196,7 +202,7 @@ void InfoSidebarPage::showItemInfo() KIconLoader iconLoader; QPixmap icon = iconLoader.loadIcon("system-run", KIconLoader::NoGroup, - KIconLoader::SizeEnormous); + m_preview->width()); m_preview->setPixmap(icon); m_nameLabel->setText(i18ncp("@info", "%1 item selected", "%1 items selected", selectedItems.count())); } else if (!applyPlace(file)) { @@ -209,7 +215,7 @@ void InfoSidebarPage::showItemInfo() KIO::PreviewJob* job = KIO::filePreview(list, m_preview->width(), - KIconLoader::SizeEnormous, + m_preview->height(), 0, 0, true, diff --git a/src/kcategorizedview.cpp b/src/kcategorizedview.cpp deleted file mode 100644 index 648a712a5..000000000 --- a/src/kcategorizedview.cpp +++ /dev/null @@ -1,1596 +0,0 @@ -/** - * This file is part of the KDE project - * Copyright (C) 2007 Rafael Fernández López <[email protected]> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "kcategorizedview.h" -#include "kcategorizedview_p.h" - -#include <math.h> // trunc on C99 compliant systems -#include <kdefakes.h> // trunc for not C99 compliant systems - -#include <QPainter> -#include <QScrollBar> -#include <QPaintEvent> - -#include <kstyle.h> - -#include "kcategorydrawer.h" -#include "kcategorizedsortfilterproxymodel.h" - -// By defining DOLPHIN_DRAGANDDROP the custom drag and drop implementation of -// KCategorizedView is bypassed to have a consistent drag and drop look for all -// views. Hopefully transparent pixmaps for drag objects will be supported in -// Qt 4.4, so that this workaround can be skipped. -#define DOLPHIN_DRAGANDDROP - -KCategorizedView::Private::Private(KCategorizedView *listView) - : listView(listView) - , categoryDrawer(0) - , biggestItemSize(QSize(0, 0)) - , mouseButtonPressed(false) - , rightMouseButtonPressed(false) - , isDragging(false) - , dragLeftViewport(false) - , proxyModel(0) -{ -} - -KCategorizedView::Private::~Private() -{ -} - -const QModelIndexList &KCategorizedView::Private::intersectionSet(const QRect &rect) -{ - QModelIndex index; - QRect indexVisualRect; - - intersectedIndexes.clear(); - - int itemHeight; - - if (listView->gridSize().isEmpty()) - { - itemHeight = biggestItemSize.height(); - } - else - { - itemHeight = listView->gridSize().height(); - } - - // Lets find out where we should start - int top = proxyModel->rowCount() - 1; - int bottom = 0; - int middle = (top + bottom) / 2; - while (bottom <= top) - { - middle = (top + bottom) / 2; - - index = proxyModel->index(middle, 0); - indexVisualRect = visualRect(index); - // We need the whole height (not only the visualRect). This will help us to update - // all needed indexes correctly (ereslibre) - indexVisualRect.setHeight(indexVisualRect.height() + (itemHeight - indexVisualRect.height())); - - if (qMax(indexVisualRect.topLeft().y(), - indexVisualRect.bottomRight().y()) < qMin(rect.topLeft().y(), - rect.bottomRight().y())) - { - bottom = middle + 1; - } - else - { - top = middle - 1; - } - } - - for (int i = middle; i < proxyModel->rowCount(); i++) - { - index = proxyModel->index(i, 0); - indexVisualRect = visualRect(index); - - if (rect.intersects(indexVisualRect)) - intersectedIndexes.append(index); - - // If we passed next item, stop searching for hits - if (qMax(rect.bottomRight().y(), rect.topLeft().y()) < - qMin(indexVisualRect.topLeft().y(), - indexVisualRect.bottomRight().y())) - break; - } - - return intersectedIndexes; -} - -QRect KCategorizedView::Private::visualRectInViewport(const QModelIndex &index) const -{ - if (!index.isValid()) - return QRect(); - - QString curCategory = elementsInfo[index.row()].category; - - QRect retRect; - - if (listView->layoutDirection() == Qt::LeftToRight) - { - retRect = QRect(listView->spacing(), listView->spacing() * 2 + - categoryDrawer->categoryHeight(index, listView->viewOptions()), 0, 0); - } - else - { - retRect = QRect(listView->viewport()->width() - listView->spacing(), listView->spacing() * 2 + - categoryDrawer->categoryHeight(index, listView->viewOptions()), 0, 0); - } - - int viewportWidth = listView->viewport()->width() - listView->spacing(); - - int itemHeight; - int itemWidth; - - if (listView->gridSize().isEmpty()) - { - itemHeight = biggestItemSize.height(); - itemWidth = biggestItemSize.width(); - } - else - { - itemHeight = listView->gridSize().height(); - itemWidth = listView->gridSize().width(); - } - - int itemWidthPlusSeparation = listView->spacing() + itemWidth; - int elementsPerRow = viewportWidth / itemWidthPlusSeparation; - if (!elementsPerRow) - elementsPerRow++; - - int column = elementsInfo[index.row()].relativeOffsetToCategory % elementsPerRow; - int row = elementsInfo[index.row()].relativeOffsetToCategory / elementsPerRow; - - if (listView->layoutDirection() == Qt::LeftToRight) - { - retRect.setLeft(retRect.left() + column * listView->spacing() + - column * itemWidth); - } - else - { - retRect.setLeft(retRect.right() - column * listView->spacing() - - column * itemWidth - itemWidth); - - retRect.setRight(retRect.right() - column * listView->spacing() - - column * itemWidth); - } - - foreach (const QString &category, categories) - { - if (category == curCategory) - break; - - float rows = (float) ((float) categoriesIndexes[category].count() / - (float) elementsPerRow); - - int rowsInt = categoriesIndexes[category].count() / elementsPerRow; - - if (rows - trunc(rows)) rowsInt++; - - retRect.setTop(retRect.top() + - (rowsInt * itemHeight) + - categoryDrawer->categoryHeight(index, listView->viewOptions()) + - listView->spacing() * 2); - - if (listView->gridSize().isEmpty()) - { - retRect.setTop(retRect.top() + - (rowsInt * listView->spacing())); - } - } - - if (listView->gridSize().isEmpty()) - { - retRect.setTop(retRect.top() + row * listView->spacing() + - (row * itemHeight)); - } - else - { - retRect.setTop(retRect.top() + (row * itemHeight)); - } - - retRect.setWidth(itemWidth); - - QModelIndex heightIndex = proxyModel->index(index.row(), 0); - if (listView->gridSize().isEmpty()) - { - retRect.setHeight(listView->sizeHintForIndex(heightIndex).height()); - } - else - { - retRect.setHeight(qMin(listView->sizeHintForIndex(heightIndex).height(), - listView->gridSize().height())); - } - - return retRect; -} - -QRect KCategorizedView::Private::visualCategoryRectInViewport(const QString &category) - const -{ - QRect retRect(listView->spacing(), - listView->spacing(), - listView->viewport()->width() - listView->spacing() * 2, - 0); - - if (!proxyModel->rowCount() || !categories.contains(category)) - return QRect(); - - QModelIndex index = proxyModel->index(0, 0, QModelIndex()); - - int viewportWidth = listView->viewport()->width() - listView->spacing(); - - int itemHeight; - int itemWidth; - - if (listView->gridSize().isEmpty()) - { - itemHeight = biggestItemSize.height(); - itemWidth = biggestItemSize.width(); - } - else - { - itemHeight = listView->gridSize().height(); - itemWidth = listView->gridSize().width(); - } - - int itemWidthPlusSeparation = listView->spacing() + itemWidth; - int elementsPerRow = viewportWidth / itemWidthPlusSeparation; - - if (!elementsPerRow) - elementsPerRow++; - - foreach (const QString &itCategory, categories) - { - if (itCategory == category) - break; - - float rows = (float) ((float) categoriesIndexes[itCategory].count() / - (float) elementsPerRow); - int rowsInt = categoriesIndexes[itCategory].count() / elementsPerRow; - - if (rows - trunc(rows)) rowsInt++; - - retRect.setTop(retRect.top() + - (rowsInt * itemHeight) + - categoryDrawer->categoryHeight(index, listView->viewOptions()) + - listView->spacing() * 2); - - if (listView->gridSize().isEmpty()) - { - retRect.setTop(retRect.top() + - (rowsInt * listView->spacing())); - } - } - - retRect.setHeight(categoryDrawer->categoryHeight(index, listView->viewOptions())); - - return retRect; -} - -// We're sure elementsPosition doesn't contain index -const QRect &KCategorizedView::Private::cacheIndex(const QModelIndex &index) -{ - QRect rect = visualRectInViewport(index); - elementsPosition[index.row()] = rect; - - return elementsPosition[index.row()]; -} - -// We're sure categoriesPosition doesn't contain category -const QRect &KCategorizedView::Private::cacheCategory(const QString &category) -{ - QRect rect = visualCategoryRectInViewport(category); - categoriesPosition[category] = rect; - - return categoriesPosition[category]; -} - -const QRect &KCategorizedView::Private::cachedRectIndex(const QModelIndex &index) -{ - if (elementsPosition.contains(index.row())) // If we have it cached - { // return it - return elementsPosition[index.row()]; - } - else // Otherwise, cache it - { // and return it - return cacheIndex(index); - } -} - -const QRect &KCategorizedView::Private::cachedRectCategory(const QString &category) -{ - if (categoriesPosition.contains(category)) // If we have it cached - { // return it - return categoriesPosition[category]; - } - else // Otherwise, cache it and - { // return it - return cacheCategory(category); - } -} - -QRect KCategorizedView::Private::visualRect(const QModelIndex &index) -{ - QRect retRect = cachedRectIndex(index); - int dx = -listView->horizontalOffset(); - int dy = -listView->verticalOffset(); - retRect.adjust(dx, dy, dx, dy); - - return retRect; -} - -QRect KCategorizedView::Private::categoryVisualRect(const QString &category) -{ - QRect retRect = cachedRectCategory(category); - int dx = -listView->horizontalOffset(); - int dy = -listView->verticalOffset(); - retRect.adjust(dx, dy, dx, dy); - - return retRect; -} - -void KCategorizedView::Private::drawNewCategory(const QModelIndex &index, - int sortRole, - const QStyleOption &option, - QPainter *painter) -{ - if (!index.isValid()) - { - return; - } - - QStyleOption optionCopy = option; - const QString category = proxyModel->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString(); - - optionCopy.state &= ~QStyle::State_Selected; - - if ((listView->selectionMode() != SingleSelection) && (listView->selectionMode() != NoSelection)) { - if ((category == hoveredCategory) && !mouseButtonPressed) - { - optionCopy.state |= QStyle::State_MouseOver; - } - else if ((category == hoveredCategory) && mouseButtonPressed) - { - QPoint initialPressPosition = listView->viewport()->mapFromGlobal(QCursor::pos()); - initialPressPosition.setY(initialPressPosition.y() + listView->verticalOffset()); - initialPressPosition.setX(initialPressPosition.x() + listView->horizontalOffset()); - - if (initialPressPosition == this->initialPressPosition) - { - optionCopy.state |= QStyle::State_Selected; - } - } - } - - categoryDrawer->drawCategory(index, - sortRole, - optionCopy, - painter); -} - - -void KCategorizedView::Private::updateScrollbars() -{ - // find the last index in the last category - QModelIndex lastIndex = categoriesIndexes.isEmpty() ? QModelIndex() : categoriesIndexes[categories.last()].last(); - - int lastItemBottom = cachedRectIndex(lastIndex).top() + - listView->spacing() + (listView->gridSize().isEmpty() ? biggestItemSize.height() : listView->gridSize().height()) - listView->viewport()->height(); - - listView->horizontalScrollBar()->setRange(0, 0); - - listView->verticalScrollBar()->setSingleStep(listView->viewport()->height() / 10); - listView->verticalScrollBar()->setPageStep(listView->viewport()->height()); - listView->verticalScrollBar()->setRange(0, lastItemBottom); -} - -void KCategorizedView::Private::drawDraggedItems(QPainter *painter) -{ - QStyleOptionViewItemV3 option = listView->viewOptions(); - option.state &= ~QStyle::State_MouseOver; - foreach (const QModelIndex &index, listView->selectionModel()->selectedIndexes()) - { - const int dx = mousePosition.x() - initialPressPosition.x() + listView->horizontalOffset(); - const int dy = mousePosition.y() - initialPressPosition.y() + listView->verticalOffset(); - - option.rect = visualRect(index); - option.rect.adjust(dx, dy, dx, dy); - - if (option.rect.intersects(listView->viewport()->rect())) - { - listView->itemDelegate(index)->paint(painter, option, index); - } - } -} - -void KCategorizedView::Private::layoutChanged(bool forceItemReload) -{ - if ((listView->viewMode() == KCategorizedView::IconMode) && proxyModel && - categoryDrawer && proxyModel->isCategorizedModel() && - ((forceItemReload || - (modelSortRole != proxyModel->sortRole()) || - (modelSortColumn != proxyModel->sortColumn()) || - (modelSortOrder != proxyModel->sortOrder()) || - (modelLastRowCount != proxyModel->rowCount()) || - (modelCategorized != proxyModel->isCategorizedModel())))) - { - // Force the view to update all elements - listView->rowsInsertedArtifficial(QModelIndex(), 0, proxyModel->rowCount() - 1); - - if (!forceItemReload) - { - modelSortRole = proxyModel->sortRole(); - modelSortColumn = proxyModel->sortColumn(); - modelSortOrder = proxyModel->sortOrder(); - modelLastRowCount = proxyModel->rowCount(); - modelCategorized = proxyModel->isCategorizedModel(); - } - } - else if ((listView->viewMode() == KCategorizedView::IconMode) && proxyModel && - categoryDrawer && proxyModel->isCategorizedModel()) - { - updateScrollbars(); - } -} - -void KCategorizedView::Private::drawDraggedItems() -{ - QRect rectToUpdate; - QRect currentRect; - foreach (const QModelIndex &index, listView->selectionModel()->selectedIndexes()) - { - int dx = mousePosition.x() - initialPressPosition.x() + listView->horizontalOffset(); - int dy = mousePosition.y() - initialPressPosition.y() + listView->verticalOffset(); - - currentRect = visualRect(index); - currentRect.adjust(dx, dy, dx, dy); - - if (currentRect.intersects(listView->viewport()->rect())) - { - rectToUpdate = rectToUpdate.united(currentRect); - } - } - - listView->viewport()->update(lastDraggedItemsRect.united(rectToUpdate)); - - lastDraggedItemsRect = rectToUpdate; -} - - -//============================================================================== - - -KCategorizedView::KCategorizedView(QWidget *parent) - : QListView(parent) - , d(new Private(this)) -{ -} - -KCategorizedView::~KCategorizedView() -{ - delete d; -} - -void KCategorizedView::setGridSize(const QSize &size) -{ - QListView::setGridSize(size); - - d->layoutChanged(true); -} - -void KCategorizedView::setModel(QAbstractItemModel *model) -{ - d->lastSelection = QItemSelection(); - d->forcedSelectionPosition = 0; - d->elementsInfo.clear(); - d->elementsPosition.clear(); - d->categoriesIndexes.clear(); - d->categoriesPosition.clear(); - d->categories.clear(); - d->intersectedIndexes.clear(); - d->modelIndexList.clear(); - d->hovered = QModelIndex(); - d->mouseButtonPressed = false; - d->rightMouseButtonPressed = false; - - if (d->proxyModel) - { - QObject::disconnect(d->proxyModel, - SIGNAL(layoutChanged()), - this, SLOT(slotLayoutChanged())); - - QObject::disconnect(d->proxyModel, - SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(slotLayoutChanged())); - - QObject::disconnect(d->proxyModel, - SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(rowsRemoved(QModelIndex,int,int))); - } - - QListView::setModel(model); - - d->proxyModel = dynamic_cast<KCategorizedSortFilterProxyModel*>(model); - - if (d->proxyModel) - { - d->modelSortRole = d->proxyModel->sortRole(); - d->modelSortColumn = d->proxyModel->sortColumn(); - d->modelSortOrder = d->proxyModel->sortOrder(); - d->modelLastRowCount = d->proxyModel->rowCount(); - d->modelCategorized = d->proxyModel->isCategorizedModel(); - - QObject::connect(d->proxyModel, - SIGNAL(layoutChanged()), - this, SLOT(slotLayoutChanged())); - - QObject::connect(d->proxyModel, - SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(slotLayoutChanged())); - - QObject::connect(d->proxyModel, - SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(rowsRemoved(QModelIndex,int,int))); - - if (d->proxyModel->rowCount()) - { - d->layoutChanged(true); - } - } - else - { - d->modelCategorized = false; - } -} - -QRect KCategorizedView::visualRect(const QModelIndex &index) const -{ - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - return QListView::visualRect(index); - } - - if (!qobject_cast<const QSortFilterProxyModel*>(index.model())) - { - return d->visualRect(d->proxyModel->mapFromSource(index)); - } - - return d->visualRect(index); -} - -KCategoryDrawer *KCategorizedView::categoryDrawer() const -{ - return d->categoryDrawer; -} - -void KCategorizedView::setCategoryDrawer(KCategoryDrawer *categoryDrawer) -{ - d->lastSelection = QItemSelection(); - d->forcedSelectionPosition = 0; - d->elementsInfo.clear(); - d->elementsPosition.clear(); - d->categoriesIndexes.clear(); - d->categoriesPosition.clear(); - d->categories.clear(); - d->intersectedIndexes.clear(); - d->modelIndexList.clear(); - d->hovered = QModelIndex(); - d->mouseButtonPressed = false; - d->rightMouseButtonPressed = false; - - if (!categoryDrawer && d->proxyModel) - { - QObject::disconnect(d->proxyModel, - SIGNAL(layoutChanged()), - this, SLOT(slotLayoutChanged())); - - QObject::disconnect(d->proxyModel, - SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(slotLayoutChanged())); - - QObject::disconnect(d->proxyModel, - SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(rowsRemoved(QModelIndex,int,int))); - } - else if (categoryDrawer && d->proxyModel) - { - QObject::connect(d->proxyModel, - SIGNAL(layoutChanged()), - this, SLOT(slotLayoutChanged())); - - QObject::connect(d->proxyModel, - SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(slotLayoutChanged())); - - QObject::connect(d->proxyModel, - SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(rowsRemoved(QModelIndex,int,int))); - } - - d->categoryDrawer = categoryDrawer; - - if (categoryDrawer) - { - if (d->proxyModel) - { - if (d->proxyModel->rowCount()) - { - d->layoutChanged(true); - } - } - } - else - { - updateGeometries(); - } -} - -QModelIndex KCategorizedView::indexAt(const QPoint &point) const -{ - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - return QListView::indexAt(point); - } - - QModelIndex index; - - QModelIndexList item = d->intersectionSet(QRect(point, point)); - - if (item.count() == 1) - { - index = item[0]; - } - - return index; -} - -void KCategorizedView::reset() -{ - QListView::reset(); - - d->lastSelection = QItemSelection(); - d->forcedSelectionPosition = 0; - d->elementsInfo.clear(); - d->elementsPosition.clear(); - d->categoriesIndexes.clear(); - d->categoriesPosition.clear(); - d->categories.clear(); - d->intersectedIndexes.clear(); - d->modelIndexList.clear(); - d->hovered = QModelIndex(); - d->biggestItemSize = QSize(0, 0); - d->mouseButtonPressed = false; - d->rightMouseButtonPressed = false; -} - -void KCategorizedView::paintEvent(QPaintEvent *event) -{ - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - QListView::paintEvent(event); - return; - } - - QStyleOptionViewItemV3 option = viewOptions(); - option.widget = this; - if (wordWrap()) - { - option.features |= QStyleOptionViewItemV2::WrapText; - } - - QPainter painter(viewport()); - QRect area = event->rect(); - const bool focus = (hasFocus() || viewport()->hasFocus()) && - currentIndex().isValid(); - const QStyle::State state = option.state; - const bool enabled = (state & QStyle::State_Enabled) != 0; - - painter.save(); - - QModelIndexList dirtyIndexes = d->intersectionSet(area); - foreach (const QModelIndex &index, dirtyIndexes) - { - option.state = state; - option.rect = visualRect(index); - - if (selectionModel() && selectionModel()->isSelected(index)) - { - option.state |= QStyle::State_Selected; - } - - if (enabled) - { - QPalette::ColorGroup cg; - if ((d->proxyModel->flags(index) & Qt::ItemIsEnabled) == 0) - { - option.state &= ~QStyle::State_Enabled; - cg = QPalette::Disabled; - } - else - { - cg = QPalette::Normal; - } - option.palette.setCurrentColorGroup(cg); - } - - if (focus && currentIndex() == index) - { - option.state |= QStyle::State_HasFocus; - if (this->state() == EditingState) - option.state |= QStyle::State_Editing; - } - - // we are only interested to give the mouse over feedback when no - // dragging is happening (ereslibre) - if ((index == d->hovered) && !d->mouseButtonPressed && - (this->state() == QAbstractItemView::NoState)) - option.state |= QStyle::State_MouseOver; - else - option.state &= ~QStyle::State_MouseOver; - - itemDelegate(index)->paint(&painter, option, index); - } - - // Redraw categories - QStyleOptionViewItem otherOption; - bool intersectedInThePast = false; - foreach (const QString &category, d->categories) - { - otherOption = option; - otherOption.rect = d->categoryVisualRect(category); - otherOption.state &= ~QStyle::State_MouseOver; - - if (otherOption.rect.intersects(area)) - { - intersectedInThePast = true; - - QModelIndex indexToDraw = d->proxyModel->index(d->categoriesIndexes[category][0].row(), d->proxyModel->sortColumn()); - - d->drawNewCategory(indexToDraw, - d->proxyModel->sortRole(), otherOption, &painter); - } - else if (intersectedInThePast) - { - break; // the visible area has been finished, we don't need to keep asking, the rest won't intersect - // this is doable because we know that categories are correctly ordered on the list - } - } - - if ((selectionMode() != SingleSelection) && (selectionMode() != NoSelection)) - { - if (d->mouseButtonPressed && !d->isDragging) - { - QPoint start, end, initialPressPosition; - - initialPressPosition = d->initialPressPosition; - - initialPressPosition.setY(initialPressPosition.y() - verticalOffset()); - initialPressPosition.setX(initialPressPosition.x() - horizontalOffset()); - - if (d->initialPressPosition.x() > d->mousePosition.x() || - d->initialPressPosition.y() > d->mousePosition.y()) - { - start = d->mousePosition; - end = initialPressPosition; - } - else - { - start = initialPressPosition; - end = d->mousePosition; - } - - QStyleOptionRubberBand yetAnotherOption; - yetAnotherOption.initFrom(this); - yetAnotherOption.shape = QRubberBand::Rectangle; - yetAnotherOption.opaque = false; - yetAnotherOption.rect = QRect(start, end).intersected(viewport()->rect().adjusted(-16, -16, 16, 16)); - painter.save(); - style()->drawControl(QStyle::CE_RubberBand, &yetAnotherOption, &painter); - painter.restore(); - } - } - - if (d->isDragging && !d->dragLeftViewport) - { - painter.setOpacity(0.5); - d->drawDraggedItems(&painter); - } - - painter.restore(); -} - -void KCategorizedView::resizeEvent(QResizeEvent *event) -{ - QListView::resizeEvent(event); - - // Clear the items positions cache - d->elementsPosition.clear(); - d->categoriesPosition.clear(); - d->forcedSelectionPosition = 0; - - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - return; - } - - d->updateScrollbars(); -} - -void KCategorizedView::setSelection(const QRect &rect, - QItemSelectionModel::SelectionFlags flags) -{ - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - QListView::setSelection(rect, flags); - return; - } - - if (!flags) - return; - - if (flags & QItemSelectionModel::Clear) - { - selectionModel()->clear(); - d->lastSelection.clear(); - } - - QModelIndexList dirtyIndexes = d->intersectionSet(rect); - - // no items affected, just leave - if (!dirtyIndexes.count()) - { - selectionModel()->select(d->lastSelection, QItemSelectionModel::SelectCurrent); - - return; - } - - QModelIndex topLeft; - QModelIndex bottomRight; - - if (d->mouseButtonPressed || d->rightMouseButtonPressed) // selection with click + drag - { - QItemSelection selection; - - QModelIndex prev = dirtyIndexes[0]; - QModelIndex first = prev; - foreach (const QModelIndex &index, dirtyIndexes) - { - // we have a different interval. non-contiguous items - if ((index.row() - prev.row()) > 1) { - selection << QItemSelectionRange(first, prev); - - first = index; - } - - prev = index; - } - - selection << QItemSelectionRange(first, prev); - - if (flags & QItemSelectionModel::Current) - { - if (rect.topLeft() == rect.bottomRight()) - { - selectionModel()->setCurrentIndex(indexAt(rect.topLeft()), QItemSelectionModel::NoUpdate); - } - - selection.merge(d->lastSelection, flags); - } - else - { - selection.merge(selectionModel()->selection(), flags); - - selectionModel()->select(selection, QItemSelectionModel::SelectCurrent); - - return; - } - - selectionModel()->select(selection, flags); - } - else // selection with click + keyboard keys - { - QModelIndex topLeftIndex = indexAt(QPoint(rect.topLeft().x(), - rect.topLeft().y())); - QModelIndex bottomRightIndex = indexAt(QPoint(rect.bottomRight().x(), - rect.bottomRight().y())); - - // keyboard selection comes "upside down". Let's normalize it - if (topLeftIndex.row() > bottomRightIndex.row()) - { - QModelIndex auxIndex = topLeftIndex; - topLeftIndex = bottomRightIndex; - bottomRightIndex = auxIndex; - } - - int viewportWidth = viewport()->width() - spacing(); - int itemWidth; - - if (gridSize().isEmpty()) - { - itemWidth = d->biggestItemSize.width(); - } - else - { - itemWidth = gridSize().width(); - } - - int itemWidthPlusSeparation = spacing() + itemWidth; - int elementsPerRow = viewportWidth / itemWidthPlusSeparation; - if (!elementsPerRow) - elementsPerRow++; - - QModelIndexList theoricDirty(dirtyIndexes); - dirtyIndexes.clear(); - int first = model()->rowCount(); - int last = 0; - - foreach (const QModelIndex &index, theoricDirty) - { - if ((index.row() < first) && - ((((topLeftIndex.row() / elementsPerRow) == (index.row() / elementsPerRow)) && - ((topLeftIndex.row() % elementsPerRow) <= (index.row() % elementsPerRow))) || - (topLeftIndex.row() / elementsPerRow) != (index.row() / elementsPerRow))) - { - first = index.row(); - topLeft = index; - } - - if ((index.row() > last) && - ((((bottomRightIndex.row() / elementsPerRow) == (index.row() / elementsPerRow)) && - ((bottomRightIndex.row() % elementsPerRow) >= (index.row() % elementsPerRow))) || - (bottomRightIndex.row() / elementsPerRow) != (index.row() / elementsPerRow))) - { - last = index.row(); - bottomRight = index; - } - } - - for (int i = first; i <= last; i++) - { - dirtyIndexes << model()->index(i, theoricDirty[0].column(), theoricDirty[0].parent()); - } - - QItemSelection selection(topLeft, bottomRight); - - selectionModel()->select(selection, flags); - } -} - -void KCategorizedView::mouseMoveEvent(QMouseEvent *event) -{ - QListView::mouseMoveEvent(event); - - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - return; - } - - QModelIndexList item = d->intersectionSet(QRect(event->pos(), event->pos())); - - if (item.count() == 1) - { - d->hovered = item[0]; - } - else - { - d->hovered = QModelIndex(); - } - - const QString previousHoveredCategory = d->hoveredCategory; - - d->mousePosition = event->pos(); - d->hoveredCategory = QString(); - - // Redraw categories - foreach (const QString &category, d->categories) - { - if (d->categoryVisualRect(category).intersects(QRect(event->pos(), event->pos()))) - { - d->hoveredCategory = category; - viewport()->update(d->categoryVisualRect(category)); - } - else if ((category == previousHoveredCategory) && - (!d->categoryVisualRect(previousHoveredCategory).intersects(QRect(event->pos(), event->pos())))) - { - viewport()->update(d->categoryVisualRect(category)); - } - } - - QRect rect; - if (d->mouseButtonPressed && !d->isDragging) - { - QPoint start, end, initialPressPosition; - - initialPressPosition = d->initialPressPosition; - - initialPressPosition.setY(initialPressPosition.y() - verticalOffset()); - initialPressPosition.setX(initialPressPosition.x() - horizontalOffset()); - - if (d->initialPressPosition.x() > d->mousePosition.x() || - d->initialPressPosition.y() > d->mousePosition.y()) - { - start = d->mousePosition; - end = initialPressPosition; - } - else - { - start = initialPressPosition; - end = d->mousePosition; - } - - rect = QRect(start, end).adjusted(-16, -16, 16, 16); - rect = rect.united(QRect(start, end).adjusted(16, 16, -16, -16)).intersected(viewport()->rect()); - - viewport()->update(rect); - } -} - -void KCategorizedView::mousePressEvent(QMouseEvent *event) -{ - d->dragLeftViewport = false; - - if (event->button() == Qt::LeftButton) - { - d->mouseButtonPressed = true; - - d->initialPressPosition = event->pos(); - d->initialPressPosition.setY(d->initialPressPosition.y() + - verticalOffset()); - d->initialPressPosition.setX(d->initialPressPosition.x() + - horizontalOffset()); - } - else if (event->button() == Qt::RightButton) - { - d->rightMouseButtonPressed = true; - } - - QListView::mousePressEvent(event); - - d->lastSelection = selectionModel()->selection(); - - viewport()->update(d->categoryVisualRect(d->hoveredCategory)); -} - -void KCategorizedView::mouseReleaseEvent(QMouseEvent *event) -{ - d->mouseButtonPressed = false; - d->rightMouseButtonPressed = false; - - QListView::mouseReleaseEvent(event); - - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - return; - } - - QPoint initialPressPosition = viewport()->mapFromGlobal(QCursor::pos()); - initialPressPosition.setY(initialPressPosition.y() + verticalOffset()); - initialPressPosition.setX(initialPressPosition.x() + horizontalOffset()); - - if ((selectionMode() != SingleSelection) && (selectionMode() != NoSelection) && - (initialPressPosition == d->initialPressPosition)) - { - foreach(const QString &category, d->categories) - { - if (d->categoryVisualRect(category).contains(event->pos())) - { - QItemSelection selection = selectionModel()->selection(); - QModelIndexList indexList = d->categoriesIndexes[category]; - - foreach (const QModelIndex &index, indexList) - { - QModelIndex selectIndex = index.model()->index(index.row(), 0); - - selection << QItemSelectionRange(selectIndex); - } - - selectionModel()->select(selection, QItemSelectionModel::SelectCurrent); - - break; - } - } - } - - QRect rect; - if (!d->isDragging) - { - QPoint start, end, initialPressPosition; - - initialPressPosition = d->initialPressPosition; - - initialPressPosition.setY(initialPressPosition.y() - verticalOffset()); - initialPressPosition.setX(initialPressPosition.x() - horizontalOffset()); - - if (d->initialPressPosition.x() > d->mousePosition.x() || - d->initialPressPosition.y() > d->mousePosition.y()) - { - start = d->mousePosition; - end = initialPressPosition; - } - else - { - start = initialPressPosition; - end = d->mousePosition; - } - - rect = QRect(start, end).adjusted(-16, -16, 16, 16); - rect = rect.united(QRect(start, end).adjusted(16, 16, -16, -16)).intersected(viewport()->rect()); - - viewport()->update(rect); - } - - if (d->hovered.isValid()) - viewport()->update(visualRect(d->hovered)); - else if (!d->hoveredCategory.isEmpty()) - viewport()->update(d->categoryVisualRect(d->hoveredCategory)); -} - -void KCategorizedView::leaveEvent(QEvent *event) -{ - d->hovered = QModelIndex(); - d->hoveredCategory = QString(); - - QListView::leaveEvent(event); -} - -void KCategorizedView::startDrag(Qt::DropActions supportedActions) -{ - // FIXME: QAbstractItemView does far better here since it sets the - // pixmap of selected icons to the dragging cursor, but it sets a non - // ARGB window so it is no transparent. Use QAbstractItemView when - // this is fixed on Qt. - // QAbstractItemView::startDrag(supportedActions); -#if !defined(DOLPHIN_DRAGANDDROP) - QListView::startDrag(supportedActions); -#endif - - d->isDragging = false; - d->mouseButtonPressed = false; - d->rightMouseButtonPressed = false; - - viewport()->update(d->lastDraggedItemsRect); -} - -void KCategorizedView::dragMoveEvent(QDragMoveEvent *event) -{ - d->mousePosition = event->pos(); - - if (d->mouseButtonPressed) - { - d->isDragging = true; - } - else - { - d->isDragging = false; - } - - d->dragLeftViewport = false; - -#if defined(DOLPHIN_DRAGANDDROP) - QAbstractItemView::dragMoveEvent(event); -#else - QListView::dragMoveEvent(event); -#endif - - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - return; - } - - d->drawDraggedItems(); -} - -void KCategorizedView::dragLeaveEvent(QDragLeaveEvent *event) -{ - d->dragLeftViewport = true; - -#if defined(DOLPHIN_DRAGANDDROP) - QAbstractItemView::dragLeaveEvent(event); -#else - QListView::dragLeaveEvent(event); -#endif -} - -void KCategorizedView::dropEvent(QDropEvent *event) -{ -#if defined(DOLPHIN_DRAGANDDROP) - QAbstractItemView::dropEvent(event); -#else - QListView::dropEvent(event); -#endif -} - -QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction, - Qt::KeyboardModifiers modifiers) -{ - if ((viewMode() != KCategorizedView::IconMode) || - !d->proxyModel || - !d->categoryDrawer || - d->categories.isEmpty() || - !d->proxyModel->isCategorizedModel() - ) - { - return QListView::moveCursor(cursorAction, modifiers); - } - - int viewportWidth = viewport()->width() - spacing(); - int itemWidth; - - if (gridSize().isEmpty()) - { - itemWidth = d->biggestItemSize.width(); - } - else - { - itemWidth = gridSize().width(); - } - - int itemWidthPlusSeparation = spacing() + itemWidth; - int elementsPerRow = viewportWidth / itemWidthPlusSeparation; - if (!elementsPerRow) - elementsPerRow++; - - QModelIndex current = selectionModel()->currentIndex(); - - if (!current.isValid()) - { - if (cursorAction == MoveEnd) - { - current = model()->index(model()->rowCount() - 1, 0, QModelIndex()); - d->forcedSelectionPosition = d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow; - } - else - { - current = model()->index(0, 0, QModelIndex()); - d->forcedSelectionPosition = 0; - } - - return current; - } - else if (!current.isValid()) - { - return QModelIndex(); - } - - QString lastCategory = d->categories.first(); - QString theCategory = d->categories.first(); - QString afterCategory = d->categories.first(); - - bool hasToBreak = false; - foreach (const QString &category, d->categories) - { - if (hasToBreak) - { - afterCategory = category; - - break; - } - - if (category == d->elementsInfo[current.row()].category) - { - theCategory = category; - - hasToBreak = true; - } - - if (!hasToBreak) - { - lastCategory = category; - } - } - - switch (cursorAction) - { - case QAbstractItemView::MoveUp: { - if (d->elementsInfo[current.row()].relativeOffsetToCategory >= elementsPerRow) - { - int indexToMove = current.row(); - indexToMove -= qMin(((d->elementsInfo[current.row()].relativeOffsetToCategory) + d->forcedSelectionPosition), elementsPerRow - d->forcedSelectionPosition + (d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow)); - - return d->proxyModel->index(indexToMove, 0); - } - else - { - int lastCategoryLastRow = (d->categoriesIndexes[lastCategory].count() - 1) % elementsPerRow; - int indexToMove = current.row() - d->elementsInfo[current.row()].relativeOffsetToCategory; - - if (d->forcedSelectionPosition >= lastCategoryLastRow) - { - indexToMove -= 1; - } - else - { - indexToMove -= qMin((lastCategoryLastRow - d->forcedSelectionPosition + 1), d->forcedSelectionPosition + elementsPerRow + 1); - } - - return d->proxyModel->index(indexToMove, 0); - } - } - - case QAbstractItemView::MoveDown: { - if (d->elementsInfo[current.row()].relativeOffsetToCategory < (d->categoriesIndexes[theCategory].count() - 1 - ((d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow))) - { - int indexToMove = current.row(); - indexToMove += qMin(elementsPerRow, d->categoriesIndexes[theCategory].count() - 1 - d->elementsInfo[current.row()].relativeOffsetToCategory); - - return d->proxyModel->index(indexToMove, 0); - } - else - { - int afterCategoryLastRow = qMin(elementsPerRow, d->categoriesIndexes[afterCategory].count()); - int indexToMove = current.row() + (d->categoriesIndexes[theCategory].count() - d->elementsInfo[current.row()].relativeOffsetToCategory); - - if (d->forcedSelectionPosition >= afterCategoryLastRow) - { - indexToMove += afterCategoryLastRow - 1; - } - else - { - indexToMove += qMin(d->forcedSelectionPosition, elementsPerRow); - } - - return d->proxyModel->index(indexToMove, 0); - } - } - - case QAbstractItemView::MoveLeft: - if (layoutDirection() == Qt::RightToLeft) - { - if (!(d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow)) - return current; - - d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow; - -#if 0 //follow qt view behavior. lateral movements won't change visual row - if (d->forcedSelectionPosition < 0) - d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow; -#endif - - return d->proxyModel->index(current.row() + 1, 0); - } - - if (!(d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow)) - return current; - - d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow; - -#if 0 //follow qt view behavior. lateral movements won't change visual row - if (d->forcedSelectionPosition < 0) - d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow; -#endif - - return d->proxyModel->index(current.row() - 1, 0); - - case QAbstractItemView::MoveRight: - if (layoutDirection() == Qt::RightToLeft) - { - if (!(d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow)) - return current; - - d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow; - -#if 0 //follow qt view behavior. lateral movements won't change visual row - if (d->forcedSelectionPosition < 0) - d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow; -#endif - - return d->proxyModel->index(current.row() - 1, 0); - } - - if (!(d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow)) - return current; - - d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow; - -#if 0 //follow qt view behavior. lateral movements won't change visual row - if (d->forcedSelectionPosition < 0) - d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow; -#endif - - return d->proxyModel->index(current.row() + 1, 0); - - default: - break; - } - - return QListView::moveCursor(cursorAction, modifiers); -} - -void KCategorizedView::rowsInserted(const QModelIndex &parent, - int start, - int end) -{ - QListView::rowsInserted(parent, start, end); - - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - d->forcedSelectionPosition = 0; - d->elementsInfo.clear(); - d->elementsPosition.clear(); - d->categoriesIndexes.clear(); - d->categoriesPosition.clear(); - d->categories.clear(); - d->intersectedIndexes.clear(); - d->modelIndexList.clear(); - d->hovered = QModelIndex(); - d->biggestItemSize = QSize(0, 0); - d->mouseButtonPressed = false; - d->rightMouseButtonPressed = false; - - return; - } - - rowsInsertedArtifficial(parent, start, end); -} - -void KCategorizedView::rowsInsertedArtifficial(const QModelIndex &parent, - int start, - int end) -{ - Q_UNUSED(parent); - - d->forcedSelectionPosition = 0; - d->elementsInfo.clear(); - d->elementsPosition.clear(); - d->categoriesIndexes.clear(); - d->categoriesPosition.clear(); - d->categories.clear(); - d->intersectedIndexes.clear(); - d->modelIndexList.clear(); - d->hovered = QModelIndex(); - d->biggestItemSize = QSize(0, 0); - d->mouseButtonPressed = false; - d->rightMouseButtonPressed = false; - - if (start > end || end < 0 || start < 0 || !d->proxyModel->rowCount()) - { - return; - } - - // Add all elements mapped to the source model and explore categories - QString prevCategory = d->proxyModel->data(d->proxyModel->index(0, d->proxyModel->sortColumn()), KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString(); - QString lastCategory = prevCategory; - QModelIndexList modelIndexList; - struct Private::ElementInfo elementInfo; - int offset = -1; - for (int k = 0; k < d->proxyModel->rowCount(); ++k) - { - QModelIndex index = d->proxyModel->index(k, d->proxyModel->sortColumn()); - QModelIndex indexSize = d->proxyModel->index(k, 0); - - d->biggestItemSize = QSize(qMax(sizeHintForIndex(indexSize).width(), - d->biggestItemSize.width()), - qMax(sizeHintForIndex(indexSize).height(), - d->biggestItemSize.height())); - - d->modelIndexList << index; - - lastCategory = d->proxyModel->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString(); - - elementInfo.category = lastCategory; - - if (prevCategory != lastCategory) - { - offset = 0; - d->categoriesIndexes.insert(prevCategory, modelIndexList); - d->categories << prevCategory; - modelIndexList.clear(); - } - else - { - offset++; - } - - elementInfo.relativeOffsetToCategory = offset; - - modelIndexList << index; - prevCategory = lastCategory; - - d->elementsInfo.insert(index.row(), elementInfo); - } - - d->categoriesIndexes.insert(prevCategory, modelIndexList); - d->categories << prevCategory; - - d->updateScrollbars(); - - // FIXME: We need to safely save the last selection. This is on my TODO - // list (ereslibre). - selectionModel()->clear(); -} - -void KCategorizedView::rowsRemoved(const QModelIndex &parent, - int start, - int end) -{ - if ((viewMode() == KCategorizedView::IconMode) && d->proxyModel && - d->categoryDrawer && d->proxyModel->isCategorizedModel()) - { - // Force the view to update all elements - rowsInsertedArtifficial(QModelIndex(), 0, d->proxyModel->rowCount() - 1); - } -} - -void KCategorizedView::updateGeometries() -{ - if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel || - !d->categoryDrawer || !d->proxyModel->isCategorizedModel()) - { - QListView::updateGeometries(); - return; - } - - // Avoid QListView::updateGeometries(), since it will try to set another - // range to our scroll bars, what we don't want (ereslibre) - QAbstractItemView::updateGeometries(); -} - -void KCategorizedView::slotLayoutChanged() -{ - d->layoutChanged(); -} - -void KCategorizedView::currentChanged(const QModelIndex ¤t, - const QModelIndex &previous) -{ - // We need to update the forcedSelectionPosition property in order to correctly - // navigate after with keyboard using up & down keys - - int viewportWidth = viewport()->width() - spacing(); - - int itemHeight; - int itemWidth; - - if (gridSize().isEmpty()) - { - itemHeight = d->biggestItemSize.height(); - itemWidth = d->biggestItemSize.width(); - } - else - { - itemHeight = gridSize().height(); - itemWidth = gridSize().width(); - } - - int itemWidthPlusSeparation = spacing() + itemWidth; - int elementsPerRow = viewportWidth / itemWidthPlusSeparation; - if (!elementsPerRow) - elementsPerRow++; - - if (d->mouseButtonPressed || d->rightMouseButtonPressed) - d->forcedSelectionPosition = d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow; - - QListView::currentChanged(current, previous); -} - -#include "kcategorizedview.moc" diff --git a/src/kcategorizedview.h b/src/kcategorizedview.h deleted file mode 100644 index 015433ae3..000000000 --- a/src/kcategorizedview.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - * This file is part of the KDE project - * Copyright (C) 2007 Rafael Fernández López <[email protected]> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef KCATEGORIZEDVIEW_H -#define KCATEGORIZEDVIEW_H - -#include <QtGui/QListView> - -#include <libdolphin_export.h> - -class KCategoryDrawer; - -/** - * @short Item view for listing items - * - * KCategorizedView allows you to use it as it were a QListView. You can add an - * itemCategorizer to it, so your items became categorized depending on the - * KItemCategorizer inherited class rules. - * - * @see KItemCategorizer, KSortFilterProxyModel - * - * @author Rafael Fernández López <[email protected]> - */ -class LIBDOLPHINPRIVATE_EXPORT KCategorizedView - : public QListView -{ - Q_OBJECT - -public: - KCategorizedView(QWidget *parent = 0); - - ~KCategorizedView(); - - virtual void setModel(QAbstractItemModel *model); - - void setGridSize(const QSize &size); - - virtual QRect visualRect(const QModelIndex &index) const; - - KCategoryDrawer *categoryDrawer() const; - - void setCategoryDrawer(KCategoryDrawer *categoryDrawer); - - virtual QModelIndex indexAt(const QPoint &point) const; - -public Q_SLOTS: - virtual void reset(); - -protected: - virtual void paintEvent(QPaintEvent *event); - - virtual void resizeEvent(QResizeEvent *event); - - virtual void setSelection(const QRect &rect, - QItemSelectionModel::SelectionFlags flags); - - virtual void mouseMoveEvent(QMouseEvent *event); - - virtual void mousePressEvent(QMouseEvent *event); - - virtual void mouseReleaseEvent(QMouseEvent *event); - - virtual void leaveEvent(QEvent *event); - - virtual void startDrag(Qt::DropActions supportedActions); - - virtual void dragMoveEvent(QDragMoveEvent *event); - - virtual void dragLeaveEvent(QDragLeaveEvent *event); - - virtual void dropEvent(QDropEvent *event); - - virtual QModelIndex moveCursor(CursorAction cursorAction, - Qt::KeyboardModifiers modifiers); - -protected Q_SLOTS: - virtual void rowsInserted(const QModelIndex &parent, - int start, - int end); - - virtual void rowsInsertedArtifficial(const QModelIndex &parent, - int start, - int end); - - virtual void rowsRemoved(const QModelIndex &parent, - int start, - int end); - - virtual void updateGeometries(); - - virtual void slotLayoutChanged(); - - virtual void currentChanged(const QModelIndex ¤t, - const QModelIndex &previous); - - -private: - class Private; - Private *d; -}; - -#endif // KCATEGORIZEDVIEW_H diff --git a/src/kcategorizedview_p.h b/src/kcategorizedview_p.h deleted file mode 100644 index a18854ba3..000000000 --- a/src/kcategorizedview_p.h +++ /dev/null @@ -1,164 +0,0 @@ -/** - * This file is part of the KDE project - * Copyright (C) 2007 Rafael Fernández López <[email protected]> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef KCATEGORIZEDVIEW_P_H -#define KCATEGORIZEDVIEW_P_H - -class KCategorizedSortFilterProxyModel; -class KCategoryDrawer; - -/** - * @internal - */ -class KCategorizedView::Private -{ -public: - Private(KCategorizedView *listView); - ~Private(); - - - // Methods - - /** - * Returns the list of items that intersects with @p rect - */ - const QModelIndexList &intersectionSet(const QRect &rect); - - /** - * Gets the item rect in the viewport for @p index - */ - QRect visualRectInViewport(const QModelIndex &index) const; - - /** - * Returns the category rect in the viewport for @p category - */ - QRect visualCategoryRectInViewport(const QString &category) const; - - /** - * Caches and returns the rect that corresponds to @p index - */ - const QRect &cacheIndex(const QModelIndex &index); - - /** - * Caches and returns the rect that corresponds to @p category - */ - const QRect &cacheCategory(const QString &category); - - /** - * Returns the rect that corresponds to @p index - * @note If the rect is not cached, it becomes cached - */ - const QRect &cachedRectIndex(const QModelIndex &index); - - /** - * Returns the rect that corresponds to @p category - * @note If the rect is not cached, it becomes cached - */ - const QRect &cachedRectCategory(const QString &category); - - /** - * Returns the visual rect (taking in count x and y offsets) for @p index - * @note If the rect is not cached, it becomes cached - */ - QRect visualRect(const QModelIndex &index); - - /** - * Returns the visual rect (taking in count x and y offsets) for @p category - * @note If the rect is not cached, it becomes cached - */ - QRect categoryVisualRect(const QString &category); - - /** - * This method will draw a new category represented by index - * @param index on the rect specified by @p option.rect, with - * painter @p painter - */ - void drawNewCategory(const QModelIndex &index, - int sortRole, - const QStyleOption &option, - QPainter *painter); - - /** - * This method will update scrollbars ranges. Called when our model changes - * or when the view is resized - */ - void updateScrollbars(); - - /** - * This method will draw dragged items in the painting operation - */ - void drawDraggedItems(QPainter *painter); - - /** - * This method will determine which rect needs to be updated because of a - * dragging operation - */ - void drawDraggedItems(); - - void layoutChanged(bool forceItemReload = false); - - - // Attributes - - struct ElementInfo - { - QString category; - int relativeOffsetToCategory; - }; - - // Basic data - KCategorizedView *listView; - KCategoryDrawer *categoryDrawer; - QSize biggestItemSize; - - // Behavior data - bool mouseButtonPressed; - bool rightMouseButtonPressed; - bool isDragging; - bool dragLeftViewport; - QModelIndex hovered; - QString hoveredCategory; - QPoint initialPressPosition; - QPoint mousePosition; - int forcedSelectionPosition; - - // Cache data - // We cannot merge some of them into structs because it would affect - // performance - QHash<int, struct ElementInfo> elementsInfo; - QHash<int, QRect> elementsPosition; - QHash<QString, QModelIndexList> categoriesIndexes; - QHash<QString, QRect> categoriesPosition; - QStringList categories; - QModelIndexList intersectedIndexes; - QRect lastDraggedItemsRect; - int modelSortRole; - int modelSortColumn; - int modelLastRowCount; - bool modelCategorized; - Qt::SortOrder modelSortOrder; - QItemSelection lastSelection; - - // Attributes for speed reasons - KCategorizedSortFilterProxyModel *proxyModel; - QModelIndexList modelIndexList; -}; - -#endif // KCATEGORIZEDVIEW_P_H diff --git a/src/kcategorydrawer.cpp b/src/kcategorydrawer.cpp deleted file mode 100644 index 6d82bf96b..000000000 --- a/src/kcategorydrawer.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/** - * This file is part of the KDE project - * Copyright (C) 2007 Rafael Fernández López <[email protected]> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "kcategorydrawer.h" - -#include <QPainter> -#include <QStyleOption> - -#include <kiconloader.h> -#include <kcategorizedsortfilterproxymodel.h> - -KCategoryDrawer::KCategoryDrawer() -{ -} - -KCategoryDrawer::~KCategoryDrawer() -{ -} - -void KCategoryDrawer::drawCategory(const QModelIndex &index, - int /*sortRole*/, - const QStyleOption &option, - QPainter *painter) const -{ - const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString(); - - QColor color; - - if (option.state & QStyle::State_Selected) - { - color = option.palette.color(QPalette::HighlightedText); - } - else - { - color = option.palette.color(QPalette::Text); - } - - painter->save(); - painter->setRenderHint(QPainter::Antialiasing); - - if (option.state & QStyle::State_Selected) - { - QColor selected = option.palette.color(QPalette::Highlight); - - QLinearGradient gradient(option.rect.topLeft(), - option.rect.bottomRight()); - gradient.setColorAt(option.direction == Qt::LeftToRight ? 0 - : 1, selected); - gradient.setColorAt(option.direction == Qt::LeftToRight ? 1 - : 0, Qt::transparent); - - painter->fillRect(option.rect, gradient); - } - else if (option.state & QStyle::State_MouseOver) - { - QColor hover = option.palette.color(QPalette::Highlight).light(); - hover.setAlpha(88); - - QLinearGradient gradient(option.rect.topLeft(), - option.rect.bottomRight()); - gradient.setColorAt(option.direction == Qt::LeftToRight ? 0 - : 1, hover); - gradient.setColorAt(option.direction == Qt::LeftToRight ? 1 - : 0, Qt::transparent); - - painter->fillRect(option.rect, gradient); - } - - QFont painterFont = painter->font(); - painterFont.setWeight(QFont::Bold); - QFontMetrics metrics(painterFont); - painter->setFont(painterFont); - - QRect lineRect(option.rect.left(), - option.rect.bottom() - 1, - option.rect.width(), - 1); - - QLinearGradient gradient(option.rect.topLeft(), - option.rect.bottomRight()); - gradient.setColorAt(option.direction == Qt::LeftToRight ? 0 - : 1, color); - gradient.setColorAt(option.direction == Qt::LeftToRight ? 1 - : 0, Qt::transparent); - - painter->fillRect(lineRect, gradient); - - painter->setPen(color); - - painter->drawText(option.rect, Qt::AlignVCenter | Qt::AlignLeft, - metrics.elidedText(category, Qt::ElideRight, option.rect.width())); - - painter->restore(); -} - -int KCategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &option) const -{ - Q_UNUSED(index); - - return option.fontMetrics.height() + 4 /* 3 separator; 1 gradient */; -} diff --git a/src/kcategorydrawer.h b/src/kcategorydrawer.h deleted file mode 100644 index 6af0d73cd..000000000 --- a/src/kcategorydrawer.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * This file is part of the KDE project - * Copyright (C) 2007 Rafael Fernández López <[email protected]> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef KCATEGORYDRAWER_H -#define KCATEGORYDRAWER_H - -#include <libdolphin_export.h> - -class QPainter; -class QModelIndex; -class QStyleOption; - -class LIBDOLPHINPRIVATE_EXPORT KCategoryDrawer -{ -public: - KCategoryDrawer(); - - virtual ~KCategoryDrawer(); - - /** - * This method purpose is to draw a category represented by the given - * @param index with the given @param sortRole sorting role - * - * @note This method will be called one time per category, always with the - * first element in that category - */ - virtual void drawCategory(const QModelIndex &index, - int sortRole, - const QStyleOption &option, - QPainter *painter) const; - - virtual int categoryHeight(const QModelIndex &index, const QStyleOption &option) const; -}; - -#endif // KCATEGORYDRAWER_H diff --git a/src/main.cpp b/src/main.cpp index 3cc7c000b..b9e8997a7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,7 +33,7 @@ int main(int argc, char **argv) { KAboutData about("dolphin", 0, ki18nc("@title", "Dolphin"), - "1.0.1", + "1.0.99", ki18nc("@title", "File Manager"), KAboutData::License_GPL, ki18nc("@info:credit", "(C) 2006, 2007 Peter Penz")); diff --git a/src/pixmapviewer.cpp b/src/pixmapviewer.cpp index a7a593bb0..f535475aa 100644 --- a/src/pixmapviewer.cpp +++ b/src/pixmapviewer.cpp @@ -21,6 +21,7 @@ #include <kiconloader.h> +#include <QLayout> #include <QPainter> #include <QPixmap> #include <QKeyEvent> @@ -28,7 +29,8 @@ PixmapViewer::PixmapViewer(QWidget* parent, Transition transition) : QWidget(parent), m_transition(transition), - m_animationStep(0) + m_animationStep(0), + m_sizeHint() { setMinimumWidth(KIconLoader::SizeEnormous); setMinimumHeight(KIconLoader::SizeEnormous); @@ -72,6 +74,19 @@ void PixmapViewer::setPixmap(const QPixmap& pixmap) } } +void PixmapViewer::setSizeHint(const QSize& size) +{ + m_sizeHint = size; + if ((parentWidget() != 0) && (parentWidget()->layout() != 0)) { + parentWidget()->layout()->activate(); + } +} + +QSize PixmapViewer::sizeHint() const +{ + return m_sizeHint; +} + void PixmapViewer::paintEvent(QPaintEvent* event) { QWidget::paintEvent(event); diff --git a/src/pixmapviewer.h b/src/pixmapviewer.h index 01d8cf1c1..26e520aab 100644 --- a/src/pixmapviewer.h +++ b/src/pixmapviewer.h @@ -66,6 +66,13 @@ public: void setPixmap(const QPixmap& pixmap); const QPixmap& pixmap() const; + /** + * Sets the size hint to \a size and triggers a relayout + * of the parent widget. Per default no size hint is given. + */ + void setSizeHint(const QSize& size); + virtual QSize sizeHint() const; + protected: virtual void paintEvent(QPaintEvent* event); @@ -79,6 +86,7 @@ private: QTimeLine m_animation; Transition m_transition; int m_animationStep; + QSize m_sizeHint; }; inline const QPixmap& PixmapViewer::pixmap() const diff --git a/src/renamedialog.cpp b/src/renamedialog.cpp index adfc48676..fa5bf60e0 100644 --- a/src/renamedialog.cpp +++ b/src/renamedialog.cpp @@ -116,9 +116,9 @@ void RenameDialog::slotButtonClicked(int button) if (m_newName.isEmpty()) { m_errorString = i18nc("@info:status", "The new name is empty. A name with at least one character must be entered."); - } else if (!m_renameOneItem && m_newName.count('#') != 1) { + } else if (!m_renameOneItem && (m_newName.count('#') == 0)) { m_newName.truncate(0); - m_errorString = i18nc("@info:status", "The name must contain exactly one # character."); + m_errorString = i18nc("@info:status", "The name must contain at least one # character."); } } diff --git a/src/selectionmanager.cpp b/src/selectionmanager.cpp new file mode 100644 index 000000000..02125d7c9 --- /dev/null +++ b/src/selectionmanager.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 * + ***************************************************************************/ + +#include "selectionmanager.h" + +#include "dolphinmodel.h" +#include "selectiontoggle.h" +#include <kdirmodel.h> +#include <kiconeffect.h> + +#include <QAbstractButton> +#include <QAbstractItemView> +#include <QAbstractProxyModel> +#include <QModelIndex> +#include <QPainter> +#include <QPaintEvent> +#include <QRect> +#include <QTimeLine> + +SelectionManager::SelectionManager(QAbstractItemView* parent) : + QObject(parent), + m_view(parent), + m_toggle(0) +{ + connect(parent, SIGNAL(entered(const QModelIndex&)), + this, SLOT(slotEntered(const QModelIndex&))); + connect(parent, SIGNAL(viewportEntered()), + this, SLOT(slotViewportEntered())); + m_toggle = new SelectionToggle(m_view->viewport()); + m_toggle->setCheckable(true); + m_toggle->hide(); + connect(m_toggle, SIGNAL(clicked(bool)), + this, SLOT(setItemSelected(bool))); +} + +SelectionManager::~SelectionManager() +{ +} + +void SelectionManager::reset() +{ + m_toggle->reset(); +} + +void SelectionManager::slotEntered(const QModelIndex& index) +{ + m_toggle->hide(); + if (index.isValid() && (index.column() == DolphinModel::Name)) { + m_toggle->setFileItem(itemForIndex(index)); + + connect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)), + this, SLOT(slotRowsRemoved(const QModelIndex&, int, int))); + + const QRect rect = m_view->visualRect(index); + + const int gap = 2; + const int x = rect.left() + gap; + const int y = rect.top() + gap; + m_toggle->move(QPoint(x, y)); + + QItemSelectionModel* selModel = m_view->selectionModel(); + m_toggle->setChecked(selModel->isSelected(index)); + m_toggle->show(); + } else { + m_toggle->setFileItem(KFileItem()); + disconnect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)), + this, SLOT(slotRowsRemoved(const QModelIndex&, int, int))); + } +} + +void SelectionManager::slotViewportEntered() +{ + m_toggle->hide(); +} + +void SelectionManager::setItemSelected(bool selected) +{ + emit selectionChanged(); + Q_ASSERT(!m_toggle->fileItem().isNull()); + + const QModelIndex index = indexForItem(m_toggle->fileItem()); + if (index.isValid()) { + QItemSelectionModel* selModel = m_view->selectionModel(); + if (selected) { + selModel->select(index, QItemSelectionModel::Select); + } else { + selModel->select(index, QItemSelectionModel::Deselect); + } + } +} + +void SelectionManager::slotRowsRemoved(const QModelIndex& parent, int start, int end) +{ + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); + m_toggle->hide(); +} + +KFileItem SelectionManager::itemForIndex(const QModelIndex& index) const +{ + QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(m_view->model()); + KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel()); + const QModelIndex dirIndex = proxyModel->mapToSource(index); + return dirModel->itemForIndex(dirIndex); +} + +const QModelIndex SelectionManager::indexForItem(const KFileItem& item) const +{ + QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(m_view->model()); + KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel()); + const QModelIndex dirIndex = dirModel->indexForItem(item); + return proxyModel->mapFromSource(dirIndex); +} + +#include "selectionmanager.moc" diff --git a/src/selectionmanager.h b/src/selectionmanager.h new file mode 100644 index 000000000..04e6e29c1 --- /dev/null +++ b/src/selectionmanager.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 SELECTIONMANAGER_H +#define SELECTIONMANAGER_H + +#include <kfileitem.h> + +#include <QObject> + +class DolphinSortFilterProxyModel; +class QAbstractItemView; +class QModelIndex; +class QAbstractButton; +class SelectionToggle; + +/** + * @brief Allows to select and deselect items for the single-click mode. + * + * Whenever an item is hovered by the mouse, a toggle button is shown + * which allows to select/deselect the current item. + */ +class SelectionManager : public QObject +{ + Q_OBJECT + +public: + SelectionManager(QAbstractItemView* parent); + virtual ~SelectionManager(); + +public slots: + /** + * Resets the selection manager so that the toggle button gets + * invisible. + */ + void reset(); + +signals: + /** Is emitted if the selection has been changed by the toggle button. */ + void selectionChanged(); + +private slots: + void slotEntered(const QModelIndex& index); + void slotViewportEntered(); + void setItemSelected(bool selected); + void slotRowsRemoved(const QModelIndex& parent, int start, int end); + +private: + KFileItem itemForIndex(const QModelIndex& index) const; + const QModelIndex indexForItem(const KFileItem& item) const; + +private: + QAbstractItemView* m_view; + SelectionToggle* m_toggle; +}; + +#endif diff --git a/src/selectiontoggle.cpp b/src/selectiontoggle.cpp new file mode 100644 index 000000000..7a3f0ef56 --- /dev/null +++ b/src/selectiontoggle.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 * + ***************************************************************************/ + +#include "selectiontoggle.h" + +#include <kicon.h> +#include <kiconloader.h> +#include <kiconeffect.h> + +#include <QPainter> +#include <QPaintEvent> +#include <QRect> +#include <QTimer> +#include <QTimeLine> + +SelectionToggle::SelectionToggle(QWidget* parent) : + QAbstractButton(parent), + m_isHovered(false), + m_fadingValue(0), + m_icon(), + m_fadingTimeLine(0) +{ + parent->installEventFilter(this); + resize(sizeHint()); + m_icon = KIconLoader::global()->loadIcon("dialog-ok", + KIconLoader::NoGroup, + KIconLoader::SizeSmall); +} + +SelectionToggle::~SelectionToggle() +{ +} + +QSize SelectionToggle::sizeHint() const +{ + return QSize(16, 16); +} + +void SelectionToggle::reset() +{ + m_item = KFileItem(); + hide(); +} + +void SelectionToggle::setFileItem(const KFileItem& item) +{ + m_item = item; + if (!item.isNull()) { + startFading(); + } +} + +KFileItem SelectionToggle::fileItem() const +{ + return m_item; +} + +void SelectionToggle::setVisible(bool visible) +{ + QAbstractButton::setVisible(visible); + + stopFading(); + if (visible) { + startFading(); + } + +} + +bool SelectionToggle::eventFilter(QObject* obj, QEvent* event) +{ + if ((obj == parent()) && (event->type() == QEvent::Leave)) { + hide(); + } + return QAbstractButton::eventFilter(obj, event); +} + +void SelectionToggle::enterEvent(QEvent* event) +{ + QAbstractButton::enterEvent(event); + + // if the mouse cursor is above the selection toggle, display + // it immediately without fading timer + m_isHovered = true; + if (m_fadingTimeLine != 0) { + m_fadingTimeLine->stop(); + } + m_fadingValue = 255; + update(); +} + +void SelectionToggle::leaveEvent(QEvent* event) +{ + QAbstractButton::leaveEvent(event); + m_isHovered = false; + update(); +} + +void SelectionToggle::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + painter.setClipRect(event->rect()); + + if (m_isHovered) { + KIconEffect iconEffect; + QPixmap activeIcon = iconEffect.apply(m_icon, KIconLoader::Desktop, KIconLoader::ActiveState); + painter.drawPixmap(0, 0, activeIcon); + } else { + if (m_fadingValue < 255) { + // apply an alpha mask respecting the fading value to the icon + QPixmap icon = m_icon; + QPixmap alphaMask(icon.width(), icon.height()); + const QColor color(m_fadingValue, m_fadingValue, m_fadingValue); + alphaMask.fill(color); + icon.setAlphaChannel(alphaMask); + painter.drawPixmap(0, 0, icon); + } else { + // no fading is required + painter.drawPixmap(0, 0, m_icon); + } + } +} + +void SelectionToggle::setFadingValue(int value) +{ + m_fadingValue = value; + if (m_fadingValue >= 255) { + Q_ASSERT(m_fadingTimeLine != 0); + m_fadingTimeLine->stop(); + } + update(); +} + +void SelectionToggle::startFading() +{ + Q_ASSERT(m_fadingTimeLine == 0); + + m_fadingTimeLine = new QTimeLine(2000, this); + connect(m_fadingTimeLine, SIGNAL(frameChanged(int)), + this, SLOT(setFadingValue(int))); + m_fadingTimeLine->setFrameRange(0, 255); + m_fadingTimeLine->start(); + m_fadingValue = 0; +} + +void SelectionToggle::stopFading() +{ + if (m_fadingTimeLine != 0) { + m_fadingTimeLine->stop(); + delete m_fadingTimeLine; + m_fadingTimeLine = 0; + } + m_fadingValue = 0; +} + +#include "selectiontoggle.moc" diff --git a/src/selectiontoggle.h b/src/selectiontoggle.h new file mode 100644 index 000000000..653104ab5 --- /dev/null +++ b/src/selectiontoggle.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 SELECTIONTOGGLE_H +#define SELECTIONTOGGLE_H + +#include <kfileitem.h> + +#include <QAbstractButton> +#include <QPixmap> + +class QTimeLine; + +/** + * @brief Toggle button for changing the selection of an hovered item. + * + * The toggle button is visually invisible until it is displayed at least + * for one second. + * + * @see SelectionManager + */ +class SelectionToggle : public QAbstractButton +{ + Q_OBJECT + +public: + explicit SelectionToggle(QWidget* parent); + virtual ~SelectionToggle(); + virtual QSize sizeHint() const; + + /** + * Resets the selection toggle so that it is hidden and stays + * visually invisible for at least one second after it is shown again. + */ + void reset(); + + void setFileItem(const KFileItem& item); + KFileItem fileItem() const; + +public slots: + virtual void setVisible(bool visible); + +protected: + virtual bool eventFilter(QObject* obj, QEvent* event); + virtual void enterEvent(QEvent* event); + virtual void leaveEvent(QEvent* event); + virtual void paintEvent(QPaintEvent* event); + +private slots: + /** + * Sets the alpha value for the fading animation and is + * connected with m_fadingTimeLine. + */ + void setFadingValue(int value); + +private: + void startFading(); + void stopFading(); + +private: + bool m_isHovered; + int m_fadingValue; + QPixmap m_icon; + QTimeLine* m_fadingTimeLine; + KFileItem m_item; +}; + +#endif diff --git a/src/startupsettingspage.cpp b/src/startupsettingspage.cpp new file mode 100644 index 000000000..e3f237ca9 --- /dev/null +++ b/src/startupsettingspage.cpp @@ -0,0 +1,152 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 * + ***************************************************************************/ + +#include "startupsettingspage.h" + +#include "dolphinsettings.h" +#include "dolphinmainwindow.h" +#include "dolphinview.h" +#include "dolphinviewcontainer.h" + +#include "dolphin_generalsettings.h" + +#include <kdialog.h> +#include <kfiledialog.h> +#include <klocale.h> +#include <kvbox.h> + +#include <QCheckBox> +#include <QGroupBox> +#include <QLabel> +#include <QLineEdit> +#include <QPushButton> +#include <QRadioButton> + +StartupSettingsPage::StartupSettingsPage(DolphinMainWindow* mainWin, QWidget* parent) : + SettingsPageBase(parent), + m_mainWindow(mainWin), + m_homeUrl(0), + m_splitView(0), + m_editableUrl(0), + m_filterBar(0) +{ + const int spacing = KDialog::spacingHint(); + + QVBoxLayout* topLayout = new QVBoxLayout(this); + KVBox* vBox = new KVBox(this); + vBox->setSpacing(spacing); + + // create 'Home URL' editor + QGroupBox* homeBox = new QGroupBox(i18nc("@title:group", "Home Folder"), vBox); + + KHBox* homeUrlBox = new KHBox(homeBox); + homeUrlBox->setSpacing(spacing); + + new QLabel(i18nc("@label:textbox", "Location:"), homeUrlBox); + m_homeUrl = new QLineEdit(homeUrlBox); + + QPushButton* selectHomeUrlButton = new QPushButton(KIcon("folder-open"), QString(), homeUrlBox); + connect(selectHomeUrlButton, SIGNAL(clicked()), + this, SLOT(selectHomeUrl())); + + KHBox* buttonBox = new KHBox(homeBox); + buttonBox->setSpacing(spacing); + + QPushButton* useCurrentButton = new QPushButton(i18nc("@action:button", "Use Current Location"), buttonBox); + connect(useCurrentButton, SIGNAL(clicked()), + this, SLOT(useCurrentLocation())); + QPushButton* useDefaultButton = new QPushButton(i18nc("@action:button", "Use Default Location"), buttonBox); + connect(useDefaultButton, SIGNAL(clicked()), + this, SLOT(useDefaultLocation())); + + QVBoxLayout* homeBoxLayout = new QVBoxLayout(homeBox); + homeBoxLayout->addWidget(homeUrlBox); + homeBoxLayout->addWidget(buttonBox); + + // create 'Split view', 'Editable location' and 'Filter bar' checkboxes + m_splitView = new QCheckBox(i18nc("@option:check Startup Settings", "Split view mode"), vBox); + m_editableUrl = new QCheckBox(i18nc("@option:check Startup Settings", "Editable location bar"), vBox); + m_filterBar = new QCheckBox(i18nc("@option:check Startup Settings", "Show filter bar"), vBox); + + // Add a dummy widget with no restriction regarding + // a vertical resizing. This assures that the dialog layout + // is not stretched vertically. + new QWidget(vBox); + + topLayout->addWidget(vBox); + + loadSettings(); +} + +StartupSettingsPage::~StartupSettingsPage() +{ +} + +void StartupSettingsPage::applySettings() +{ + GeneralSettings* settings = DolphinSettings::instance().generalSettings(); + + const KUrl url(m_homeUrl->text()); + KFileItem fileItem(S_IFDIR, KFileItem::Unknown, url); + if (url.isValid() && fileItem.isDir()) { + settings->setHomeUrl(url.prettyUrl()); + } + + settings->setSplitView(m_splitView->isChecked()); + settings->setEditableUrl(m_editableUrl->isChecked()); + settings->setFilterBar(m_filterBar->isChecked()); +} + +void StartupSettingsPage::restoreDefaults() +{ + GeneralSettings* settings = DolphinSettings::instance().generalSettings(); + settings->setDefaults(); + loadSettings(); +} + +void StartupSettingsPage::selectHomeUrl() +{ + const QString homeUrl = m_homeUrl->text(); + KUrl url = KFileDialog::getExistingDirectoryUrl(homeUrl); + if (!url.isEmpty()) { + m_homeUrl->setText(url.prettyUrl()); + } +} + +void StartupSettingsPage::useCurrentLocation() +{ + const DolphinView* view = m_mainWindow->activeViewContainer()->view(); + m_homeUrl->setText(view->url().prettyUrl()); +} + +void StartupSettingsPage::useDefaultLocation() +{ + m_homeUrl->setText("file://" + QDir::homePath()); +} + +void StartupSettingsPage::loadSettings() +{ + GeneralSettings* settings = DolphinSettings::instance().generalSettings(); + m_homeUrl->setText(settings->homeUrl()); + m_splitView->setChecked(settings->splitView()); + m_editableUrl->setChecked(settings->editableUrl()); + m_filterBar->setChecked(settings->filterBar()); +} + +#include "startupsettingspage.moc" diff --git a/src/startupsettingspage.h b/src/startupsettingspage.h new file mode 100644 index 000000000..14314c6c2 --- /dev/null +++ b/src/startupsettingspage.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz <[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 STARTUPSETTINGSPAGE_H +#define STARTUPSETTINGSPAGE_H + +#include <settingspagebase.h> + +class DolphinMainWindow; +class QLineEdit; +class QCheckBox; + +/** + * @brief Page for the 'Startup' settings of the Dolphin settings dialog. + * + * The startup settings allow to set the home URL and to configure the + * state of the view mode, split mode and the filter bar when starting Dolphin. + */ +class StartupSettingsPage : public SettingsPageBase +{ + Q_OBJECT + +public: + StartupSettingsPage(DolphinMainWindow* mainWindow, QWidget* parent); + virtual ~StartupSettingsPage(); + + /** @see SettingsPageBase::applySettings() */ + virtual void applySettings(); + + /** @see SettingsPageBase::restoreDefaults() */ + virtual void restoreDefaults(); + +private slots: + void selectHomeUrl(); + void useCurrentLocation(); + void useDefaultLocation(); + +private: + void loadSettings(); + +private: + DolphinMainWindow* m_mainWindow; + QLineEdit* m_homeUrl; + + QCheckBox* m_splitView; + QCheckBox* m_editableUrl; + QCheckBox* m_filterBar; +}; + +#endif diff --git a/src/viewpropertiesdialog.cpp b/src/viewpropertiesdialog.cpp index c5d0ec510..844a2ecf9 100644 --- a/src/viewpropertiesdialog.cpp +++ b/src/viewpropertiesdialog.cpp @@ -89,14 +89,16 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) : propsBox = new QGroupBox(i18nc("@title:group", "Properties"), main); } - QLabel* viewModeLabel = new QLabel(i18nc("@label:listbox", "View mode:"), propsBox); - m_viewMode = new QComboBox(propsBox); + QWidget* propsGrid = new QWidget(); + + QLabel* viewModeLabel = new QLabel(i18nc("@label:listbox", "View mode:"), propsGrid); + m_viewMode = new QComboBox(propsGrid); m_viewMode->addItem(KIcon("view-list-icons"), i18nc("@item:inlistbox", "Icons")); m_viewMode->addItem(KIcon("view-list-details"), i18nc("@item:inlistbox", "Details")); m_viewMode->addItem(KIcon("view-file-columns"), i18nc("@item:inlistbox", "Column")); - QLabel* sortingLabel = new QLabel(i18nc("@label:listbox", "Sorting:"), propsBox); - QWidget* sortingBox = new QWidget(propsBox); + QLabel* sortingLabel = new QLabel(i18nc("@label:listbox", "Sorting:"), propsGrid); + QWidget* sortingBox = new QWidget(propsGrid); m_sortOrder = new QComboBox(sortingBox); m_sortOrder->addItem(i18nc("@item:inlistbox", "Ascending")); @@ -119,6 +121,11 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) : // m_sorting->addItem(i18nc("@item:inlistbox Sort", "By Tags")); // } #endif + m_showPreview = new QCheckBox(i18nc("@option:check", "Show preview"), propsBox); + m_showInGroups = new QCheckBox(i18nc("@option:check", "Show in groups"), propsBox); + m_showHiddenFiles = new QCheckBox(i18nc("@option:check", "Show hidden files"), propsBox); + + m_additionalInfo = new QPushButton(i18nc("@action:button", "Additional Information"), propsBox); QHBoxLayout* sortingLayout = new QHBoxLayout(); sortingLayout->setMargin(0); @@ -126,23 +133,18 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) : sortingLayout->addWidget(m_sorting); sortingBox->setLayout(sortingLayout); - m_showPreview = new QCheckBox(i18nc("@option:check", "Show preview"), propsBox); - m_showInGroups = new QCheckBox(i18nc("@option:check", "Show in Groups"), propsBox); - m_showHiddenFiles = new QCheckBox(i18nc("@option:check", "Show hidden files"), propsBox); + QGridLayout* propsGridLayout = new QGridLayout(propsGrid); + propsGridLayout->addWidget(viewModeLabel, 0, 0); + propsGridLayout->addWidget(m_viewMode, 0, 1); + propsGridLayout->addWidget(sortingLabel, 1, 0); + propsGridLayout->addWidget(sortingBox, 1, 1); - m_additionalInfo = new QPushButton(i18nc("@action:button", "Additional Information"), propsBox); - connect(m_additionalInfo, SIGNAL(clicked()), - this, SLOT(configureAdditionalInfo())); - - QGridLayout* propsBoxLayout = new QGridLayout(propsBox); - propsBoxLayout->addWidget(viewModeLabel, 0, 0); - propsBoxLayout->addWidget(m_viewMode, 0, 1); - propsBoxLayout->addWidget(sortingLabel, 1, 0); - propsBoxLayout->addWidget(sortingBox, 1, 1); - propsBoxLayout->addWidget(m_showPreview, 2, 0); - propsBoxLayout->addWidget(m_showInGroups, 3, 0); - propsBoxLayout->addWidget(m_showHiddenFiles, 4, 0); - propsBoxLayout->addWidget(m_additionalInfo, 5, 0); + QVBoxLayout* propsBoxLayout = new QVBoxLayout(propsBox); + propsBoxLayout->addWidget(propsGrid); + propsBoxLayout->addWidget(m_showPreview); + propsBoxLayout->addWidget(m_showInGroups); + propsBoxLayout->addWidget(m_showHiddenFiles); + propsBoxLayout->addWidget(m_additionalInfo); topLayout->addWidget(propsBox); @@ -152,8 +154,8 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) : this, SLOT(slotSortingChanged(int))); connect(m_sortOrder, SIGNAL(activated(int)), this, SLOT(slotSortOrderChanged(int))); - connect(m_additionalInfo, SIGNAL(activated(int)), - this, SLOT(slotAdditionalInfoChanged(int))); + connect(m_additionalInfo, SIGNAL(clicked()), + this, SLOT(configureAdditionalInfo())); connect(m_showPreview, SIGNAL(clicked()), this, SLOT(slotShowPreviewChanged())); connect(m_showInGroups, SIGNAL(clicked()), |
