File indexing completed on 2024-04-14 15:05:36

0001 /***************************************************************************
0002     smb4knetworkbrowser  -  The network browser widget of Smb4K.
0003                              -------------------
0004     begin                : Mo Jan 8 2007
0005     copyright            : (C) 2007-2019 by Alexander Reinholdt
0006     email                : alexander.reinholdt@kdemail.net
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *   This program is free software; you can redistribute it and/or modify  *
0011  *   it under the terms of the GNU General Public License as published by  *
0012  *   the Free Software Foundation; either version 2 of the License, or     *
0013  *   (at your option) any later version.                                   *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful, but   *
0016  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
0018  *   General Public License for more details.                              *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program; if not, write to the                         *
0022  *   Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston,*
0023  *   MA 02110-1335, USA                                                    *
0024  ***************************************************************************/
0025 
0026 #ifdef HAVE_CONFIG_H
0027 #include <config.h>
0028 #endif
0029 
0030 // application specific includes
0031 #include "smb4knetworkbrowser.h"
0032 #include "smb4knetworkbrowseritem.h"
0033 #include "smb4ktooltip.h"
0034 #include "core/smb4ksettings.h"
0035 #include "core/smb4kglobal.h"
0036 #include "core/smb4kshare.h"
0037 
0038 // Qt includes
0039 #include <QTimer>
0040 #include <QMouseEvent>
0041 #include <QFocusEvent>
0042 #include <QWheelEvent>
0043 #include <QCursor>
0044 #include <QHelpEvent>
0045 #include <QHeaderView>
0046 #include <QDesktopWidget>
0047 #include <QApplication>
0048 
0049 // KDE includes
0050 #include <KI18n/KLocalizedString>
0051 
0052 using namespace Smb4KGlobal;
0053 
0054 Smb4KNetworkBrowser::Smb4KNetworkBrowser(QWidget *parent)
0055 : QTreeWidget(parent)
0056 {
0057   setRootIsDecorated(true);
0058   setAllColumnsShowFocus(false);
0059   setMouseTracking(true);
0060   setSelectionMode(ExtendedSelection);
0061   
0062   setContextMenuPolicy(Qt::CustomContextMenu);
0063 
0064   m_tooltip_item = 0;
0065   m_mouse_inside = false;
0066 
0067   QStringList header_labels;
0068   header_labels.append(i18n("Network"));
0069   header_labels.append(i18n("Type"));
0070   header_labels.append(i18n("IP Address"));
0071   header_labels.append(i18n("Comment"));
0072   setHeaderLabels(header_labels);
0073 
0074   header()->setSectionResizeMode(QHeaderView::ResizeToContents);
0075 
0076   // 
0077   // Connections
0078   // 
0079   connect(this, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(slotItemActivated(QTreeWidgetItem*,int)));
0080   connect(this, SIGNAL(itemEntered(QTreeWidgetItem*,int)), this, SLOT(slotItemEntered(QTreeWidgetItem*,int)));
0081   connect(this, SIGNAL(viewportEntered()), this, SLOT(slotViewportEntered()));
0082   connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged()));
0083 }
0084 
0085 
0086 Smb4KNetworkBrowser::~Smb4KNetworkBrowser()
0087 {
0088 }
0089 
0090 
0091 bool Smb4KNetworkBrowser::event(QEvent *e)
0092 {
0093   switch (e->type())
0094   {
0095     case QEvent::ToolTip:
0096     {
0097       // Intercept the tool tip event and show our own tool tip.
0098       QPoint pos = viewport()->mapFromGlobal(cursor().pos());
0099       Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(itemAt(pos));
0100       
0101       if (item)
0102       {
0103         if (Smb4KSettings::showNetworkItemToolTip())
0104         {
0105           int ind = 0;
0106 
0107           switch (item->type())
0108           {
0109             case Host:
0110             {
0111               ind = 2;
0112               break;
0113             }
0114             case Share:
0115             {
0116               ind = 3;
0117               break;
0118             }
0119             default:
0120             {
0121               ind = 1;
0122               break;
0123             }
0124           }
0125           
0126           // Check that the tooltip is not over the root decoration.
0127           // If it is, hide it.
0128           if (pos.x() <= ind * indentation())
0129           {
0130             if (m_tooltip_item)
0131             {
0132               emit aboutToHideToolTip(m_tooltip_item);
0133               m_tooltip_item->tooltip()->hide();
0134               m_tooltip_item = 0;
0135             }
0136           }
0137           else
0138           {
0139             m_tooltip_item = item;
0140             emit aboutToShowToolTip(m_tooltip_item);
0141             m_tooltip_item->tooltip()->show(cursor().pos());
0142           }
0143         }
0144         else
0145         {
0146           if (m_tooltip_item)
0147           {
0148             emit aboutToHideToolTip(m_tooltip_item);
0149             m_tooltip_item->tooltip()->hide();
0150             m_tooltip_item = 0;
0151           }
0152         }
0153       }
0154       else
0155       {
0156         if (m_tooltip_item)
0157         {
0158           emit aboutToHideToolTip(m_tooltip_item);
0159           m_tooltip_item->tooltip()->hide();
0160           m_tooltip_item = 0;
0161         }
0162       }
0163       
0164       break;
0165     }
0166     default:
0167     {
0168       break;
0169     }
0170   }
0171   
0172   return QTreeWidget::event(e);
0173 }
0174 
0175 
0176 void Smb4KNetworkBrowser::mouseMoveEvent(QMouseEvent *e)
0177 {
0178   // Find the item over which the user moved the mouse:
0179   Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(itemAt(e->pos()));
0180 
0181   if (item)
0182   {
0183     emit itemEntered(item, columnAt(e->pos().x()));
0184     
0185     // Hide tool tip if the items diverge.
0186     if (m_tooltip_item && m_tooltip_item->tooltip()->networkItem() != item->networkItem())
0187     {
0188       emit aboutToHideToolTip(m_tooltip_item);
0189       m_tooltip_item->tooltip()->hide();
0190       m_tooltip_item = 0;
0191     }
0192   }
0193   else
0194   {
0195     // Hide the tool tip
0196     if (m_tooltip_item)
0197     {
0198       emit aboutToHideToolTip(m_tooltip_item);
0199       m_tooltip_item->tooltip()->hide();
0200       m_tooltip_item = 0;
0201     }
0202   }
0203 
0204   QTreeWidget::mouseMoveEvent(e);
0205 }
0206 
0207 
0208 void Smb4KNetworkBrowser::leaveEvent(QEvent *e)
0209 {
0210   if (m_tooltip_item)
0211   {
0212     emit aboutToHideToolTip(m_tooltip_item);
0213     m_tooltip_item->tooltip()->hide();
0214     m_tooltip_item = 0;
0215   }
0216   
0217   m_mouse_inside = false;
0218 
0219   QTreeWidget::leaveEvent(e);
0220 }
0221 
0222 
0223 void Smb4KNetworkBrowser::enterEvent(QEvent *e)
0224 {
0225   m_mouse_inside = true;
0226 
0227   QTreeWidget::enterEvent(e);
0228 }
0229 
0230 
0231 void Smb4KNetworkBrowser::mousePressEvent(QMouseEvent *e)
0232 {
0233   // Hide the current tool tip so that it is not in the way.
0234   if (m_tooltip_item)
0235   {
0236     emit aboutToHideToolTip(m_tooltip_item);
0237     m_tooltip_item->tooltip()->hide();
0238     m_tooltip_item = 0;
0239   }
0240 
0241   // Get the item that is under the mouse. If there is no
0242   // item, unselect the current item.
0243   QTreeWidgetItem *item = itemAt(e->pos());
0244 
0245   if (!item && currentItem())
0246   {
0247     currentItem()->setSelected(false);
0248     setCurrentItem(0);
0249     emit itemPressed(currentItem(), -1);
0250   }
0251 
0252   QTreeWidget::mousePressEvent(e);
0253 }
0254 
0255 
0256 void Smb4KNetworkBrowser::focusOutEvent(QFocusEvent *e)
0257 {
0258   QTreeWidget::focusOutEvent(e);
0259 }
0260 
0261 
0262 void Smb4KNetworkBrowser::wheelEvent(QWheelEvent *e)
0263 {
0264   if (m_tooltip_item)
0265   {
0266     emit aboutToHideToolTip(m_tooltip_item);
0267     m_tooltip_item->tooltip()->hide();
0268     m_tooltip_item = 0;
0269   }
0270   
0271   QTreeWidget::wheelEvent(e);
0272 }
0273 
0274 
0275 /////////////////////////////////////////////////////////////////////////////
0276 // SLOT IMPLEMENTATIONS
0277 /////////////////////////////////////////////////////////////////////////////
0278 
0279 void Smb4KNetworkBrowser::slotItemEntered(QTreeWidgetItem *item, int /*column*/)
0280 {
0281   Smb4KNetworkBrowserItem *browser_item = static_cast<Smb4KNetworkBrowserItem *>(item);
0282   
0283   if (m_tooltip_item && m_tooltip_item != browser_item)
0284   {
0285     emit aboutToHideToolTip(m_tooltip_item);
0286     m_tooltip_item->tooltip()->hide();
0287     m_tooltip_item = 0;
0288   }
0289 }
0290 
0291 
0292 void Smb4KNetworkBrowser::slotViewportEntered()
0293 {
0294   if (m_tooltip_item)
0295   {
0296     emit aboutToHideToolTip(m_tooltip_item);
0297     m_tooltip_item->tooltip()->hide();
0298     m_tooltip_item = 0;
0299   }
0300 }
0301 
0302 
0303 void Smb4KNetworkBrowser::slotItemActivated(QTreeWidgetItem *item, int /*column*/)
0304 {
0305   if (m_tooltip_item)
0306   {
0307     emit aboutToHideToolTip(m_tooltip_item);
0308     m_tooltip_item->tooltip()->hide();
0309     m_tooltip_item = 0;
0310   }
0311 
0312   // Only do something if there are no keyboard modifiers pressed
0313   // and there is only one item selected.
0314   if (QApplication::keyboardModifiers() == Qt::NoModifier && selectedItems().size() == 1)
0315   {
0316     if (item)
0317     {
0318       switch (item->type())
0319       {
0320         case Workgroup:
0321         case Host:
0322         {
0323           if (!item->isExpanded())
0324           {
0325             expandItem(item);
0326           }
0327           else
0328           {
0329             collapseItem(item);
0330           }
0331 
0332           break;
0333         }
0334         default:
0335         {
0336           break;
0337         }
0338       }
0339     }
0340   }
0341 }
0342 
0343 
0344 void Smb4KNetworkBrowser::slotItemSelectionChanged()
0345 {
0346   if (selectedItems().size() > 1)
0347   {
0348     // If multiple items are selected, only allow shares
0349     // to stay selected.
0350     for (int i = 0; i < selectedItems().size(); ++i)
0351     {
0352       Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItems()[i]);
0353       
0354       if (item)
0355       {
0356         switch (item->networkItem()->type())
0357         {
0358           case Workgroup:
0359           case Host:
0360           {
0361             item->setSelected(false);
0362             break;
0363           }
0364           case Share:
0365           {
0366             if (item->shareItem()->isPrinter())
0367             {
0368               item->setSelected(false);
0369             }
0370             break;
0371           }
0372           default:
0373           {
0374             break;
0375           }
0376         }
0377       }
0378     }
0379   }
0380 }
0381