diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dolphindockwidget.cpp | 4 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.cpp | 15 | ||||
| -rw-r--r-- | src/kitemviews/kitemlistview.h | 7 | ||||
| -rw-r--r-- | src/kitemviews/kstandarditemlistwidget.cpp | 11 | ||||
| -rw-r--r-- | src/kitemviews/private/kitemlistroleeditor.cpp | 49 | ||||
| -rw-r--r-- | src/kitemviews/private/kitemlistroleeditor.h | 12 | ||||
| -rw-r--r-- | src/panels/information/phononwidget.cpp | 7 | ||||
| -rw-r--r-- | src/panels/places/placesitem.cpp | 3 | ||||
| -rw-r--r-- | src/settings/dolphin_generalsettings.kcfg | 3 | ||||
| -rw-r--r-- | src/views/dolphinview.cpp | 15 |
10 files changed, 114 insertions, 12 deletions
diff --git a/src/dolphindockwidget.cpp b/src/dolphindockwidget.cpp index 72e06a656..0d8aea7bd 100644 --- a/src/dolphindockwidget.cpp +++ b/src/dolphindockwidget.cpp @@ -68,8 +68,12 @@ void DolphinDockWidget::setLocked(bool lock) m_dockTitleBar = new DolphinDockTitleBar(this); } setTitleBarWidget(m_dockTitleBar); + setFeatures(QDockWidget::NoDockWidgetFeatures); } else { setTitleBarWidget(0); + setFeatures(QDockWidget::DockWidgetMovable | + QDockWidget::DockWidgetFloatable | + QDockWidget::DockWidgetClosable); } } } diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 3c60b8e43..6a68ae798 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1454,12 +1454,16 @@ void KItemListView::slotGeometryOfGroupHeaderParentChanged() void KItemListView::slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value) { + disconnectRoleEditingSignals(index); + emit roleEditingCanceled(index, role, value); m_editingRole = false; } void KItemListView::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value) { + disconnectRoleEditingSignals(index); + emit roleEditingFinished(index, role, value); m_editingRole = false; } @@ -2530,6 +2534,17 @@ bool KItemListView::hasSiblingSuccessor(int index) const return hasSuccessor; } +void KItemListView::disconnectRoleEditingSignals(int index) +{ + KItemListWidget* widget = m_visibleItems.value(index); + if (!widget) { + return; + } + + widget->disconnect(SIGNAL(roleEditingCanceled(int,QByteArray,QVariant)), this); + widget->disconnect(SIGNAL(roleEditingFinished(int,QByteArray,QVariant)), this); +} + int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc) { int inc = 0; diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index ca17053a3..2baf20c94 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -663,6 +663,13 @@ private: bool hasSiblingSuccessor(int index) const; /** + * Helper method for slotRoleEditingCanceled() and slotRoleEditingFinished(). + * Disconnects the two Signals "roleEditingCanceled" and + * "roleEditingFinished" + */ + void disconnectRoleEditingSignals(int index); + + /** * Helper function for triggerAutoScrolling(). * @param pos Logical position of the mouse relative to the range. * @param range Range of the visible area. diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index 3dccfcc7d..4d1031943 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -610,7 +610,10 @@ void KStandardItemListWidget::editedRoleChanged(const QByteArray& current, const this, SLOT(slotRoleEditingCanceled(int,QByteArray,QVariant))); disconnect(m_roleEditor, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)), this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant))); - m_roleEditor->deleteLater(); + // Do not delete the role editor using deleteLater() because we might be + // inside a nested event loop which has been started by one of its event + // handlers (contextMenuEvent() or drag&drop inside mouseMoveEvent()). + m_roleEditor->deleteWhenIdle(); m_roleEditor = 0; } return; @@ -1275,7 +1278,11 @@ void KStandardItemListWidget::closeRoleEditor() this, SLOT(slotRoleEditingCanceled(int,QByteArray,QVariant))); disconnect(m_roleEditor, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)), this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant))); - m_roleEditor->deleteLater(); + + // Do not delete the role editor using deleteLater() because we might be + // inside a nested event loop which has been started by one of its event + // handlers (contextMenuEvent() or drag&drop inside mouseMoveEvent()). + m_roleEditor->deleteWhenIdle(); m_roleEditor = 0; } diff --git a/src/kitemviews/private/kitemlistroleeditor.cpp b/src/kitemviews/private/kitemlistroleeditor.cpp index 1e4b5fd4e..ead5b298e 100644 --- a/src/kitemviews/private/kitemlistroleeditor.cpp +++ b/src/kitemviews/private/kitemlistroleeditor.cpp @@ -26,7 +26,9 @@ KItemListRoleEditor::KItemListRoleEditor(QWidget *parent) : KTextEdit(parent), m_index(0), m_role(), - m_blockFinishedSignal(false) + m_blockFinishedSignal(false), + m_eventHandlingLevel(0), + m_deleteAfterEventHandling(false) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -64,6 +66,20 @@ QByteArray KItemListRoleEditor::role() const return m_role; } +void KItemListRoleEditor::deleteWhenIdle() +{ + if (m_eventHandlingLevel > 0) { + // We are handling an event at the moment. It could be that we + // are in a nested event loop run by contextMenuEvent() or a + // call of mousePressEvent() which results in drag&drop. + // -> do not call deleteLater() to prevent a crash when we + // return from the nested event loop. + m_deleteAfterEventHandling = true; + } else { + deleteLater(); + } +} + bool KItemListRoleEditor::eventFilter(QObject* watched, QEvent* event) { if (watched == parentWidget() && event->type() == QEvent::Resize) { @@ -75,13 +91,42 @@ bool KItemListRoleEditor::eventFilter(QObject* watched, QEvent* event) bool KItemListRoleEditor::event(QEvent* event) { + ++m_eventHandlingLevel; + if (event->type() == QEvent::FocusOut) { QFocusEvent* focusEvent = static_cast<QFocusEvent*>(event); if (focusEvent->reason() != Qt::PopupFocusReason) { emitRoleEditingFinished(); } } - return KTextEdit::event(event); + + const int result = KTextEdit::event(event); + --m_eventHandlingLevel; + + if (m_deleteAfterEventHandling && m_eventHandlingLevel == 0) { + // Schedule this object for deletion and make sure that we do not try + // to deleteLater() again when the DeferredDelete event is received. + deleteLater(); + m_deleteAfterEventHandling = false; + } + + return result; +} + +bool KItemListRoleEditor::viewportEvent(QEvent* event) +{ + ++m_eventHandlingLevel; + const bool result = KTextEdit::viewportEvent(event); + --m_eventHandlingLevel; + + if (m_deleteAfterEventHandling && m_eventHandlingLevel == 0) { + // Schedule this object for deletion and make sure that we do not try + // to deleteLater() again when the DeferredDelete event is received. + deleteLater(); + m_deleteAfterEventHandling = false; + } + + return result; } void KItemListRoleEditor::keyPressEvent(QKeyEvent* event) diff --git a/src/kitemviews/private/kitemlistroleeditor.h b/src/kitemviews/private/kitemlistroleeditor.h index aa2c97754..a2f705808 100644 --- a/src/kitemviews/private/kitemlistroleeditor.h +++ b/src/kitemviews/private/kitemlistroleeditor.h @@ -47,6 +47,15 @@ public: void setRole(const QByteArray& role); QByteArray role() const; + /** + * Calls deleteLater() if no event is being handled at the moment. + * Otherwise, the deletion is deferred until the event handling is + * finished. This prevents that the deletion happens inside a nested + * event loop which might be run in contextMenuEvent() or + * mouseMoveEvent() because this would probably cause a crash. + */ + void deleteWhenIdle(); + virtual bool eventFilter(QObject* watched, QEvent* event); signals: @@ -55,6 +64,7 @@ signals: protected: virtual bool event(QEvent* event); + virtual bool viewportEvent(QEvent* event); virtual void keyPressEvent(QKeyEvent* event); private slots: @@ -75,6 +85,8 @@ private: int m_index; QByteArray m_role; bool m_blockFinishedSignal; + int m_eventHandlingLevel; + bool m_deleteAfterEventHandling; }; #endif diff --git a/src/panels/information/phononwidget.cpp b/src/panels/information/phononwidget.cpp index f0c030ed6..a36ada180 100644 --- a/src/panels/information/phononwidget.cpp +++ b/src/panels/information/phononwidget.cpp @@ -123,14 +123,17 @@ void PhononWidget::showEvent(QShowEvent *event) m_topLayout->addLayout(controlsLayout); + const int smallIconSize = IconSize(KIconLoader::Small); + const QSize buttonSize(smallIconSize, smallIconSize); + m_playButton->setToolTip(i18n("play")); - m_playButton->setIconSize(QSize(16, 16)); + m_playButton->setIconSize(buttonSize); m_playButton->setIcon(KIcon("media-playback-start")); m_playButton->setAutoRaise(true); connect(m_playButton, SIGNAL(clicked()), this, SLOT(play())); m_stopButton->setToolTip(i18n("stop")); - m_stopButton->setIconSize(QSize(16, 16)); + m_stopButton->setIconSize(buttonSize); m_stopButton->setIcon(KIcon("media-playback-stop")); m_stopButton->setAutoRaise(true); m_stopButton->hide(); diff --git a/src/panels/places/placesitem.cpp b/src/panels/places/placesitem.cpp index f78c98b76..75e14d0fb 100644 --- a/src/panels/places/placesitem.cpp +++ b/src/panels/places/placesitem.cpp @@ -268,8 +268,7 @@ void PlacesItem::initializeDevice(const QString& udi) } else if (m_disc && (m_disc->availableContent() & Solid::OpticalDisc::Audio) != 0) { const QString device = m_device.as<Solid::Block>()->device(); setUrl(QString("audiocd:/?device=%1").arg(device)); - } else if (m_mtp && m_mtp->supportedProtocols().contains("mtp")) { - setText(m_device.product()); + } else if (m_mtp) { setUrl(QString("mtp:udi=%1").arg(m_device.udi())); } } diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg index 050750199..849a9c75c 100644 --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -5,6 +5,7 @@ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 http://www.kde.org/standards/kcfg/1.0/kcfg.xsd"> <include>QDir</include> + <include>KUrl</include> <include>kglobalsettings.h</include> <kcfgfile name="dolphinrc"/> <group name="General"> @@ -30,7 +31,7 @@ </entry> <entry name="HomeUrl" type="String"> <label>Home URL</label> - <default code="true">QDir::homePath()</default> + <default code="true">KUrl(QDir::homePath()).prettyUrl()</default> </entry> <entry name="SplitView" type="Bool"> <label>Split the view into two panes</label> diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 5b3d074c9..e2ccc7ff1 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -1357,9 +1357,18 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con if (!newName.isEmpty() && newName != oldItem.text() && newName != QLatin1String(".") && newName != QLatin1String("..")) { const KUrl oldUrl = oldItem.url(); - QHash<QByteArray, QVariant> data; - data.insert(role, value); - m_model->setData(index, data); + const KUrl newUrl(url().path(KUrl::AddTrailingSlash) + newName); + const bool newNameExistsAlready = (m_model->index(newUrl) >= 0); + if (!newNameExistsAlready) { + // Only change the data in the model if no item with the new name + // is in the model yet. If there is an item with the new name + // already, calling KonqOperations::rename() will open a dialog + // asking for a new name, and KFileItemModel will update the + // data when the dir lister signals that the file name has changed. + QHash<QByteArray, QVariant> data; + data.insert(role, value); + m_model->setData(index, data); + } KonqOperations::rename(this, oldUrl, newName); } |
