File indexing completed on 2023-12-03 05:04:26

0001 /*
0002     smb4knetworkbrowser  -  The network browser widget of Smb4K.
0003 
0004     SPDX-FileCopyrightText: 2007-2022 Alexander Reinholdt <alexander.reinholdt@kdemail.net>
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 // application specific includes
0009 #include "smb4knetworkbrowser.h"
0010 #include "core/smb4kglobal.h"
0011 #include "core/smb4ksettings.h"
0012 #include "core/smb4kshare.h"
0013 #include "smb4knetworkbrowseritem.h"
0014 #include "smb4ktooltip.h"
0015 
0016 // Qt includes
0017 #include <QApplication>
0018 #include <QHeaderView>
0019 #include <QMouseEvent>
0020 #include <QTimer>
0021 
0022 #include <QLayout>
0023 
0024 // KDE includes
0025 #include <KLocalizedString>
0026 
0027 using namespace Smb4KGlobal;
0028 
0029 Smb4KNetworkBrowser::Smb4KNetworkBrowser(QWidget *parent)
0030     : QTreeWidget(parent)
0031 {
0032     setRootIsDecorated(true);
0033     setAllColumnsShowFocus(false);
0034     setMouseTracking(true);
0035     setSelectionMode(ExtendedSelection);
0036 
0037     setContextMenuPolicy(Qt::CustomContextMenu);
0038 
0039     m_toolTip = new Smb4KToolTip(this);
0040 
0041     QStringList header_labels;
0042     header_labels.append(i18n("Network"));
0043     header_labels.append(i18n("Type"));
0044     header_labels.append(i18n("IP Address"));
0045     header_labels.append(i18n("Comment"));
0046     setHeaderLabels(header_labels);
0047 
0048     header()->setSectionResizeMode(QHeaderView::ResizeToContents);
0049 
0050     //
0051     // Connections
0052     //
0053     connect(this, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(slotItemActivated(QTreeWidgetItem *, int)));
0054     connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged()));
0055 }
0056 
0057 Smb4KNetworkBrowser::~Smb4KNetworkBrowser()
0058 {
0059 }
0060 
0061 Smb4KToolTip *Smb4KNetworkBrowser::toolTip()
0062 {
0063     return m_toolTip;
0064 }
0065 
0066 bool Smb4KNetworkBrowser::event(QEvent *e)
0067 {
0068     switch (e->type()) {
0069     case QEvent::ToolTip: {
0070         //
0071         // Intercept the tool tip event and show our own tool tip
0072         //
0073         QPoint pos = viewport()->mapFromGlobal(cursor().pos());
0074         Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(itemAt(pos));
0075 
0076         if (item) {
0077             if (Smb4KSettings::showNetworkItemToolTip()) {
0078                 int ind = 0;
0079 
0080                 switch (item->type()) {
0081                 case Host: {
0082                     ind = 2;
0083                     break;
0084                 }
0085                 case Share: {
0086                     ind = 3;
0087                     break;
0088                 }
0089                 default: {
0090                     ind = 1;
0091                     break;
0092                 }
0093                 }
0094 
0095                 //
0096                 // Show the tooltip
0097                 //
0098                 if (pos.x() > ind * indentation()) {
0099                     //
0100                     // Set up the tooltip
0101                     //
0102                     m_toolTip->setupToolTip(Smb4KToolTip::NetworkItem, item->networkItem());
0103 
0104                     //
0105                     // Show the tooltip
0106                     //
0107                     m_toolTip->show(cursor().pos(), nativeParentWidget()->windowHandle());
0108                 }
0109             }
0110         }
0111 
0112         break;
0113     }
0114     default: {
0115         break;
0116     }
0117     }
0118 
0119     return QTreeWidget::event(e);
0120 }
0121 
0122 void Smb4KNetworkBrowser::mousePressEvent(QMouseEvent *e)
0123 {
0124     //
0125     // Hide the tooltip
0126     //
0127     if (m_toolTip->isVisible()) {
0128         m_toolTip->hide();
0129     }
0130 
0131     //
0132     // Get the item that is under the mouse. If there is no
0133     // item, unselect the current item.
0134     //
0135     QTreeWidgetItem *item = itemAt(e->pos());
0136 
0137     if (!item && currentItem()) {
0138         currentItem()->setSelected(false);
0139         setCurrentItem(nullptr);
0140     }
0141 
0142     QTreeWidget::mousePressEvent(e);
0143 }
0144 
0145 void Smb4KNetworkBrowser::mouseMoveEvent(QMouseEvent *e)
0146 {
0147     //
0148     // Hide the tooltip
0149     //
0150     if (m_toolTip->isVisible()) {
0151         m_toolTip->hide();
0152     }
0153 
0154     QTreeWidget::mouseMoveEvent(e);
0155 }
0156 
0157 /////////////////////////////////////////////////////////////////////////////
0158 // SLOT IMPLEMENTATIONS
0159 /////////////////////////////////////////////////////////////////////////////
0160 
0161 void Smb4KNetworkBrowser::slotItemActivated(QTreeWidgetItem *item, int /*column*/)
0162 {
0163     // Only do something if there are no keyboard modifiers pressed
0164     // and there is only one item selected.
0165     if (QApplication::keyboardModifiers() == Qt::NoModifier && selectedItems().size() == 1) {
0166         if (item) {
0167             switch (item->type()) {
0168             case Workgroup:
0169             case Host: {
0170                 if (!item->isExpanded()) {
0171                     expandItem(item);
0172                 } else {
0173                     collapseItem(item);
0174                 }
0175 
0176                 break;
0177             }
0178             default: {
0179                 break;
0180             }
0181             }
0182         }
0183     }
0184 }
0185 
0186 void Smb4KNetworkBrowser::slotItemSelectionChanged()
0187 {
0188     if (selectedItems().size() > 1) {
0189         // If multiple items are selected, only allow shares
0190         // to stay selected.
0191         for (int i = 0; i < selectedItems().size(); ++i) {
0192             Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItems()[i]);
0193 
0194             if (item) {
0195                 switch (item->networkItem()->type()) {
0196                 case Workgroup:
0197                 case Host: {
0198                     item->setSelected(false);
0199                     break;
0200                 }
0201                 case Share: {
0202                     if (item->shareItem()->isPrinter()) {
0203                         item->setSelected(false);
0204                     }
0205                     break;
0206                 }
0207                 default: {
0208                     break;
0209                 }
0210                 }
0211             }
0212         }
0213     }
0214 }