m_settingsDialog(),
m_controlButton(0),
m_updateToolBarTimer(0),
- m_lastHandleUrlStatJob(0)
+ m_lastHandleUrlStatJob(0),
+ m_terminalPanel(0),
+ m_placesPanel(0),
+ m_tearDownFromPlacesRequested(false)
{
Q_INIT_RESOURCE(dolphin);
void DolphinMainWindow::slotTerminalDirectoryChanged(const QUrl& url)
{
+ if (m_tearDownFromPlacesRequested && url == QUrl::fromLocalFile(QDir::homePath())) {
+ m_placesPanel->proceedWithTearDown();
+ m_tearDownFromPlacesRequested = false;
+ }
+
m_activeViewContainer->setAutoGrabFocus(false);
changeUrl(url);
m_activeViewContainer->setAutoGrabFocus(true);
setWindowTitle(schemePrefix + fileName);
}
+void DolphinMainWindow::slotStorageTearDownFromPlacesRequested(const QString& mountPath)
+{
+ if (m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
+ m_tearDownFromPlacesRequested = true;
+ m_terminalPanel->goHome();
+ // m_placesPanel->proceedWithTearDown() will be called in slotTerminalDirectoryChanged
+ } else {
+ m_placesPanel->proceedWithTearDown();
+ }
+}
+
+void DolphinMainWindow::slotStorageTearDownExternallyRequested(const QString& mountPath)
+{
+ if (m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
+ m_tearDownFromPlacesRequested = false;
+ m_terminalPanel->goHome();
+ }
+}
+
void DolphinMainWindow::setupActions()
{
// setup 'File' menu
terminalDock->setLocked(lock);
terminalDock->setObjectName(QStringLiteral("terminalDock"));
terminalDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
- TerminalPanel* terminalPanel = new TerminalPanel(terminalDock);
- terminalPanel->setCustomContextMenuActions({lockLayoutAction});
- terminalDock->setWidget(terminalPanel);
+ m_terminalPanel = new TerminalPanel(terminalDock);
+ m_terminalPanel->setCustomContextMenuActions({lockLayoutAction});
+ terminalDock->setWidget(m_terminalPanel);
- connect(terminalPanel, &TerminalPanel::hideTerminalPanel, terminalDock, &DolphinDockWidget::hide);
- connect(terminalPanel, &TerminalPanel::changeUrl, this, &DolphinMainWindow::slotTerminalDirectoryChanged);
+ connect(m_terminalPanel, &TerminalPanel::hideTerminalPanel, terminalDock, &DolphinDockWidget::hide);
+ connect(m_terminalPanel, &TerminalPanel::changeUrl, this, &DolphinMainWindow::slotTerminalDirectoryChanged);
connect(terminalDock, &DolphinDockWidget::visibilityChanged,
- terminalPanel, &TerminalPanel::dockVisibilityChanged);
+ m_terminalPanel, &TerminalPanel::dockVisibilityChanged);
QAction* terminalAction = terminalDock->toggleViewAction();
createPanelAction(QIcon::fromTheme(QStringLiteral("utilities-terminal")), Qt::Key_F4, terminalAction, QStringLiteral("show_terminal_panel"));
addDockWidget(Qt::BottomDockWidgetArea, terminalDock);
connect(this, &DolphinMainWindow::urlChanged,
- terminalPanel, &TerminalPanel::setUrl);
+ m_terminalPanel, &TerminalPanel::setUrl);
if (GeneralSettings::version() < 200) {
terminalDock->hide();
placesDock->setObjectName(QStringLiteral("placesDock"));
placesDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
- PlacesPanel* placesPanel = new PlacesPanel(placesDock);
- placesPanel->setCustomContextMenuActions({lockLayoutAction});
- placesDock->setWidget(placesPanel);
+ m_placesPanel = new PlacesPanel(placesDock);
+ m_placesPanel->setCustomContextMenuActions({lockLayoutAction});
+ placesDock->setWidget(m_placesPanel);
- QAction* placesAction = placesDock->toggleViewAction();
+ QAction *placesAction = placesDock->toggleViewAction();
createPanelAction(QIcon::fromTheme(QStringLiteral("bookmarks")), Qt::Key_F9, placesAction, QStringLiteral("show_places_panel"));
addDockWidget(Qt::LeftDockWidgetArea, placesDock);
- connect(placesPanel, &PlacesPanel::placeActivated,
+ connect(m_placesPanel, &PlacesPanel::placeActivated,
this, &DolphinMainWindow::slotPlaceActivated);
- connect(placesPanel, &PlacesPanel::placeMiddleClicked,
+ connect(m_placesPanel, &PlacesPanel::placeMiddleClicked,
this, &DolphinMainWindow::openNewTab);
- connect(placesPanel, &PlacesPanel::errorMessage,
+ connect(m_placesPanel, &PlacesPanel::errorMessage,
this, &DolphinMainWindow::showErrorMessage);
connect(this, &DolphinMainWindow::urlChanged,
- placesPanel, &PlacesPanel::setUrl);
+ m_placesPanel, &PlacesPanel::setUrl);
connect(placesDock, &DolphinDockWidget::visibilityChanged,
m_tabWidget, &DolphinTabWidget::slotPlacesPanelVisibilityChanged);
connect(this, &DolphinMainWindow::settingsChanged,
- placesPanel, &PlacesPanel::readSettings);
-
- m_tabWidget->slotPlacesPanelVisibilityChanged(placesPanel->isVisible());
+ m_placesPanel, &PlacesPanel::readSettings);
+ connect(m_placesPanel, &PlacesPanel::storageTearDownRequested,
+ this, &DolphinMainWindow::slotStorageTearDownFromPlacesRequested);
+ connect(m_placesPanel, &PlacesPanel::storageTearDownExternallyRequested,
+ this, &DolphinMainWindow::slotStorageTearDownExternallyRequested);
+ m_tabWidget->slotPlacesPanelVisibilityChanged(m_placesPanel->isVisible());
// Add actions into the "Panels" menu
KActionMenu* panelsMenu = new KActionMenu(i18nc("@action:inmenu View", "Panels"), this);
class KNewFileMenu;
class QToolButton;
class QIcon;
+class PlacesPanel;
+class TerminalPanel;
/**
* @short Main window for Dolphin.
*/
KNewFileMenu* newFileMenu() const;
+ void setTabsToHomeIfMountPathOpen(const QString& mountPath);
+
public slots:
/**
* Pastes the clipboard data into the currently selected folder
*/
void setUrlAsCaption(const QUrl& url);
+ /**
+ * This slot is called when the user requested to unmount a removable media
+ * from the places menu
+ */
+ void slotStorageTearDownFromPlacesRequested(const QString& mountPath);
+
+ /**
+ * This slot is called when the user requested to unmount a removable media
+ * _not_ from the dolphin's places menu (from the notification area for e.g.)
+ * This slot is basically connected to each removable device's
+ * Solid::StorageAccess::teardownRequested(const QString & udi)
+ * signal through the places panel.
+ */
+ void slotStorageTearDownExternallyRequested(const QString& mountPath);
+
/**
* Is called when the view has finished loading the directory.
*/
QTimer* m_updateToolBarTimer;
KIO::Job* m_lastHandleUrlStatJob;
+
+ TerminalPanel* m_terminalPanel;
+ PlacesPanel* m_placesPanel;
+ bool m_tearDownFromPlacesRequested;
};
inline DolphinViewContainer* DolphinMainWindow::activeViewContainer() const
setUrl(QUrl::fromLocalFile(m_access->filePath()));
QObject::connect(m_access.data(), &Solid::StorageAccess::accessibilityChanged,
m_signalHandler.data(), &PlacesItemSignalHandler::onAccessibilityChanged);
+ QObject::connect(m_access.data(), &Solid::StorageAccess::teardownRequested,
+ m_signalHandler.data(), &PlacesItemSignalHandler::onTearDownRequested);
} else if (m_disc && (m_disc->availableContent() & Solid::OpticalDisc::Audio) != 0) {
Solid::Block *block = m_device.as<Solid::Block>();
if (block) {
return QString::number(QDateTime::currentDateTimeUtc().toTime_t()) +
'/' + QString::number(count++) + " (V2)";
}
+
+PlacesItemSignalHandler *PlacesItem::signalHandler() const
+{
+ return m_signalHandler.data();
+}
static KBookmark createDeviceBookmark(KBookmarkManager* manager,
const QString& udi);
+ PlacesItemSignalHandler* signalHandler() const;
+
protected:
virtual void onDataValueChanged(const QByteArray& role,
const QVariant& current,
***************************************************************************/
#include "placesitemmodel.h"
+#include "placesitemsignalhandler.h"
#include "dolphin_generalsettings.h"
m_systemBookmarksIndexes(),
m_bookmarkedItems(),
m_hiddenItemToRemove(-1),
+ m_deviceToTearDown(0),
m_updateBookmarksTimer(0),
m_storageSetupInProgress()
{
Solid::OpticalDrive* drive = item->device().parent().as<Solid::OpticalDrive>();
if (drive) {
connect(drive, &Solid::OpticalDrive::ejectDone,
- this, &PlacesItemModel::slotStorageTeardownDone);
+ this, &PlacesItemModel::slotStorageTearDownDone);
drive->eject();
} else {
const QString label = item->text();
}
}
-void PlacesItemModel::requestTeardown(int index)
+void PlacesItemModel::requestTearDown(int index)
{
const PlacesItem* item = placesItem(index);
if (item) {
- Solid::StorageAccess* access = item->device().as<Solid::StorageAccess>();
- if (access) {
- connect(access, &Solid::StorageAccess::teardownDone,
- this, &PlacesItemModel::slotStorageTeardownDone);
- access->teardown();
+ Solid::StorageAccess *tmp = item->device().as<Solid::StorageAccess>();
+ if (tmp) {
+ m_deviceToTearDown = tmp;
+ // disconnect the Solid::StorageAccess::teardownRequested
+ // to prevent emitting PlacesItemModel::storageTearDownExternallyRequested
+ // after we have emitted PlacesItemModel::storageTearDownRequested
+ disconnect(tmp, &Solid::StorageAccess::teardownRequested,
+ item->signalHandler(), &PlacesItemSignalHandler::onTearDownRequested);
+ emit storageTearDownRequested(tmp->filePath());
}
}
}
m_availableDevices << udi;
const KBookmark bookmark = PlacesItem::createDeviceBookmark(m_bookmarkManager, udi);
- appendItem(new PlacesItem(bookmark));
+
+ PlacesItem *item = new PlacesItem(bookmark);
+ appendItem(item);
+ connect(item->signalHandler(), &PlacesItemSignalHandler::tearDownExternallyRequested,
+ this, &PlacesItemModel::storageTearDownExternallyRequested);
}
void PlacesItemModel::slotDeviceRemoved(const QString& udi)
}
}
-void PlacesItemModel::slotStorageTeardownDone(Solid::ErrorType error, const QVariant& errorData)
+void PlacesItemModel::slotStorageTearDownDone(Solid::ErrorType error, const QVariant& errorData)
{
if (error && errorData.isValid()) {
emit errorMessage(errorData.toString());
}
+ m_deviceToTearDown->disconnect();
+ m_deviceToTearDown = nullptr;
}
void PlacesItemModel::slotStorageSetupDone(Solid::ErrorType error,
devicesItems.reserve(devicesItems.count() + devices.count());
foreach (const QString& udi, devices) {
const KBookmark bookmark = PlacesItem::createDeviceBookmark(m_bookmarkManager, udi);
- devicesItems.append(new PlacesItem(bookmark));
+ PlacesItem *item = new PlacesItem(bookmark);
+ devicesItems.append(item);
+ connect(item->signalHandler(), &PlacesItemSignalHandler::tearDownExternallyRequested,
+ this, &PlacesItemModel::storageTearDownExternallyRequested);
}
QList<PlacesItem*> items;
KStandardItemModel::clear();
}
+void PlacesItemModel::proceedWithTearDown()
+{
+ Q_ASSERT(m_deviceToTearDown);
+
+ connect(m_deviceToTearDown, &Solid::StorageAccess::teardownDone,
+ this, &PlacesItemModel::slotStorageTearDownDone);
+ m_deviceToTearDown->teardown();
+}
+
void PlacesItemModel::initializeAvailableDevices()
{
QString predicate(QStringLiteral("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]"
QAction* teardownAction(int index) const;
void requestEject(int index);
- void requestTeardown(int index);
+ void requestTearDown(int index);
bool storageSetupNeeded(int index) const;
void requestStorageSetup(int index);
virtual void clear() Q_DECL_OVERRIDE;
+ void proceedWithTearDown();
+
/**
* Saves the bookmarks and indicates to other applications that the
* state of the bookmarks has been changed. Is only called by the
signals:
void errorMessage(const QString& message);
void storageSetupDone(int index, bool success);
+ void storageTearDownRequested(const QString& mountPath);
+ void storageTearDownExternallyRequested(const QString& mountPath);
protected:
virtual void onItemInserted(int index) Q_DECL_OVERRIDE;
private slots:
void slotDeviceAdded(const QString& udi);
void slotDeviceRemoved(const QString& udi);
- void slotStorageTeardownDone(Solid::ErrorType error, const QVariant& errorData);
+ void slotStorageTearDownDone(Solid::ErrorType error, const QVariant& errorData);
void slotStorageSetupDone(Solid::ErrorType error, const QVariant& errorData, const QString& udi);
void hideItem();
// removing an item is not allowed.
int m_hiddenItemToRemove;
+ Solid::StorageAccess *m_deviceToTearDown;
+
QTimer* m_updateBookmarksTimer;
QHash<QObject*, int> m_storageSetupInProgress;
}
}
+void PlacesItemSignalHandler::onTearDownRequested(const QString& udi)
+{
+ Q_UNUSED(udi)
+ if (m_item) {
+ Solid::StorageAccess *tmp = m_item->device().as<Solid::StorageAccess>();
+ if (tmp) {
+ QString mountPath = tmp->filePath();
+ emit tearDownExternallyRequested(mountPath);
+ }
+ }
+}
+
*/
void onTrashDirListerCompleted();
+ void onTearDownRequested(const QString& udi);
+
+signals:
+ void tearDownExternallyRequested(const QString& udi);
+
private:
PlacesItem* m_item;
};
{
}
+void PlacesPanel::proceedWithTearDown()
+{
+ m_model->proceedWithTearDown();
+}
+
bool PlacesPanel::urlChanged()
{
if (!url().isValid() || url().scheme().contains(QStringLiteral("search"))) {
m_model->setGroupedSorting(true);
connect(m_model, &PlacesItemModel::errorMessage,
this, &PlacesPanel::errorMessage);
+ connect(m_model, &PlacesItemModel::storageTearDownRequested,
+ this, &PlacesPanel::storageTearDownRequested);
+ connect(m_model, &PlacesItemModel::storageTearDownExternallyRequested,
+ this, &PlacesPanel::storageTearDownExternallyRequested);
m_view = new PlacesView();
m_view->setWidgetCreator(new KItemListWidgetCreator<PlacesItemListWidget>());
// emit the slotItemMiddleClicked signal, because of Qt::MiddleButton.
triggerItem(index, Qt::MiddleButton);
} else if (action == teardownAction) {
- m_model->requestTeardown(index);
+ m_model->requestTearDown(index);
} else if (action == ejectAction) {
m_model->requestEject(index);
}
public:
PlacesPanel(QWidget* parent);
virtual ~PlacesPanel();
+ void proceedWithTearDown();
signals:
void placeActivated(const QUrl& url);
void placeMiddleClicked(const QUrl& url);
void errorMessage(const QString& error);
+ void storageTearDownRequested(const QString& mountPath);
+ void storageTearDownExternallyRequested(const QString& mountPath);
protected:
virtual bool urlChanged() Q_DECL_OVERRIDE;
{
}
+void TerminalPanel::goHome()
+{
+ sendCdToTerminal(QDir::homePath(), HistoryPolicy::SkipHistory);
+}
+
+QString TerminalPanel::currentWorkingDirectory()
+{
+ if (m_terminal) {
+ return m_terminal->currentWorkingDirectory();
+ }
+ return QString();
+}
+
void TerminalPanel::terminalExited()
{
m_terminal = 0;
}
}
-void TerminalPanel::sendCdToTerminal(const QString& dir)
+void TerminalPanel::sendCdToTerminal(const QString& dir, HistoryPolicy addToHistory)
{
if (dir == m_konsolePartCurrentDirectory) {
m_clearTerminal = false;
// the directory change, because this directory change is not caused by a "cd" command that the
// user entered in the panel. Therefore, we have to remember 'dir'. Note that it could also be
// a symbolic link -> remember the 'canonical' path.
- m_sendCdToTerminalHistory.enqueue(QDir(dir).canonicalPath());
+ if (addToHistory == HistoryPolicy::AddToHistory)
+ m_sendCdToTerminalHistory.enqueue(QDir(dir).canonicalPath());
if (m_clearTerminal) {
m_terminal->sendInput(QStringLiteral(" clear\n"));
TerminalPanel(QWidget* parent = 0);
virtual ~TerminalPanel();
+ /**
+ * @brief This function is used to set the terminal panels's cwd to
+ * home when an unmounting request is receieved.
+ */
+ void goHome();
+ QString currentWorkingDirectory();
+
public slots:
void terminalExited();
void dockVisibilityChanged();
void slotKonsolePartCurrentDirectoryChanged(const QString& dir);
private:
+ enum class HistoryPolicy {
+ AddToHistory,
+ SkipHistory
+ };
+
void changeDir(const QUrl& url);
- void sendCdToTerminal(const QString& path);
+ void sendCdToTerminal(const QString& path, HistoryPolicy addToHistory = HistoryPolicy::AddToHistory);
private:
bool m_clearTerminal;