diff --git a/smb4k/smb4knetworkbrowser.cpp b/smb4k/smb4knetworkbrowser.cpp index 826c8f9..2a3ebf2 100644 --- a/smb4k/smb4knetworkbrowser.cpp +++ b/smb4k/smb4knetworkbrowser.cpp @@ -1,263 +1,270 @@ /*************************************************************************** smb4knetworkbrowser - The network browser widget of Smb4K. ------------------- begin : Mo Jan 8 2007 copyright : (C) 2007-2020 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ // application specific includes #include "smb4knetworkbrowser.h" #include "smb4knetworkbrowseritem.h" #include "core/smb4ksettings.h" #include "core/smb4kglobal.h" #include "core/smb4kshare.h" // Qt includes #include #include #include #include #include // KDE includes #include using namespace Smb4KGlobal; Smb4KNetworkBrowser::Smb4KNetworkBrowser(QWidget *parent) : QTreeWidget(parent) { setRootIsDecorated(true); setAllColumnsShowFocus(false); setMouseTracking(true); setSelectionMode(ExtendedSelection); setContextMenuPolicy(Qt::CustomContextMenu); m_toolTip = new Smb4KToolTip(this); QStringList header_labels; header_labels.append(i18n("Network")); header_labels.append(i18n("Type")); header_labels.append(i18n("IP Address")); header_labels.append(i18n("Comment")); setHeaderLabels(header_labels); header()->setSectionResizeMode(QHeaderView::ResizeToContents); // // Connections // connect(this, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(slotItemActivated(QTreeWidgetItem*,int))); connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged())); } Smb4KNetworkBrowser::~Smb4KNetworkBrowser() { } +Smb4KToolTip *Smb4KNetworkBrowser::toolTip() +{ + return m_toolTip; +} + + + bool Smb4KNetworkBrowser::event(QEvent *e) { switch (e->type()) { case QEvent::ToolTip: { // // Intercept the tool tip event and show our own tool tip // QPoint pos = viewport()->mapFromGlobal(cursor().pos()); Smb4KNetworkBrowserItem *item = static_cast(itemAt(pos)); if (item) { if (Smb4KSettings::showNetworkItemToolTip()) { int ind = 0; switch (item->type()) { case Host: { ind = 2; break; } case Share: { ind = 3; break; } default: { ind = 1; break; } } // // Show the tooltip // if (pos.x() > ind * indentation()) { // // Set up the tooltip // m_toolTip->setupToolTip(Smb4KToolTip::NetworkItem, item->networkItem()); // // Show the tooltip // m_toolTip->show(cursor().pos(), nativeParentWidget()->windowHandle()); } } } break; } default: { break; } } return QTreeWidget::event(e); } void Smb4KNetworkBrowser::mousePressEvent(QMouseEvent *e) { // // Hide the tooltip // if (m_toolTip->isVisible()) { m_toolTip->hide(); } // // Get the item that is under the mouse. If there is no // item, unselect the current item. // QTreeWidgetItem *item = itemAt(e->pos()); if (!item && currentItem()) { currentItem()->setSelected(false); setCurrentItem(0); } QTreeWidget::mousePressEvent(e); } void Smb4KNetworkBrowser::mouseMoveEvent(QMouseEvent* e) { // // Hide the tooltip // if (m_toolTip->isVisible()) { m_toolTip->hide(); } QTreeWidget::mouseMoveEvent(e); } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KNetworkBrowser::slotItemActivated(QTreeWidgetItem *item, int /*column*/) { // Only do something if there are no keyboard modifiers pressed // and there is only one item selected. if (QApplication::keyboardModifiers() == Qt::NoModifier && selectedItems().size() == 1) { if (item) { switch (item->type()) { case Workgroup: case Host: { if (!item->isExpanded()) { expandItem(item); } else { collapseItem(item); } break; } default: { break; } } } } } void Smb4KNetworkBrowser::slotItemSelectionChanged() { if (selectedItems().size() > 1) { // If multiple items are selected, only allow shares // to stay selected. for (int i = 0; i < selectedItems().size(); ++i) { Smb4KNetworkBrowserItem *item = static_cast(selectedItems()[i]); if (item) { switch (item->networkItem()->type()) { case Workgroup: case Host: { item->setSelected(false); break; } case Share: { if (item->shareItem()->isPrinter()) { item->setSelected(false); } break; } default: { break; } } } } } } diff --git a/smb4k/smb4knetworkbrowser.h b/smb4k/smb4knetworkbrowser.h index 38c5fff..ed1d330 100644 --- a/smb4k/smb4knetworkbrowser.h +++ b/smb4k/smb4knetworkbrowser.h @@ -1,113 +1,118 @@ /*************************************************************************** smb4knetworkbrowser - The network browser widget of Smb4K. ------------------- begin : Mo Jan 8 2007 copyright : (C) 2007-2020 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ #ifndef SMB4KNETWORKBROWSER_H #define SMB4KNETWORKBROWSER_H // application specific includes -#include +#include "smb4ktooltip.h" // Qt includes #include // forward declarations class Smb4KNetworkBrowserItem; /** * This is the network neighborhood browser widget. * * @author Alexander Reinholdt */ class Smb4KNetworkBrowser : public QTreeWidget { Q_OBJECT public: /** * The constructor * * @param parent The parent widget */ explicit Smb4KNetworkBrowser(QWidget *parent = 0); /** * The destructor */ ~Smb4KNetworkBrowser(); /** * Enumeration for the columns in the list view. */ enum Columns{ Network = 0, Type = 1, IP = 2, Comment = 3 }; + + /** + * The tooltip + */ + Smb4KToolTip *toolTip(); protected: /** * Reimplemented from QWidget. */ bool event(QEvent *e) override; /** * Reimplemented from QAbstractItemView. This function handles * mouse press events. * * @param e The mouse event object */ void mousePressEvent(QMouseEvent *e) override; /** * Reimplemented from QAbstractItemView. This function handles * mouse move events. * * @param e The mouse event object */ void mouseMoveEvent(QMouseEvent *e) override; protected slots: /** * This slot is called when the user activated an item. It is used * to open the item if it is expandable. * @param item The item that has been activated. * @param column The column where the item was activated. */ void slotItemActivated(QTreeWidgetItem *item, int column); /** * Take care that only shares are selected when the user marks multiple * shares. */ void slotItemSelectionChanged(); private: /** * The tool top widget */ Smb4KToolTip *m_toolTip; }; #endif diff --git a/smb4k/smb4knetworkbrowserdockwidget.cpp b/smb4k/smb4knetworkbrowserdockwidget.cpp index 24c77be..4db7502 100644 --- a/smb4k/smb4knetworkbrowserdockwidget.cpp +++ b/smb4k/smb4knetworkbrowserdockwidget.cpp @@ -1,1431 +1,1446 @@ /*************************************************************************** The network neighborhood browser dock widget ------------------- begin : Sat Apr 28 2018 copyright : (C) 2018-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ // application specific includes #include "smb4knetworkbrowserdockwidget.h" #include "smb4knetworkbrowseritem.h" #include "core/smb4kmounter.h" #include "core/smb4kworkgroup.h" #include "core/smb4khost.h" #include "core/smb4kshare.h" #include "core/smb4ksettings.h" #include "core/smb4kbookmarkhandler.h" #include "core/smb4kwalletmanager.h" #include "core/smb4kcustomoptionsmanager.h" #include "core/smb4kclient.h" // Qt includes #include #include #include #include #include // KDE includes #include #include #include #include using namespace Smb4KGlobal; Smb4KNetworkBrowserDockWidget::Smb4KNetworkBrowserDockWidget(const QString& title, QWidget* parent) : QDockWidget(title, parent) { // // The network browser widget // QWidget *mainWidget = new QWidget(this); QVBoxLayout *mainWidgetLayout = new QVBoxLayout(mainWidget); mainWidgetLayout->setContentsMargins(0, 0, 0, 0); mainWidgetLayout->setSpacing(5); m_networkBrowser = new Smb4KNetworkBrowser(mainWidget); m_searchToolBar = new Smb4KNetworkSearchToolBar(mainWidget); m_searchToolBar->setVisible(false); mainWidgetLayout->addWidget(m_networkBrowser); mainWidgetLayout->addWidget(m_searchToolBar); setWidget(mainWidget); // // The action collection // m_actionCollection = new KActionCollection(this); // // The context menu // m_contextMenu = new KActionMenu(this); // // Search underway? // m_searchRunning = false; // // Set up the actions // setupActions(); // // Load the settings // loadSettings(); // // Connections // connect(m_networkBrowser, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenuRequested(QPoint))); connect(m_networkBrowser, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(slotItemActivated(QTreeWidgetItem*,int))); connect(m_networkBrowser, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged())); connect(m_searchToolBar, SIGNAL(close()), this, SLOT(slotHideSearchToolBar())); connect(m_searchToolBar, SIGNAL(search(QString)), this, SLOT(slotPerformSearch(QString))); connect(m_searchToolBar, SIGNAL(abort()), this, SLOT(slotStopSearch())); connect(m_searchToolBar, SIGNAL(jumpToResult(QString)), this, SLOT(slotJumpToResult(QString))); connect(m_searchToolBar, SIGNAL(clearSearchResults()), this, SLOT(slotClearSearchResults())); connect(Smb4KClient::self(), SIGNAL(aboutToStart(NetworkItemPtr,int)), this, SLOT(slotClientAboutToStart(NetworkItemPtr,int))); connect(Smb4KClient::self(), SIGNAL(finished(NetworkItemPtr,int)), this, SLOT(slotClientFinished(NetworkItemPtr,int))); connect(Smb4KClient::self(), SIGNAL(workgroups()), this, SLOT(slotWorkgroups())); connect(Smb4KClient::self(), SIGNAL(hosts(WorkgroupPtr)), this, SLOT(slotWorkgroupMembers(WorkgroupPtr))); connect(Smb4KClient::self(), SIGNAL(shares(HostPtr)), this, SLOT(slotShares(HostPtr))); connect(Smb4KClient::self(), SIGNAL(searchResults(QList)), this, SLOT(slotSearchResults(QList))); connect(Smb4KMounter::self(), SIGNAL(mounted(SharePtr)), this, SLOT(slotShareMounted(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(unmounted(SharePtr)), this, SLOT(slotShareUnmounted(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(aboutToStart(int)), this, SLOT(slotMounterAboutToStart(int))); connect(Smb4KMounter::self(), SIGNAL(finished(int)), this, SLOT(slotMounterFinished(int))); connect(KIconLoader::global(), SIGNAL(iconChanged(int)), this, SLOT(slotIconSizeChanged(int))); } Smb4KNetworkBrowserDockWidget::~Smb4KNetworkBrowserDockWidget() { } void Smb4KNetworkBrowserDockWidget::setupActions() { // // Rescan and abort dual action // KDualAction *rescanAbortAction = new KDualAction(this); rescanAbortAction->setInactiveIcon(KDE::icon("view-refresh")); rescanAbortAction->setInactiveText(i18n("Scan Netwo&rk")); rescanAbortAction->setActiveIcon(KDE::icon("process-stop")); rescanAbortAction->setActiveText(i18n("&Abort")); rescanAbortAction->setAutoToggle(false); rescanAbortAction->setEnabled(true); connect(rescanAbortAction, SIGNAL(triggered(bool)), this, SLOT(slotRescanAbortActionTriggered(bool))); m_actionCollection->addAction("rescan_abort_action", rescanAbortAction); m_actionCollection->setDefaultShortcut(rescanAbortAction, QKeySequence::Refresh); // // Search action // QAction *searchAction = new QAction(KDE::icon("search"), i18n("&Search"), this); connect(searchAction, SIGNAL(triggered(bool)), this, SLOT(slotShowSearchToolBar())); m_actionCollection->addAction("search_action", searchAction); m_actionCollection->setDefaultShortcut(searchAction, QKeySequence::Find); // // Separator // QAction *separator1 = new QAction(this); separator1->setSeparator(true); m_actionCollection->addAction("network_separator1", separator1); // // Bookmark action // QAction *bookmarkAction = new QAction(KDE::icon("bookmark-new"), i18n("Add &Bookmark"), this); bookmarkAction->setEnabled(false); connect(bookmarkAction, SIGNAL(triggered(bool)), this, SLOT(slotAddBookmark(bool))); m_actionCollection->addAction("bookmark_action", bookmarkAction); m_actionCollection->setDefaultShortcut(bookmarkAction, QKeySequence(Qt::CTRL+Qt::Key_B)); // // Mount dialog action // QAction *manualAction = new QAction(KDE::icon("view-form", QStringList("emblem-mounted")), i18n("&Open Mount Dialog"), this); manualAction->setEnabled(true); connect(manualAction, SIGNAL(triggered(bool)), this, SLOT(slotMountManually(bool))); m_actionCollection->addAction("mount_manually_action", manualAction); m_actionCollection->setDefaultShortcut(manualAction, QKeySequence(Qt::CTRL+Qt::Key_O)); // // Separator // QAction *separator2 = new QAction(this); separator2->setSeparator(true); m_actionCollection->addAction("network_separator2", separator2); // // Authentication action // QAction *authAction = new QAction(KDE::icon("dialog-password"), i18n("Au&thentication"), this); authAction->setEnabled(false); connect(authAction, SIGNAL(triggered(bool)), this, SLOT(slotAuthentication(bool))); m_actionCollection->addAction("authentication_action", authAction); m_actionCollection->setDefaultShortcut(authAction, QKeySequence(Qt::CTRL+Qt::Key_T)); // // Custom options action // QAction *customAction = new QAction(KDE::icon("preferences-system-network"), i18n("&Custom Options"), this); customAction->setEnabled(false); connect(customAction, SIGNAL(triggered(bool)), this, SLOT(slotCustomOptions(bool))); m_actionCollection->addAction("custom_action", customAction); m_actionCollection->setDefaultShortcut(customAction, QKeySequence(Qt::CTRL+Qt::Key_C)); // // Preview action // QAction *previewAction = new QAction(KDE::icon("view-list-icons"), i18n("Pre&view"), this); previewAction->setEnabled(false); connect(previewAction, SIGNAL(triggered(bool)), this, SLOT(slotPreview(bool))); m_actionCollection->addAction("preview_action", previewAction); m_actionCollection->setDefaultShortcut(previewAction, QKeySequence(Qt::CTRL+Qt::Key_V)); // // Print action // QAction *printAction = new QAction(KDE::icon("printer"), i18n("&Print File"), this); printAction->setEnabled(false); connect(printAction, SIGNAL(triggered(bool)), this, SLOT(slotPrint(bool))); m_actionCollection->addAction("print_action", printAction); m_actionCollection->setDefaultShortcut(printAction, QKeySequence(Qt::CTRL+Qt::Key_P)); // // Mount/unmount action // KDualAction *mountAction = new KDualAction(this); KGuiItem mountItem(i18n("&Mount"), KDE::icon("media-mount")); KGuiItem unmountItem(i18n("&Unmount"), KDE::icon("media-eject")); mountAction->setActiveGuiItem(mountItem); mountAction->setInactiveGuiItem(unmountItem); mountAction->setActive(true); mountAction->setAutoToggle(false); mountAction->setEnabled(false); connect(mountAction, SIGNAL(triggered(bool)), this, SLOT(slotMountActionTriggered(bool))); connect(mountAction, SIGNAL(activeChanged(bool)), this, SLOT(slotMountActionChanged(bool))); m_actionCollection->addAction("mount_action", mountAction); m_actionCollection->setDefaultShortcut(mountAction, QKeySequence(Qt::CTRL+Qt::Key_M)); // // Plug the actions into the context menu // for (QAction *a : m_actionCollection->actions()) { m_contextMenu->addAction(a); } } void Smb4KNetworkBrowserDockWidget::loadSettings() { // // Load icon size // int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small); m_networkBrowser->setIconSize(QSize(iconSize, iconSize)); // // Show/hide columns // m_networkBrowser->setColumnHidden(Smb4KNetworkBrowser::IP, !Smb4KSettings::showIPAddress()); m_networkBrowser->setColumnHidden(Smb4KNetworkBrowser::Type, !Smb4KSettings::showType()); m_networkBrowser->setColumnHidden(Smb4KNetworkBrowser::Comment, !Smb4KSettings::showComment()); // // Load and apply the positions of the columns // KConfigGroup configGroup(Smb4KSettings::self()->config(), "NetworkBrowserPart"); QMap map; map.insert(configGroup.readEntry("ColumnPositionNetwork", (int)Smb4KNetworkBrowser::Network), Smb4KNetworkBrowser::Network); map.insert(configGroup.readEntry("ColumnPositionType", (int)Smb4KNetworkBrowser::Type), Smb4KNetworkBrowser::Type); map.insert(configGroup.readEntry("ColumnPositionIP", (int)Smb4KNetworkBrowser::IP), Smb4KNetworkBrowser::IP); map.insert(configGroup.readEntry("ColumnPositionComment", (int)Smb4KNetworkBrowser::Comment), Smb4KNetworkBrowser::Comment); QMap::const_iterator it = map.constBegin(); while (it != map.constEnd()) { if (it.key() != m_networkBrowser->header()->visualIndex(it.value())) { m_networkBrowser->header()->moveSection(m_networkBrowser->header()->visualIndex(it.value()), it.key()); } ++it; } // // Apply the completion strings to the search toolbar // m_searchToolBar->setCompletionStrings(configGroup.readEntry("SearchItemCompletion", QStringList())); // // Does anything has to be changed with the marked shares? // for (const SharePtr &share : mountedSharesList()) { // We do not need to use slotShareUnmounted() here, too, // because slotShareMounted() will take care of everything // we need here. slotShareMounted(share); } // // Adjust the actions, if needed // slotItemSelectionChanged(); } void Smb4KNetworkBrowserDockWidget::saveSettings() { // // Save the position of the columns // KConfigGroup configGroup(Smb4KSettings::self()->config(), "NetworkBrowserPart"); configGroup.writeEntry("ColumnPositionNetwork", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::Network)); configGroup.writeEntry("ColumnPositionType", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::Type)); configGroup.writeEntry("ColumnPositionIP", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::IP)); configGroup.writeEntry("ColumnPositionComment", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::Comment)); // // Save the completion strings // configGroup.writeEntry("SearchItemCompletion", m_searchToolBar->completionStrings()); configGroup.sync(); } KActionCollection *Smb4KNetworkBrowserDockWidget::actionCollection() { return m_actionCollection; } void Smb4KNetworkBrowserDockWidget::slotContextMenuRequested(const QPoint& pos) { m_contextMenu->menu()->popup(m_networkBrowser->viewport()->mapToGlobal(pos)); } void Smb4KNetworkBrowserDockWidget::slotItemActivated(QTreeWidgetItem* item, int /*column*/) { // // Process the activated item // if (QApplication::keyboardModifiers() == Qt::NoModifier && m_networkBrowser->selectedItems().size() == 1) { Smb4KNetworkBrowserItem *browserItem = static_cast(item); if (browserItem) { switch (browserItem->type()) { case Workgroup: { if (browserItem->isExpanded()) { Smb4KClient::self()->lookupDomainMembers(browserItem->workgroupItem()); } break; } case Host: { if (browserItem->isExpanded()) { Smb4KClient::self()->lookupShares(browserItem->hostItem()); } break; } case Share: { if (!browserItem->shareItem()->isPrinter()) { slotMountActionTriggered(false); // boolean is ignored } else { slotPrint(false); // boolean is ignored } break; } default: { break; } } } } } void Smb4KNetworkBrowserDockWidget::slotItemSelectionChanged() { // // Get the selected item // QList items = m_networkBrowser->selectedItems(); // // Enable/disable and/or adjust the actions depending of the number // of selected items and their type // if (items.size() == 1) { Smb4KNetworkBrowserItem *browserItem = static_cast(items.first()); if (browserItem) { switch (browserItem->type()) { case Host: { // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Compute&r")); m_actionCollection->action("bookmark_action")->setEnabled(false); m_actionCollection->action("authentication_action")->setEnabled(true); m_actionCollection->action("custom_action")->setEnabled(true); m_actionCollection->action("preview_action")->setEnabled(false); m_actionCollection->action("print_action")->setEnabled(false); static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(false); break; } case Share: { // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Compute&r")); m_actionCollection->action("bookmark_action")->setEnabled(!browserItem->shareItem()->isPrinter()); m_actionCollection->action("authentication_action")->setEnabled(true); m_actionCollection->action("custom_action")->setEnabled(!browserItem->shareItem()->isPrinter()); m_actionCollection->action("preview_action")->setEnabled(!browserItem->shareItem()->isPrinter()); m_actionCollection->action("print_action")->setEnabled(browserItem->shareItem()->isPrinter()); if (!browserItem->shareItem()->isPrinter()) { if (!browserItem->shareItem()->isMounted() || (browserItem->shareItem()->isMounted() && browserItem->shareItem()->isForeign())) { static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(true); } else if (browserItem->shareItem()->isMounted() && !browserItem->shareItem()->isForeign()) { static_cast(m_actionCollection->action("mount_action"))->setActive(false); m_actionCollection->action("mount_action")->setEnabled(true); } else { static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(false); } } else { static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(true); } break; } default: { // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Wo&rkgroup")); m_actionCollection->action("bookmark_action")->setEnabled(false); m_actionCollection->action("authentication_action")->setEnabled(false); m_actionCollection->action("custom_action")->setEnabled(false); m_actionCollection->action("preview_action")->setEnabled(false); m_actionCollection->action("print_action")->setEnabled(false); static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(false); break; } } } } else if (items.size() > 1) { // // In this case there are only shares selected, because all other items // are automatically deselected in extended selection mode. // // For deciding which function the mount action should have, we use // the number of unmounted shares. If that is identical with the items.size(), // it will mount the items, otherwise it will unmount them. // int unmountedShares = items.size(); for (QTreeWidgetItem *item : items) { Smb4KNetworkBrowserItem *browserItem = static_cast(item); if (browserItem && browserItem->shareItem()->isMounted() && !browserItem->shareItem()->isForeign()) { // // Subtract shares mounted by the user // unmountedShares--; } } // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Netwo&rk")); m_actionCollection->action("bookmark_action")->setEnabled(true); m_actionCollection->action("authentication_action")->setEnabled(false); m_actionCollection->action("custom_action")->setEnabled(false); m_actionCollection->action("preview_action")->setEnabled(true); m_actionCollection->action("print_action")->setEnabled(false); static_cast(m_actionCollection->action("mount_action"))->setActive(unmountedShares == items.size()); m_actionCollection->action("mount_action")->setEnabled(true); } else { // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Netwo&rk")); m_actionCollection->action("bookmark_action")->setEnabled(false); m_actionCollection->action("authentication_action")->setEnabled(false); m_actionCollection->action("custom_action")->setEnabled(false); m_actionCollection->action("preview_action")->setEnabled(false); m_actionCollection->action("print_action")->setEnabled(false); static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(false); } } void Smb4KNetworkBrowserDockWidget::slotClientAboutToStart(const NetworkItemPtr& /*item*/, int process) { // // Get the rescan/abort action // KDualAction *rescanAbortAction = static_cast(m_actionCollection->action("rescan_abort_action")); // // Make adjustments // if (rescanAbortAction) { rescanAbortAction->setActive(true); m_actionCollection->setDefaultShortcut(rescanAbortAction, QKeySequence::Cancel); } // // Set the active status of the search tool bar // if (process == NetworkSearch) { m_searchToolBar->setActiveState(true); } } void Smb4KNetworkBrowserDockWidget::slotClientFinished(const NetworkItemPtr& /*item*/, int process) { // // Get the rescan/abort action // KDualAction *rescanAbortAction = static_cast(m_actionCollection->action("rescan_abort_action")); // // Make adjustments // if (rescanAbortAction) { rescanAbortAction->setActive(false); m_actionCollection->setDefaultShortcut(rescanAbortAction, QKeySequence::Refresh); } // // Set the active status of the search tool bar // if (process == NetworkSearch) { m_searchToolBar->setActiveState(false); } } void Smb4KNetworkBrowserDockWidget::slotWorkgroups() { if (!workgroupsList().isEmpty()) { // // Remove obsolete workgroups and update existing ones // QTreeWidgetItemIterator itemIt(m_networkBrowser, QTreeWidgetItemIterator::All); while (*itemIt) { Smb4KNetworkBrowserItem *networkItem = static_cast(*itemIt); if (networkItem->type() == Workgroup) { WorkgroupPtr workgroup = findWorkgroup(networkItem->workgroupItem()->workgroupName()); if (workgroup) { networkItem->update(); // Update the master browser for (int i = 0; i < networkItem->childCount(); ++i) { Smb4KNetworkBrowserItem *host = static_cast(networkItem->child(i)); host->update(); } } else { delete networkItem; } } ++itemIt; } // // Add new workgroups to the tree widget // for (const WorkgroupPtr &workgroup : workgroupsList()) { QList items = m_networkBrowser->findItems(workgroup->workgroupName(), Qt::MatchFixedString, Smb4KNetworkBrowser::Network); if (items.isEmpty()) { (void) new Smb4KNetworkBrowserItem(m_networkBrowser, workgroup); } } // // Sort the items // m_networkBrowser->sortItems(Smb4KNetworkBrowser::Network, Qt::AscendingOrder); + + // + // Update the tooltip + // + m_networkBrowser->toolTip()->update(); } else { // // Clear the tree widget // m_networkBrowser->clear(); } } void Smb4KNetworkBrowserDockWidget::slotWorkgroupMembers(const WorkgroupPtr& workgroup) { if (workgroup) { // // Find the right workgroup // QList workgroups = m_networkBrowser->findItems(workgroup->workgroupName(), Qt::MatchFixedString|Qt::MatchRecursive, Smb4KNetworkBrowser::Network); Smb4KNetworkBrowserItem *workgroupItem = nullptr; for (QTreeWidgetItem *item : workgroups) { Smb4KNetworkBrowserItem *tempWorkgroup = static_cast(item); if (tempWorkgroup->type() == Workgroup && tempWorkgroup->workgroupItem()->workgroupName() == workgroup->workgroupName()) { workgroupItem = tempWorkgroup; break; } } // // Process the hosts // if (workgroupItem) { // // Remove obsolete hosts and update existing ones // QTreeWidgetItemIterator hostIt(workgroupItem); while (*hostIt) { Smb4KNetworkBrowserItem *hostItem = static_cast(*hostIt); if (hostItem->type() == Host) { HostPtr host = findHost(hostItem->hostItem()->hostName(), hostItem->hostItem()->workgroupName()); if (host) { hostItem->update(); } else { delete hostItem; } } ++hostIt; } // // Add new hosts to the workgroup item and remove obsolete workgroups if // necessary. Honor the auto-expand feature. // QList members = workgroupMembers(workgroup); if (!members.isEmpty()) { for (const HostPtr &host : members) { bool foundHost = false; for (int i = 0; i < workgroupItem->childCount(); ++i) { Smb4KNetworkBrowserItem *hostItem = static_cast(workgroupItem->child(i)); if (hostItem->hostItem()->hostName() == host->hostName()) { foundHost = true; break; } } if (!foundHost) { (void) new Smb4KNetworkBrowserItem(workgroupItem, host); } } // // Auto-expand the workgroup item, if applicable // if (Smb4KSettings::autoExpandNetworkItems() && !workgroupItem->isExpanded() && !m_searchRunning) { m_networkBrowser->expandItem(workgroupItem); } } else { // // Remove empty workgroup. // delete workgroupItem; } // // Sort the items // m_networkBrowser->sortItems(Smb4KNetworkBrowser::Network, Qt::AscendingOrder); + + // + // Update the tooltip + // + m_networkBrowser->toolTip()->update(); } } } void Smb4KNetworkBrowserDockWidget::slotShares(const HostPtr& host) { if (host) { // // Find the right host // QList hosts = m_networkBrowser->findItems(host->hostName(), Qt::MatchFixedString|Qt::MatchRecursive, Smb4KNetworkBrowser::Network); Smb4KNetworkBrowserItem *hostItem = nullptr; for (QTreeWidgetItem *item : hosts) { Smb4KNetworkBrowserItem *tempHost = static_cast(item); if (tempHost->type() == Host && tempHost->hostItem()->workgroupName() == host->workgroupName()) { hostItem = tempHost; break; } } // // Process the shares // if (hostItem) { // // Remove obsolete shares and update existing ones // QTreeWidgetItemIterator shareIt(hostItem); while (*shareIt) { Smb4KNetworkBrowserItem *shareItem = static_cast(*shareIt); if (shareItem->type() == Share) { SharePtr share = findShare(shareItem->shareItem()->url(), shareItem->shareItem()->workgroupName()); if (share) { shareItem->update(); } else { delete shareItem; } } ++shareIt; } // // Add new shares to the host item. The host will not be removed from the // view when it has no shares. Honor the auto-expand feature. // QList shares = sharedResources(host); if (!shares.isEmpty()) { for (const SharePtr &share : shares) { bool foundShare = false; for (int i = 0; i < hostItem->childCount(); ++i) { Smb4KNetworkBrowserItem *shareItem = static_cast(hostItem->child(i)); if (shareItem->shareItem()->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort) == share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort)) { foundShare = true; break; } } if (!foundShare) { (void) new Smb4KNetworkBrowserItem(hostItem, share); } } // // Auto-expand the host item, if applicable // if (Smb4KSettings::autoExpandNetworkItems() && !hostItem->isExpanded() && !m_searchRunning) { m_networkBrowser->expandItem(hostItem); } } } // // Sort the items // m_networkBrowser->sortItems(Smb4KNetworkBrowser::Network, Qt::AscendingOrder); + + // + // Update the tooltip + // + m_networkBrowser->toolTip()->update(); } } void Smb4KNetworkBrowserDockWidget::slotRescanAbortActionTriggered(bool /*checked*/) { // // Get the Rescan/Abort action // KDualAction *rescanAbortAction = static_cast(m_actionCollection->action("rescan_abort_action")); // // Get the selected items // QList selectedItems = m_networkBrowser->selectedItems(); // // Perform actions according to the state of the action and the number of // selected items. // if (!rescanAbortAction->isActive()) { if (selectedItems.size() == 1) { Smb4KNetworkBrowserItem *browserItem = static_cast(selectedItems.first()); if (browserItem) { switch (browserItem->type()) { case Workgroup: { Smb4KClient::self()->lookupDomainMembers(browserItem->workgroupItem()); break; } case Host: { Smb4KClient::self()->lookupShares(browserItem->hostItem()); break; } case Share: { Smb4KNetworkBrowserItem *parentItem = static_cast(browserItem->parent()); Smb4KClient::self()->lookupShares(parentItem->hostItem()); break; } default: { break; } } } } else { // // If several items are selected or no selected items, // only the network can be scanned. // Smb4KClient::self()->lookupDomains(); } } else { // // Stop all actions performed by the client // if (Smb4KClient::self()->isRunning()) { Smb4KClient::self()->abort(); } } } void Smb4KNetworkBrowserDockWidget::slotAddBookmark(bool /*checked*/) { QList items = m_networkBrowser->selectedItems(); QList shares; if (!items.isEmpty()) { for (int i = 0; i < items.size(); ++i) { Smb4KNetworkBrowserItem *item = static_cast(items.at(i)); if (item && item->type() == Share && !item->shareItem()->isPrinter()) { shares << item->shareItem(); } } } else { // No selected items. Just return. return; } if (!shares.isEmpty()) { Smb4KBookmarkHandler::self()->addBookmarks(shares); } } void Smb4KNetworkBrowserDockWidget::slotMountManually(bool /*checked*/) { Smb4KMounter::self()->openMountDialog(); } void Smb4KNetworkBrowserDockWidget::slotAuthentication(bool /*checked*/) { Smb4KNetworkBrowserItem *item = static_cast(m_networkBrowser->currentItem()); if (item) { switch (item->type()) { case Host: { Smb4KWalletManager::self()->showPasswordDialog(item->hostItem()); break; } case Share: { Smb4KWalletManager::self()->showPasswordDialog(item->shareItem()); break; } default: { break; } } } } void Smb4KNetworkBrowserDockWidget::slotCustomOptions(bool /*checked*/) { Smb4KNetworkBrowserItem *item = static_cast(m_networkBrowser->currentItem()); if (item) { switch (item->type()) { case Host: { Smb4KCustomOptionsManager::self()->openCustomOptionsDialog(item->hostItem()); break; } case Share: { Smb4KCustomOptionsManager::self()->openCustomOptionsDialog(item->shareItem()); break; } default: { break; } } } } void Smb4KNetworkBrowserDockWidget::slotPreview(bool /*checked*/) { QList items = m_networkBrowser->selectedItems(); if (!items.isEmpty()) { for (int i = 0; i < items.size(); ++i) { Smb4KNetworkBrowserItem *item = static_cast(items.at(i)); if (item && item->type() == Share && !item->shareItem()->isPrinter()) { Smb4KClient::self()->openPreviewDialog(item->shareItem()); } } } } void Smb4KNetworkBrowserDockWidget::slotPrint(bool /*checked*/) { Smb4KNetworkBrowserItem *item = static_cast(m_networkBrowser->currentItem()); if (item && item->shareItem()->isPrinter()) { Smb4KClient::self()->openPrintDialog(item->shareItem()); } } void Smb4KNetworkBrowserDockWidget::slotMountActionTriggered(bool /*checked*/) { // // Get the selected items // QList selectedItems = m_networkBrowser->selectedItems(); if (selectedItems.size() > 1) { // // In the case of multiple selected network items, selectedItems() // only contains shares. Thus, we do not need to test for the type. // For deciding what the mount action is supposed to do, i.e. mount // the (remaining) selected unmounted shares or unmounting all selected // mounted shares, we use the number of unmounted shares. If that is // greater than 0, we mount all shares that need to be mounted, otherwise // we unmount all selected shares. // QList unmounted, mounted; for (QTreeWidgetItem *item : selectedItems) { Smb4KNetworkBrowserItem *browserItem = static_cast(item); if (browserItem && browserItem->shareItem()->isMounted()) { mounted << browserItem->shareItem(); } else if (browserItem && !browserItem->shareItem()->isMounted()) { unmounted << browserItem->shareItem(); } } if (!unmounted.empty()) { // Mount the (remaining) unmounted shares. Smb4KMounter::self()->mountShares(unmounted); } else { // Unmount all shares. Smb4KMounter::self()->unmountShares(mounted, m_networkBrowser); } } else { // // If only one network item is selected, we need to test for the type // of the item. Only in case of a share we need to do something. // Smb4KNetworkBrowserItem *browserItem = static_cast(selectedItems.first()); if (browserItem) { switch (browserItem->type()) { case Share: { if (!browserItem->shareItem()->isMounted()) { Smb4KMounter::self()->mountShare(browserItem->shareItem()); } else { Smb4KMounter::self()->unmountShare(browserItem->shareItem(), false); } break; } default: { break; } } } } } void Smb4KNetworkBrowserDockWidget::slotMountActionChanged(bool active) { // // Get the mount action // KDualAction *mountAction = static_cast(m_actionCollection->action("mount_action")); // // Change the shortcuts depending on the value of the 'active' argument // if (mountAction) { if (active) { m_actionCollection->setDefaultShortcut(mountAction, QKeySequence(Qt::CTRL+Qt::Key_M)); } else { m_actionCollection->setDefaultShortcut(mountAction, QKeySequence(Qt::CTRL+Qt::Key_U)); } } } void Smb4KNetworkBrowserDockWidget::slotShareMounted(const SharePtr& share) { QTreeWidgetItemIterator it(m_networkBrowser); while (*it) { Smb4KNetworkBrowserItem *item = static_cast(*it); if (item->type() == Share) { if (QString::compare(item->shareItem()->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { item->update(); break; } } ++it; } } void Smb4KNetworkBrowserDockWidget::slotShareUnmounted(const SharePtr& share) { QTreeWidgetItemIterator it(m_networkBrowser); while (*it) { Smb4KNetworkBrowserItem *item = static_cast(*it); if (item->type() == Share) { if (QString::compare(item->shareItem()->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { item->update(); break; } } ++it; } } void Smb4KNetworkBrowserDockWidget::slotMounterAboutToStart(int /*process*/) { // // Unused at the moment // } void Smb4KNetworkBrowserDockWidget::slotMounterFinished(int process) { // // Get the mount/unmount action // KDualAction *mountAction = static_cast(m_actionCollection->action("mount_action")); // // Make adjustments // if (mountAction) { switch (process) { case MountShare: { mountAction->setActive(false); break; } case UnmountShare: { mountAction->setActive(true); break; } default: { break; } } } } void Smb4KNetworkBrowserDockWidget::slotIconSizeChanged(int group) { switch (group) { case KIconLoader::Small: { int icon_size = KIconLoader::global()->currentSize(KIconLoader::Small); m_networkBrowser->setIconSize(QSize(icon_size, icon_size)); break; } default: { break; } } } void Smb4KNetworkBrowserDockWidget::slotShowSearchToolBar() { // // Show the search toolbar // m_searchToolBar->setVisible(true); // // Set the focus to the search item input // m_searchToolBar->prepareInput(); } void Smb4KNetworkBrowserDockWidget::slotHideSearchToolBar() { // // Prevent another dock widget from stealing the focus when // the search tool bar is hidden // m_networkBrowser->setFocus(); // // Hide the search toolbar // m_searchToolBar->setVisible(false); } void Smb4KNetworkBrowserDockWidget::slotPerformSearch(const QString& item) { // // Prevent another dock widget from stealing the focus when // the search item input is disabled // m_networkBrowser->setFocus(); // // A global search is underway // m_searchRunning = true; // // Start the search // Smb4KClient::self()->search(item); } void Smb4KNetworkBrowserDockWidget::slotStopSearch() { // // Stop the network search // Smb4KClient::self()->abort(); // // A global search finished // m_searchRunning = false; } void Smb4KNetworkBrowserDockWidget::slotSearchResults(const QList& shares) { // // A global search finished // m_searchRunning = false; // // Process the search results // QTreeWidgetItemIterator it(m_networkBrowser); while (*it) { Smb4KNetworkBrowserItem *networkItem = static_cast(*it); if (networkItem->type() == Share) { for (const SharePtr &share : shares) { if (networkItem->shareItem() == share) { // // Select the search result // networkItem->setSelected(true); // // Expand the branch of the network tree where a search result // was retrieved // if (!networkItem->parent()->isExpanded()) { m_networkBrowser->expandItem(networkItem->parent()); } if (!networkItem->parent()->parent()->isExpanded()) { m_networkBrowser->expandItem(networkItem->parent()->parent()); } } } } it++; } // // Pass the search results to the search toolbar // m_searchToolBar->setSearchResults(shares); } void Smb4KNetworkBrowserDockWidget::slotJumpToResult(const QString& url) { // // Find the share item with URL url // QTreeWidgetItemIterator it(m_networkBrowser); while (*it) { Smb4KNetworkBrowserItem *networkItem = static_cast(*it); if (networkItem->type() == Share && networkItem->shareItem()->url().toString() == url) { m_networkBrowser->setCurrentItem(networkItem); break; } it++; } } void Smb4KNetworkBrowserDockWidget::slotClearSearchResults() { m_networkBrowser->clearSelection(); } diff --git a/smb4k/smb4ksharesview.cpp b/smb4k/smb4ksharesview.cpp index 479b18f..ce68aee 100644 --- a/smb4k/smb4ksharesview.cpp +++ b/smb4k/smb4ksharesview.cpp @@ -1,313 +1,319 @@ /*************************************************************************** This is the shares view of Smb4K. ------------------- begin : Mo Dez 4 2006 copyright : (C) 2006-2020 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ // application specific includes #include "smb4ksharesview.h" #include "smb4ksharesviewitem.h" #include "core/smb4kshare.h" #include "core/smb4ksettings.h" // Qt includes #include #include #include // KDE includes #include Smb4KSharesView::Smb4KSharesView(QWidget *parent) : QListWidget(parent) { setMouseTracking(true); setSelectionMode(ExtendedSelection); setResizeMode(Adjust); setSortingEnabled(true); setWordWrap(true); setAcceptDrops(true); setDragEnabled(true); setDropIndicatorShown(true); setUniformItemSizes(true); setWrapping(true); m_toolTip = new Smb4KToolTip(this); setContextMenuPolicy(Qt::CustomContextMenu); } Smb4KSharesView::~Smb4KSharesView() { } void Smb4KSharesView::setViewMode(QListView::ViewMode mode, int iconSize) { // // Set the view mode // QListWidget::setViewMode(mode); // // Make adjustments // switch(mode) { case IconMode: { setUniformItemSizes(true); setIconSize(QSize(iconSize, iconSize)); setSpacing(5); break; } case ListMode: { setUniformItemSizes(false); setIconSize(QSize(iconSize, iconSize)); setSpacing(0); break; } default: { break; } } // // Align the items // for (int i = 0; i < count(); ++i) { Smb4KSharesViewItem *viewItem = static_cast(item(i)); viewItem->setItemAlignment(mode); } } +Smb4KToolTip *Smb4KSharesView::toolTip() +{ + return m_toolTip; +} + + bool Smb4KSharesView::event(QEvent *e) { switch (e->type()) { case QEvent::ToolTip: { // Intercept the tool tip event and show our own tool tip. QPoint pos = viewport()->mapFromGlobal(cursor().pos()); Smb4KSharesViewItem *item = static_cast(itemAt(pos)); if (item) { if (Smb4KSettings::showShareToolTip()) { // // Set up the tooltip // m_toolTip->setupToolTip(Smb4KToolTip::MountedShare, item->shareItem()); // // Show the tooltip // m_toolTip->show(cursor().pos(), nativeParentWidget()->windowHandle()); } } break; } default: { break; } } return QListWidget::event(e); } void Smb4KSharesView::mousePressEvent(QMouseEvent *e) { // // Hide the tooltip // if (m_toolTip->isVisible()) { m_toolTip->hide(); } // // Get the item that is under the mouse. If there is no // item, unselect the current item. // QListWidgetItem *item = itemAt(e->pos()); if (!item && !selectedItems().isEmpty()) { clearSelection(); setCurrentItem(0); emit itemPressed(currentItem()); } QListWidget::mousePressEvent(e); } void Smb4KSharesView::mouseMoveEvent(QMouseEvent* e) { // // Hide the tooltip // if (m_toolTip->isVisible()) { m_toolTip->hide(); } QListWidget::mouseMoveEvent(e); } void Smb4KSharesView::dragEnterEvent(QDragEnterEvent *e) { if (e->mimeData()->hasUrls()) { e->accept(); } else { e->ignore(); } } void Smb4KSharesView::dragMoveEvent(QDragMoveEvent *e) { // Let the QAbstractItemView do the highlighting of the item, etc. QAbstractItemView::dragMoveEvent(e); // Now we do our thing. Smb4KSharesViewItem *item = static_cast(itemAt(e->pos())); if (item && !item->shareItem()->isInaccessible() && (item->flags() & Qt::ItemIsDropEnabled) && (e->proposedAction() & (Qt::CopyAction | Qt::MoveAction))) { QUrl url = QUrl::fromLocalFile(item->shareItem()->path()); if (e->source() == this && e->mimeData()->urls().first() == url) { e->ignore(); } else { e->accept(); } } else { e->ignore(); } } void Smb4KSharesView::dropEvent(QDropEvent *e) { // Get the item and process the drop event Smb4KSharesViewItem *item = static_cast(itemAt(e->pos())); if (item && !item->shareItem()->isInaccessible() && (e->proposedAction() & (Qt::CopyAction|Qt::MoveAction))) { QUrl url = QUrl::fromLocalFile(item->shareItem()->path()); if (e->source() == this && e->mimeData()->urls().first() == url) { e->ignore(); } else { e->acceptProposedAction(); emit acceptedDropEvent(item, e); e->accept(); } } else { e->ignore(); } } Qt::DropActions Smb4KSharesView::supportedDropActions() const { // Only allow copying and linking. return (Qt::CopyAction|Qt::LinkAction); } QMimeData *Smb4KSharesView::mimeData(const QList list) const { QMimeData *mimeData = new QMimeData(); QList urls; for (int i = 0; i < list.count(); ++i) { Smb4KSharesViewItem *item = static_cast(list.at(i)); urls << QUrl::fromLocalFile(item->shareItem()->path()); } mimeData->setUrls(urls); return mimeData; } void Smb4KSharesView::startDrag(Qt::DropActions supported) { QList list = selectedItems(); if (!list.isEmpty()) { QMimeData *data = mimeData(list); if (!data) { return; } QDrag *drag = new QDrag(this); QPixmap pixmap; if (list.count() == 1) { Smb4KSharesViewItem *item = static_cast(list.first()); pixmap = item->icon().pixmap(KIconLoader::SizeMedium); } else { pixmap = KDE::icon("document-multiple").pixmap(KIconLoader::SizeMedium); } drag->setPixmap(pixmap); drag->setMimeData(data); drag->exec(supported, Qt::IgnoreAction); } } diff --git a/smb4k/smb4ksharesview.h b/smb4k/smb4ksharesview.h index 5170ae6..18a6280 100644 --- a/smb4k/smb4ksharesview.h +++ b/smb4k/smb4ksharesview.h @@ -1,149 +1,154 @@ /*************************************************************************** This is the shares view of Smb4K. ------------------- begin : Mo Dez 4 2006 copyright : (C) 2006-2020 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ #ifndef SMB4KSHARESVIEW_H #define SMB4KSHARESVIEW_H // application specific includes #include // Qt includes #include #include #include // forward declarations class Smb4KSharesViewItem; class Smb4KToolTip; /** * This widget class provides the shares view of Smb4K. * * @author Alexander Reinholdt */ class Smb4KSharesView : public QListWidget { Q_OBJECT public: /** * The constructor. * * @param parent The parent widget */ explicit Smb4KSharesView(QWidget *parent = 0); /** * The destructor. */ ~Smb4KSharesView(); /** * Set the view mode. * * @param mode The view mode * @param iconSize The size of the icons */ void setViewMode(ViewMode mode, int iconSize); + + /** + * The tooltip + */ + Smb4KToolTip *toolTip(); signals: /** * This signal is emitted when something has been dropped onto * @p item and the drop event was accepted. * * @param item The item on which something has been dropped. * * @param e The drop event. */ void acceptedDropEvent(Smb4KSharesViewItem *item, QDropEvent *e); protected: /** * Reimplemented from QListWidget. */ bool event(QEvent *e) override; /** * Reimplemented from QAbstractItemView. This function handles * mouse press events. * * @param e The mouse event object */ void mousePressEvent(QMouseEvent *e) override; /** * Reimplemented from QAbstractItemView. This function handles * mouse move events. * * @param e The mouse event object */ void mouseMoveEvent(QMouseEvent *e) override; /** * Reimplemented to allow dragging and dropping. * * @param e The drag event */ virtual void dragEnterEvent(QDragEnterEvent *e) override; /** * Reimplemented to allow dragging and dropping. * * @param e The drag move event */ void dragMoveEvent(QDragMoveEvent *e) override; /** * Reimplemented to allow dragging and dropping. * * @param e The drop event */ void dropEvent(QDropEvent *e) override; /** * Reimplemented to allow only the copy drop action. */ Qt::DropActions supportedDropActions() const override; /** * Reimplemented to allow dragging. */ QMimeData *mimeData(const QList list) const override; /** * Reimplemented to allow dragging. */ void startDrag(Qt::DropActions supported) override; private: /** * The tool top widget */ Smb4KToolTip *m_toolTip; }; #endif diff --git a/smb4k/smb4ksharesviewdockwidget.cpp b/smb4k/smb4ksharesviewdockwidget.cpp index 1167f5d..6e8c320 100644 --- a/smb4k/smb4ksharesviewdockwidget.cpp +++ b/smb4k/smb4ksharesviewdockwidget.cpp @@ -1,648 +1,653 @@ /*************************************************************************** The network search widget dock widget ------------------- begin : Fri Mai 04 2018 copyright : (C) 2018-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ // application specific includes #include "smb4ksharesviewdockwidget.h" #include "smb4ksharesviewitem.h" #include "core/smb4ksettings.h" #include "core/smb4kmounter.h" #include "core/smb4ksynchronizer.h" #include "core/smb4kbookmarkhandler.h" #include "core/smb4kshare.h" #include "core/smb4khardwareinterface.h" #if defined(Q_OS_LINUX) #include "smb4kmountsettings_linux.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include "smb4kmountsettings_bsd.h" #endif // Qt includes #include #include #include #include // KDE includes #include #include #include #include #include Smb4KSharesViewDockWidget::Smb4KSharesViewDockWidget(const QString& title, QWidget* parent) : QDockWidget(title, parent) { // // Set the shares view // m_sharesView = new Smb4KSharesView(this); setWidget(m_sharesView); // // The action collection // m_actionCollection = new KActionCollection(this); // // The context menu // m_contextMenu = new KActionMenu(this); // // Set up the actions // setupActions(); // // Load the settings // loadSettings(); // // Connections // connect(m_sharesView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenuRequested(QPoint))); connect(m_sharesView, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(slotItemActivated(QListWidgetItem*))); connect(m_sharesView, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged())); connect(m_sharesView, SIGNAL(acceptedDropEvent(Smb4KSharesViewItem*,QDropEvent*)), this, SLOT(slotDropEvent(Smb4KSharesViewItem*,QDropEvent*))); connect(Smb4KMounter::self(), SIGNAL(mounted(SharePtr)), this, SLOT(slotShareMounted(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(unmounted(SharePtr)), this, SLOT(slotShareUnmounted(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(updated(SharePtr)), this, SLOT(slotShareUpdated(SharePtr))); connect(KIconLoader::global(), SIGNAL(iconChanged(int)), this, SLOT(slotIconSizeChanged(int))); } Smb4KSharesViewDockWidget::~Smb4KSharesViewDockWidget() { } void Smb4KSharesViewDockWidget::loadSettings() { // // Adjust the view according to the setting chosen // switch (Smb4KSettings::sharesViewMode()) { case Smb4KSettings::EnumSharesViewMode::IconView: { int iconSize = KIconLoader::global()->currentSize(KIconLoader::Desktop); m_sharesView->setViewMode(Smb4KSharesView::IconMode, iconSize); break; } case Smb4KSettings::EnumSharesViewMode::ListView: { int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small); m_sharesView->setViewMode(Smb4KSharesView::ListMode, iconSize); break; } default: { break; } } // // Adjust the unmount actions if needed // if (!m_sharesView->selectedItems().isEmpty()) { QList selectedItems = m_sharesView->selectedItems(); if (selectedItems.size() == 1) { Smb4KSharesViewItem *item = static_cast(selectedItems.first()); m_actionCollection->action("unmount_action")->setEnabled((!item->shareItem()->isForeign() || Smb4KMountSettings::unmountForeignShares())); } else if (selectedItems.size() > 1) { int foreign = 0; for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item && item->shareItem()->isForeign()) { foreign++; } } m_actionCollection->action("unmount_action")->setEnabled(((selectedItems.size() > foreign) || Smb4KMountSettings::unmountForeignShares())); } } actionCollection()->action("unmount_all_action")->setEnabled(((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && m_sharesView->count() != 0)); } void Smb4KSharesViewDockWidget::saveSettings() { // // Not used at the moment // } KActionCollection *Smb4KSharesViewDockWidget::actionCollection() { return m_actionCollection; } void Smb4KSharesViewDockWidget::setupActions() { // // The 'View Modes' submenu and the respective actions // KActionMenu *viewModesMenu = new KActionMenu(KDE::icon("view-choose"), i18n("View Modes"), this); QActionGroup *viewModesGroup = new QActionGroup(this); viewModesGroup->setExclusive(true); connect(viewModesGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotViewModeChanged(QAction*))); QAction *iconViewAction = new QAction(KDE::icon("view-list-icons"), i18n("Icon View"), this); iconViewAction->setObjectName("icon_view_action"); iconViewAction->setCheckable(true); viewModesGroup->addAction(iconViewAction); viewModesMenu->addAction(iconViewAction); QAction *listViewAction = new QAction(KDE::icon("view-list-details"), i18n("List View"), this); listViewAction->setObjectName("list_view_action"); listViewAction->setCheckable(true); viewModesGroup->addAction(listViewAction); viewModesMenu->addAction(listViewAction); switch (Smb4KSettings::sharesViewMode()) { case Smb4KSettings::EnumSharesViewMode::IconView: { iconViewAction->setChecked(true); break; } case Smb4KSettings::EnumSharesViewMode::ListView: { listViewAction->setChecked(true); break; } default: { break; } } // // The Unmount action // QAction *unmountAction = new QAction(KDE::icon("media-eject"), i18n("&Unmount"), this); connect(unmountAction, SIGNAL(triggered(bool)), this, SLOT(slotUnmountActionTriggered(bool))); // // The Unmount All action // QAction *unmountAllAction = new QAction(KDE::icon("system-run"), i18n("U&nmount All"), this); connect(unmountAllAction, SIGNAL(triggered(bool)), this, SLOT(slotUnmountAllActionTriggered(bool))); // // The Add Bookmark action // QAction *bookmarkAction = new QAction(KDE::icon("bookmark-new"), i18n("Add &Bookmark"), this); connect(bookmarkAction, SIGNAL(triggered(bool)), this, SLOT(slotBookmarkActionTriggered(bool))); // // The Synchronize action // QAction *synchronizeAction = new QAction(KDE::icon("folder-sync"), i18n("S&ynchronize"), this); connect(synchronizeAction, SIGNAL(triggered(bool)), this, SLOT(slotSynchronizeActionTriggered(bool))); // // The Open with Konsole action // QAction *konsoleAction = new QAction(KDE::icon("utilities-terminal"), i18n("Open with Konso&le"), this); connect(konsoleAction, SIGNAL(triggered(bool)), this, SLOT(slotKonsoleActionTriggered(bool))); QAction *filemanagerAction = new QAction(KDE::icon("system-file-manager"), i18n("Open with F&ile Manager"), this); connect(filemanagerAction, SIGNAL(triggered(bool)), this, SLOT(slotFileManagerActionTriggered(bool))); // // Three separators // QAction *separator1 = new QAction(this); separator1->setSeparator(true); QAction *separator2 = new QAction(this); separator2->setSeparator(true); QAction *separator3 = new QAction(this); separator3->setSeparator(true); // // Add the actions // m_actionCollection->addAction("shares_view_modes", viewModesMenu); m_actionCollection->addAction("shares_separator1", separator1); m_actionCollection->addAction("unmount_action", unmountAction); m_actionCollection->addAction("unmount_all_action", unmountAllAction); m_actionCollection->addAction("shares_separator2", separator2); m_actionCollection->addAction("bookmark_action", bookmarkAction); m_actionCollection->addAction("synchronize_action", synchronizeAction); m_actionCollection->addAction("shares_separator3", separator3); m_actionCollection->addAction("konsole_action", konsoleAction); m_actionCollection->addAction("filemanager_action", filemanagerAction); // // Set the shortcuts // m_actionCollection->setDefaultShortcut(unmountAction, QKeySequence(Qt::CTRL+Qt::Key_U)); m_actionCollection->setDefaultShortcut(unmountAllAction, QKeySequence(Qt::CTRL+Qt::Key_N)); m_actionCollection->setDefaultShortcut(bookmarkAction, QKeySequence(Qt::CTRL+Qt::Key_B)); m_actionCollection->setDefaultShortcut(synchronizeAction, QKeySequence(Qt::CTRL+Qt::Key_Y)); m_actionCollection->setDefaultShortcut(konsoleAction, QKeySequence(Qt::CTRL+Qt::Key_L)); m_actionCollection->setDefaultShortcut(filemanagerAction, QKeySequence(Qt::CTRL+Qt::Key_I)); // // Disable all actions // unmountAction->setEnabled(false); unmountAllAction->setEnabled(false); bookmarkAction->setEnabled(false); synchronizeAction->setEnabled(false); konsoleAction->setEnabled(false); filemanagerAction->setEnabled(false); // // Plug the actions into the context menu // for (QAction *a : m_actionCollection->actions()) { m_contextMenu->addAction(a); } } void Smb4KSharesViewDockWidget::slotContextMenuRequested(const QPoint& pos) { m_contextMenu->menu()->popup(m_sharesView->viewport()->mapToGlobal(pos)); } void Smb4KSharesViewDockWidget::slotItemActivated(QListWidgetItem* /*item*/) { // // Do not execute the item when keyboard modifiers were pressed // or the mouse button is not the left one. // if (QApplication::keyboardModifiers() == Qt::NoModifier) { slotFileManagerActionTriggered(false); } } void Smb4KSharesViewDockWidget::slotItemSelectionChanged() { QList selectedItems = m_sharesView->selectedItems(); if (selectedItems.size() == 1) { Smb4KSharesViewItem *item = static_cast(selectedItems.first()); bool syncRunning = Smb4KSynchronizer::self()->isRunning(item->shareItem()); m_actionCollection->action("unmount_action")->setEnabled((!item->shareItem()->isForeign() || Smb4KMountSettings::unmountForeignShares())); m_actionCollection->action("bookmark_action")->setEnabled(true); if (!item->shareItem()->isInaccessible()) { m_actionCollection->action("synchronize_action")->setEnabled(!QStandardPaths::findExecutable("rsync").isEmpty() && !syncRunning); m_actionCollection->action("konsole_action")->setEnabled(!QStandardPaths::findExecutable("konsole").isEmpty()); m_actionCollection->action("filemanager_action")->setEnabled(true); } else { m_actionCollection->action("synchronize_action")->setEnabled(false); m_actionCollection->action("konsole_action")->setEnabled(false); m_actionCollection->action("filemanager_action")->setEnabled(false); } } else if (selectedItems.size() > 1) { int syncsRunning = 0; int inaccessible = 0; int foreign = 0; for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item) { // Is the share synchronized at the moment? if (Smb4KSynchronizer::self()->isRunning(item->shareItem())) { syncsRunning += 1; } // Is the share inaccessible at the moment? if (item->shareItem()->isInaccessible()) { inaccessible += 1; } // Was the share being mounted by another user? if (item->shareItem()->isForeign()) { foreign += 1; } } } m_actionCollection->action("unmount_action")->setEnabled(((selectedItems.size() > foreign) || Smb4KMountSettings::unmountForeignShares())); m_actionCollection->action("bookmark_action")->setEnabled(true); if (selectedItems.size() > inaccessible) { m_actionCollection->action("synchronize_action")->setEnabled(!QStandardPaths::findExecutable("rsync").isEmpty() && (selectedItems.size() > syncsRunning)); m_actionCollection->action("konsole_action")->setEnabled(!QStandardPaths::findExecutable("konsole").isEmpty()); m_actionCollection->action("filemanager_action")->setEnabled(true); } else { m_actionCollection->action("synchronize_action")->setEnabled(false); m_actionCollection->action("konsole_action")->setEnabled(false); m_actionCollection->action("filemanager_action")->setEnabled(false); } } else { m_actionCollection->action("unmount_action")->setEnabled(false); m_actionCollection->action("bookmark_action")->setEnabled(false); m_actionCollection->action("synchronize_action")->setEnabled(false); m_actionCollection->action("konsole_action")->setEnabled(false); m_actionCollection->action("filemanager_action")->setEnabled(false); } } void Smb4KSharesViewDockWidget::slotDropEvent(Smb4KSharesViewItem* item, QDropEvent* e) { if (item && e) { if (e->mimeData()->hasUrls()) { if (Smb4KHardwareInterface::self()->isOnline()) { QUrl dest = QUrl::fromLocalFile(item->shareItem()->path()); KIO::DropJob *job = drop(e, dest, KIO::DefaultFlags); job->uiDelegate()->setAutoErrorHandlingEnabled(true); job->uiDelegate()->setAutoWarningHandlingEnabled(true); } else { KMessageBox::sorry(m_sharesView, i18n("There is no active connection to the share %1! You cannot drop any files here.", item->shareItem()->displayString())); } } } } void Smb4KSharesViewDockWidget::slotViewModeChanged(QAction* action) { // // Set the new view mode // if (action->objectName() == "icon_view_action") { Smb4KSettings::setSharesViewMode(Smb4KSettings::EnumSharesViewMode::IconView); } else if (action->objectName() == "list_view_action") { Smb4KSettings::setSharesViewMode(Smb4KSettings::EnumSharesViewMode::ListView); } // // Save settings // Smb4KSettings::self()->save(); // // Load the settings // loadSettings(); } void Smb4KSharesViewDockWidget::slotShareMounted(const SharePtr& share) { // // Add the share to the shares view // if (share) { // Add the item (void) new Smb4KSharesViewItem(m_sharesView, share); // Sort the view m_sharesView->sortItems(Qt::AscendingOrder); + // + // Update the tooltip + // + m_sharesView->toolTip()->update(); + // Enable/disable the 'Unmount All' action actionCollection()->action("unmount_all_action")->setEnabled( ((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && m_sharesView->count() != 0)); } } void Smb4KSharesViewDockWidget::slotShareUnmounted(const SharePtr& share) { // // Remove the share from the shares view // if (share) { // Get the item and delete it. Take care of the current item, if necessary. for (int i = 0; i < m_sharesView->count(); ++i) { Smb4KSharesViewItem *item = static_cast(m_sharesView->item(i)); if (item && (item->shareItem()->path() == share->path() || item->shareItem()->canonicalPath() == share->canonicalPath())) { if (item == m_sharesView->currentItem()) { m_sharesView->setCurrentItem(0); } delete m_sharesView->takeItem(i); break; } else { continue; } } // Enable/disable the 'Unmount All' action actionCollection()->action("unmount_all_action")->setEnabled( ((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && m_sharesView->count() != 0)); } } void Smb4KSharesViewDockWidget::slotShareUpdated(const SharePtr& share) { // // Get the share item and updated it // if (share) { for (int i = 0; i < m_sharesView->count(); ++i) { Smb4KSharesViewItem *item = static_cast(m_sharesView->item(i)); if (item && (item->shareItem()->path() == share->path() || item->shareItem()->canonicalPath() == share->canonicalPath())) { item->update(); break; } else { continue; } } } } void Smb4KSharesViewDockWidget::slotUnmountActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); QList shares; for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item) { shares << item->shareItem(); } } Smb4KMounter::self()->unmountShares(shares, false); } void Smb4KSharesViewDockWidget::slotUnmountAllActionTriggered(bool /*checked*/) { Smb4KMounter::self()->unmountAllShares(false); } void Smb4KSharesViewDockWidget::slotBookmarkActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); QList shares; for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); shares << item->shareItem(); } Smb4KBookmarkHandler::self()->addBookmarks(shares); } void Smb4KSharesViewDockWidget::slotSynchronizeActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item && !item->shareItem()->isInaccessible() && !Smb4KSynchronizer::self()->isRunning(item->shareItem())) { Smb4KSynchronizer::self()->synchronize(item->shareItem()); } } } void Smb4KSharesViewDockWidget::slotKonsoleActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item && !item->shareItem()->isInaccessible()) { openShare(item->shareItem(), Konsole); } } } void Smb4KSharesViewDockWidget::slotFileManagerActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item && !item->shareItem()->isInaccessible()) { openShare(item->shareItem(), FileManager); } } } void Smb4KSharesViewDockWidget::slotIconSizeChanged(int group) { // // Change the icon size depending of the view mode // if (group == KIconLoader::Desktop && Smb4KSettings::sharesViewMode() == Smb4KSettings::EnumSharesViewMode::IconView) { int iconSize = KIconLoader::global()->currentSize(KIconLoader::Desktop); m_sharesView->setIconSize(QSize(iconSize, iconSize)); } else if (group == KIconLoader::Small && Smb4KSettings::sharesViewMode() == Smb4KSettings::EnumSharesViewMode::ListView) { int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small); m_sharesView->setIconSize(QSize(iconSize, iconSize)); } } diff --git a/smb4k/smb4ktooltip.cpp b/smb4k/smb4ktooltip.cpp index 519c0b9..3332927 100644 --- a/smb4k/smb4ktooltip.cpp +++ b/smb4k/smb4ktooltip.cpp @@ -1,572 +1,612 @@ /*************************************************************************** smb4ktooltip - Provides tooltips for Smb4K ------------------- begin : Mi Mai 2020 copyright : (C) 2020 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ // application specific includes #include "smb4ktooltip.h" #include "smb4kbasicnetworkitem.h" #include "smb4kworkgroup.h" #include "smb4khost.h" #include "smb4kshare.h" #include "smb4kglobal.h" // Qt includes #include #include #include #include #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) #include #else #include #endif // KDE includes #include #include #include using namespace Smb4KGlobal; Smb4KToolTip::Smb4KToolTip(QWidget* parent) : KToolTipWidget(parent) { m_contentsWidget = new QWidget(parent); + m_type = Unknown; } Smb4KToolTip::~Smb4KToolTip() { } void Smb4KToolTip::setupToolTip(Smb4KToolTip::Type type, NetworkItemPtr item) { + // + // Copy the type + // + m_type = type; + // // Copy the item // m_item = item; // // Clear the contents widget // qDeleteAll(m_contentsWidget->children()); // // Set the layout // m_mainLayout = new QHBoxLayout(m_contentsWidget); // // Setup the contents widget // - switch (type) + switch (m_type) + { + case NetworkItem: + { + setupNetworkItemContents(); + break; + } + case MountedShare: + { + setupMountedShareContents(); + break; + } + default: + { + break; + } + } +} + + +void Smb4KToolTip::update() +{ + // + // Return if there is no item + // + if (!m_item.isNull() || m_type == Unknown) + { + return; + } + + // + // Update the contents widget + // + switch (m_type) { case NetworkItem: { setupNetworkItemContents(); break; } case MountedShare: { setupMountedShareContents(); break; } default: { break; } } } + void Smb4KToolTip::show(const QPoint& pos, QWindow *transientParent) { QPoint tooltipPos = pos; int testWidth = m_contentsWidget->width() + cursor().pos().x() + layout()->contentsMargins().left() + layout()->contentsMargins().right() + 5; int testHeight = m_contentsWidget->height() + cursor().pos().y() + layout()->contentsMargins().top() + layout()->contentsMargins().bottom() + 5; #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) if (QApplication::desktop()->screenGeometry(pos).width() < testWidth) { tooltipPos.setX(pos.x() - m_contentsWidget->width() - layout()->contentsMargins().left() - layout()->contentsMargins().right() - 5); } else { tooltipPos.setX(pos.x() + 5); } if (QApplication::desktop()->screenGeometry(pos).height() < testHeight) { tooltipPos.setY(pos.y() - m_contentsWidget->height() - layout()->contentsMargins().top() - layout()->contentsMargins().bottom() - 5); } else { tooltipPos.setY(pos.y() + 5); } #else if (QApplication::screenAt(pos)->virtualSize().width() < testWidth) { tooltipPos.setX(pos.x() - m_contentsWidget->width() - layout()->contentsMargins().left() - layout()->contentsMargins().right() - 5); } else { tooltipPos.setX(pos.x() + 5); } if (QApplication::screenAt(pos)->virtualSize().height() < testHeight) { tooltipPos.setY(pos.y() - m_contentsWidget->height() - layout()->contentsMargins().top() - layout()->contentsMargins().bottom() - 5); } else { tooltipPos.setY(pos.y() + 5); } #endif showAt(tooltipPos, m_contentsWidget, transientParent); } void Smb4KToolTip::setupNetworkItemContents() { // // Update the contents, if possible // if (!m_contentsWidget->layout()->isEmpty()) { switch (m_item->type()) { case Workgroup: { WorkgroupPtr workgroup = m_item.staticCast(); QLabel *masterBrowserName = m_contentsWidget->findChild("MasterBrowserName"); if (workgroup->hasMasterBrowserIpAddress()) { masterBrowserName->setText(workgroup->masterBrowserName()+" ("+workgroup->masterBrowserIpAddress()+')'); } else { masterBrowserName->setText(workgroup->masterBrowserName()); } break; } case Host: { HostPtr host = m_item.staticCast(); m_contentsWidget->findChild("CommentString")->setText(!host->comment().isEmpty() ? host->comment() : "-"); m_contentsWidget->findChild("IPAddressString")->setText(host->hasIpAddress() ? host->ipAddress() : "-"); break; } case Share: { SharePtr share = m_item.staticCast(); m_contentsWidget->findChild("CommentString")->setText(!share->comment().isEmpty() ? share->comment() : "-"); m_contentsWidget->findChild("IPAddressString")->setText(share->hasHostIpAddress() ? share->hostIpAddress() : "-"); QLabel *mountedState = m_contentsWidget->findChild("MountedState"); if (!share->isPrinter()) { mountedState->setText(share->isMounted() ? i18n("yes") : i18n("no")); } else { mountedState->setText("-"); } break; } default: { break; } } return; } // // Set up the widget // // Icon QLabel *iconLabel = new QLabel(m_contentsWidget); iconLabel->setPixmap(m_item->icon().pixmap(KIconLoader::SizeEnormous)); m_mainLayout->addWidget(iconLabel, Qt::AlignHCenter); // Header QGridLayout *descriptionLayout = new QGridLayout(); m_mainLayout->addLayout(descriptionLayout); QLabel *caption = new QLabel(m_contentsWidget); caption->setForegroundRole(QPalette::ToolTipText); caption->setBackgroundRole(QPalette::AlternateBase); QFont captionFont = caption->font(); captionFont.setBold(true); caption->setFont(captionFont); descriptionLayout->addWidget(caption, 0, 0, 1, 2, Qt::AlignHCenter); KSeparator *separator = new KSeparator(Qt::Horizontal, m_contentsWidget); separator->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(separator, 1, 0, 1, 2, 0); // Type QLabel *typeCaption = new QLabel(i18n("Type:"), m_contentsWidget); typeCaption->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(typeCaption, 2, 0, Qt::AlignRight); QLabel *typeName = new QLabel(m_contentsWidget); typeName->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(typeName, 2, 1, 0); switch (m_item->type()) { case Workgroup: { WorkgroupPtr workgroup = m_item.staticCast(); caption->setText(workgroup->workgroupName()); typeName->setText(i18n("Workgroup")); // Master browser QLabel *masterBrowserLabel = new QLabel(i18n("Master Browser:"), m_contentsWidget); masterBrowserLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(masterBrowserLabel, 3, 0, Qt::AlignRight); QLabel *masterBrowserName = new QLabel(m_contentsWidget); masterBrowserName->setObjectName("MasterBrowserName"); masterBrowserName->setForegroundRole(QPalette::ToolTipText); if (workgroup->hasMasterBrowserIpAddress()) { masterBrowserName->setText(QString("%1 (%2)").arg(workgroup->masterBrowserName()).arg(workgroup->masterBrowserIpAddress())); } else { masterBrowserName->setText(workgroup->masterBrowserName()); } descriptionLayout->addWidget(masterBrowserName, 3, 1, 0); descriptionLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum), 4, 0, 2, 1, 0); break; } case Host: { HostPtr host = m_item.staticCast(); caption->setText(host->hostName()); typeName->setText(i18n("Host")); // Comment QLabel *commentLabel = new QLabel(i18n("Comment:"), m_contentsWidget); commentLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(commentLabel, 3, 0, Qt::AlignRight); QLabel *commentString = new QLabel(!host->comment().isEmpty() ? host->comment() : "-", m_contentsWidget); commentString->setObjectName("CommentString"); commentString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(commentString, 3, 1, 0); // IP address QLabel *ipAddressLabel = new QLabel(i18n("IP Address:"), m_contentsWidget); ipAddressLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(ipAddressLabel, 4, 0, Qt::AlignRight); QLabel *ipAddress = new QLabel(host->hasIpAddress() ? host->ipAddress() : "-", m_contentsWidget); ipAddress->setObjectName("IPAddressString"); ipAddress->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(ipAddress, 4, 1, 0); // Workgroup QLabel *workgroupLabel = new QLabel(i18n("Workgroup:"), m_contentsWidget); workgroupLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(workgroupLabel, 5, 0, Qt::AlignRight); QLabel *workgroupName = new QLabel(host->workgroupName(), m_contentsWidget); workgroupName->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(workgroupName, 5, 1, 0); descriptionLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum), 6, 0, 2, 1, 0); break; } case Share: { SharePtr share = m_item.staticCast(); caption->setText(share->shareName()); typeName->setText(i18n("Share (%1)", share->shareTypeString())); // Comment QLabel *commentLabel = new QLabel(i18n("Comment:"), m_contentsWidget); commentLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(commentLabel, 3, 0, Qt::AlignRight); QLabel *commentString = new QLabel(!share->comment().isEmpty() ? share->comment() : "-", m_contentsWidget); commentString->setObjectName("CommentString"); commentString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(commentString, 3, 1, 0); // State (mounted/not mounted) QLabel *mountedLabel = new QLabel(i18n("Mounted:"), m_contentsWidget); mountedLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(mountedLabel, 4, 0, Qt::AlignRight); QLabel *mountedState = nullptr; if (!share->isPrinter()) { mountedState = new QLabel(share->isMounted() ? i18n("yes") : i18n("no"), m_contentsWidget); } else { mountedState = new QLabel("-", m_contentsWidget); } mountedState->setObjectName("MountedState"); mountedState->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(mountedState, 4, 1, 0); // Host QLabel *hostLabel = new QLabel(i18n("Host:"), m_contentsWidget); hostLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(hostLabel, 5, 0, Qt::AlignRight); QLabel *hostName = new QLabel(share->hostName(), m_contentsWidget); hostName->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(hostName, 5, 1, 0); // IP address QLabel *ipAddressLabel = new QLabel(i18n("IP Address:"), m_contentsWidget); ipAddressLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(ipAddressLabel, 6, 0, Qt::AlignRight); QLabel *ipAddressString = new QLabel(share->hasHostIpAddress() ? share->hostIpAddress() : "-", m_contentsWidget); ipAddressString->setObjectName("IPAddressString"); ipAddressString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(ipAddressString, 6, 1, 0); // Location QLabel *locationLabel = new QLabel(i18n("Location:"), m_contentsWidget); locationLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(locationLabel, 7, 0, Qt::AlignRight); QLabel *locationString = new QLabel(share->displayString(), m_contentsWidget); locationString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(locationString, 7, 1, 0); descriptionLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum), 8, 0, 2, 1, 0); break; } default: { break; } } m_contentsWidget->adjustSize(); m_contentsWidget->ensurePolished(); } void Smb4KToolTip::setupMountedShareContents() { // // Cast the item // SharePtr share = m_item.staticCast(); // // Update the contents, if possible // if (!m_contentsWidget->layout()->isEmpty()) { m_contentsWidget->findChild("IconLabel")->setPixmap(share->icon().pixmap(KIconLoader::SizeEnormous)); m_contentsWidget->findChild("LoginString")->setText(!share->login().isEmpty() ? share->login() : i18n("unknown")); QString sizeIndication; if (share->totalDiskSpace() != 0 && share->freeDiskSpace() != 0) { sizeIndication = i18n("%1 free of %2 (%3 used)", share->freeDiskSpaceString(), share->totalDiskSpaceString(), share->diskUsageString()); } else { sizeIndication = i18n("unknown"); } m_contentsWidget->findChild("SizeString")->setText(sizeIndication); return; } // // Set up the widget // // Icon QLabel *iconLabel = new QLabel(m_contentsWidget); iconLabel->setPixmap(share->icon().pixmap(KIconLoader::SizeEnormous)); iconLabel->setObjectName("IconLabel"); m_mainLayout->addWidget(iconLabel, Qt::AlignHCenter); // Header QGridLayout *descriptionLayout = new QGridLayout(); m_mainLayout->addLayout(descriptionLayout); QLabel *caption = new QLabel(share->shareName(), m_contentsWidget); caption->setForegroundRole(QPalette::ToolTipText); caption->setBackgroundRole(QPalette::AlternateBase); QFont captionFont = caption->font(); captionFont.setBold(true); caption->setFont(captionFont); descriptionLayout->addWidget(caption, 0, 0, 1, 2, Qt::AlignHCenter); KSeparator *separator = new KSeparator(Qt::Horizontal, m_contentsWidget); separator->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(separator, 1, 0, 1, 2, 0); // Location QLabel *locationLabel = new QLabel(i18n("Location:"), m_contentsWidget); locationLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(locationLabel, 2, 0, Qt::AlignRight); QLabel *locationString = new QLabel(share->displayString(), m_contentsWidget); locationString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(locationString, 2, 1, 0); // Mount point QLabel *mountpointLabel = new QLabel(i18n("Mountpoint:"), m_contentsWidget); mountpointLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(mountpointLabel, 3, 0, Qt::AlignRight); QLabel *mountpointString = new QLabel(share->path(), m_contentsWidget); mountpointString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(mountpointString, 3, 1, 0); // Login QLabel *loginLabel = new QLabel(i18n("Login:"), m_contentsWidget); loginLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(loginLabel, 4, 0, Qt::AlignRight); QLabel *loginString = new QLabel(!share->login().isEmpty() ? share->login() : i18n("unknown"), m_contentsWidget); loginString->setObjectName("LoginString"); loginString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(loginString, 4, 1, 0); // Owner QLabel *ownerLabel = new QLabel(i18n("Owner:"), m_contentsWidget); ownerLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(ownerLabel, 5, 0, Qt::AlignRight); QString owner(!share->user().loginName().isEmpty() ? share->user().loginName() : i18n("unknown")); QString group(!share->group().name().isEmpty() ? share->group().name() : i18n("unknown")); QLabel *ownerString = new QLabel(QString("%1 - %2").arg(owner, group),m_contentsWidget); ownerString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(ownerString, 5, 1, 0); // File system QLabel *fileSystemLabel = new QLabel(i18n("File system:"), m_contentsWidget); fileSystemLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(fileSystemLabel, 6, 0, Qt::AlignRight); QLabel *fileSystemString = new QLabel(share->fileSystemString(), m_contentsWidget); fileSystemString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(fileSystemString, 6, 1, 0); // Size QLabel *sizeLabel = new QLabel(i18n("Size:"), m_contentsWidget); sizeLabel->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(sizeLabel, 7, 0, Qt::AlignRight); QString sizeIndication; if (share->totalDiskSpace() != 0 && share->freeDiskSpace() != 0) { sizeIndication = i18n("%1 free of %2 (%3 used)", share->freeDiskSpaceString(), share->totalDiskSpaceString(), share->diskUsageString()); } else { sizeIndication = i18n("unknown"); } QLabel *sizeString = new QLabel(sizeIndication, m_contentsWidget); sizeString->setObjectName("SizeString"); sizeString->setForegroundRole(QPalette::ToolTipText); descriptionLayout->addWidget(sizeString, 7, 1, 0); descriptionLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum), 8, 0, 2, 1, 0); m_contentsWidget->adjustSize(); m_contentsWidget->ensurePolished(); } diff --git a/smb4k/smb4ktooltip.h b/smb4k/smb4ktooltip.h index 4eaec90..b63f30b 100644 --- a/smb4k/smb4ktooltip.h +++ b/smb4k/smb4ktooltip.h @@ -1,107 +1,118 @@ /*************************************************************************** smb4ktooltip - Provides tooltips for Smb4K ------------------- begin : Mi Mai 2020 copyright : (C) 2020 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ #ifndef SMB4KTOOLTIP_H #define SMB4KTOOLTIP_H // application specific includes #include // Qt includes #include #include #include // KDE includes #include // Forward declaration class Smb4KBasicNetworkItem; class Smb4KToolTip : public KToolTipWidget { Q_OBJECT public: /** * The constructor */ Smb4KToolTip(QWidget *parent = nullptr); /** * The destructor */ ~Smb4KToolTip(); /** * This enumeration determines the kind of tooltip * this is to be shown. * * @enum NetworkItem Tooltip reflecting a remote network item * @enum MountedShare Tooltip reflecting a mounted share */ enum Type { NetworkItem, - MountedShare }; + MountedShare, + Unknown }; /** * Set up the tooltip. */ void setupToolTip(Type type, NetworkItemPtr item); /** * Show the tooltip */ void show(const QPoint &pos, QWindow *transientParent); + /** + * Update the tooltip + */ + void update(); + private: /** * Setup the contents widget for a remote network item */ void setupNetworkItemContents(); /** * Setup the contents widget for a mounted share */ void setupMountedShareContents(); /** * The network item */ NetworkItemPtr m_item; + /** + * The type + */ + Type m_type; + /** * The contents widget for the tooltip */ QWidget *m_contentsWidget; /** * The main layout */ QHBoxLayout *m_mainLayout; }; #endif