File indexing completed on 2024-07-14 15:13:56

0001 /***************************************************************************
0002     This is the shares view of Smb4K.
0003                              -------------------
0004     begin                : Mo Dez 4 2006
0005     copyright            : (C) 2006-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 "smb4ksharesview.h"
0032 #include "smb4ksharesviewitem.h"
0033 #include "smb4ktooltip.h"
0034 #include "core/smb4kshare.h"
0035 #include "core/smb4ksettings.h"
0036 
0037 // Qt includes
0038 #include <QMouseEvent>
0039 #include <QWheelEvent>
0040 #include <QDrag>
0041 #include <QDesktopWidget>
0042 #include <QApplication>
0043 
0044 // KDE includes
0045 #include <KIconThemes/KIconLoader>
0046 
0047 
0048 Smb4KSharesView::Smb4KSharesView(QWidget *parent)
0049 : QListWidget(parent)
0050 {
0051   setMouseTracking(true);
0052   setSelectionMode(ExtendedSelection);
0053   setResizeMode(Adjust);
0054   setSortingEnabled(true);
0055   setWordWrap(true);
0056   setAcceptDrops(true);
0057   setDragEnabled(true);
0058   setDropIndicatorShown(true);
0059   setUniformItemSizes(true);
0060   setWrapping(true);
0061   
0062   setContextMenuPolicy(Qt::CustomContextMenu);
0063 
0064   m_tooltipItem = 0;
0065   m_mouseInside = false;
0066 
0067   // 
0068   // Connections
0069   // 
0070   connect(this, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(slotItemEntered(QListWidgetItem*)));
0071   connect(this, SIGNAL(viewportEntered()), this, SLOT(slotViewportEntered()));
0072 }
0073 
0074 
0075 Smb4KSharesView::~Smb4KSharesView()
0076 {
0077 }
0078 
0079 
0080 void Smb4KSharesView::setViewMode(QListView::ViewMode mode, int iconSize)
0081 {
0082   //
0083   // Set the view mode
0084   //
0085   QListWidget::setViewMode(mode);
0086   
0087   //
0088   // Make adjustments
0089   //
0090   switch(mode)
0091   {
0092     case IconMode:
0093     {
0094       setUniformItemSizes(true);
0095       setIconSize(QSize(iconSize, iconSize));
0096       setSpacing(5);
0097       break;
0098     }
0099     case ListMode:
0100     {
0101       setUniformItemSizes(false);
0102       setIconSize(QSize(iconSize, iconSize));
0103       setSpacing(0);
0104       break;
0105     }
0106     default:
0107     {
0108       break;
0109     }
0110   }
0111   
0112   //
0113   // Align the items 
0114   //
0115   for (int i = 0; i < count(); ++i)
0116   {
0117     Smb4KSharesViewItem *viewItem = static_cast<Smb4KSharesViewItem *>(item(i));
0118     viewItem->setItemAlignment(mode);
0119   }
0120 }
0121 
0122 
0123 bool Smb4KSharesView::event(QEvent *e)
0124 {
0125   switch (e->type())
0126   {
0127     case QEvent::ToolTip:
0128     {
0129       // Intercept the tool tip event and show our own tool tip.
0130       QPoint pos = viewport()->mapFromGlobal(cursor().pos());
0131       Smb4KSharesViewItem *item = static_cast<Smb4KSharesViewItem *>(itemAt(pos));
0132       
0133       if (item)
0134       {
0135         if (Smb4KSettings::showShareToolTip())
0136         {
0137           m_tooltipItem = item;
0138           emit aboutToShowToolTip(m_tooltipItem);
0139           m_tooltipItem->tooltip()->show(cursor().pos());
0140         }
0141         else
0142         {
0143           if (m_tooltipItem)
0144           {
0145             emit aboutToHideToolTip(m_tooltipItem);
0146             m_tooltipItem->tooltip()->hide();
0147             m_tooltipItem = 0;
0148           }
0149         }
0150       }
0151       else
0152       {
0153         if (m_tooltipItem)
0154         {
0155           emit aboutToHideToolTip(m_tooltipItem);
0156           m_tooltipItem->tooltip()->hide();
0157           m_tooltipItem = 0;
0158         }
0159       }
0160 
0161       break;
0162     }
0163     default:
0164     {
0165       break;
0166     }
0167   }
0168 
0169   return QListWidget::event(e);
0170 }
0171 
0172 
0173 void Smb4KSharesView::leaveEvent(QEvent *e)
0174 {
0175   if (m_tooltipItem)
0176   {
0177     emit aboutToHideToolTip(m_tooltipItem);
0178     m_tooltipItem->tooltip()->hide();
0179     m_tooltipItem = 0;
0180   }
0181   
0182   m_mouseInside = false;
0183   QListWidget::leaveEvent(e);
0184 }
0185 
0186 
0187 void Smb4KSharesView::enterEvent(QEvent *e)
0188 {
0189   m_mouseInside = true;
0190   QListWidget::enterEvent(e);
0191 }
0192 
0193 
0194 void Smb4KSharesView::mousePressEvent(QMouseEvent *e)
0195 {
0196   // Hide the current tool tip so that it is not in the way.
0197   if (m_tooltipItem)
0198   {
0199     emit aboutToHideToolTip(m_tooltipItem);
0200     m_tooltipItem->tooltip()->hide();
0201     m_tooltipItem = 0;
0202   }
0203 
0204   // Get the item that is under the mouse. If there is no
0205   // item, unselect the current item.
0206   QListWidgetItem *item = itemAt(e->pos());
0207 
0208   if (!item && !selectedItems().isEmpty())
0209   {
0210     clearSelection();
0211     setCurrentItem(0);
0212     emit itemPressed(currentItem());
0213   }
0214 
0215   QListWidget::mousePressEvent(e);
0216 }
0217 
0218 
0219 void Smb4KSharesView::focusOutEvent(QFocusEvent *e)
0220 {
0221   QListWidget::focusOutEvent(e);
0222 }
0223 
0224 
0225 void Smb4KSharesView::wheelEvent(QWheelEvent *e)
0226 {
0227   if (m_tooltipItem)
0228   {
0229     emit aboutToHideToolTip(m_tooltipItem);
0230     m_tooltipItem->tooltip()->hide();
0231     m_tooltipItem = 0;
0232   }
0233   
0234   QListWidget::wheelEvent(e);
0235 }
0236 
0237 
0238 void Smb4KSharesView::dragEnterEvent(QDragEnterEvent *e)
0239 {
0240   if (e->mimeData()->hasUrls())
0241   {
0242     e->accept();
0243   }
0244   else
0245   {
0246     e->ignore();
0247   }
0248 }
0249 
0250 
0251 void Smb4KSharesView::dragMoveEvent(QDragMoveEvent *e)
0252 {
0253   // Let the QAbstractItemView do the highlighting of the item, etc.
0254   QAbstractItemView::dragMoveEvent(e);
0255 
0256   // Now we do our thing.
0257   Smb4KSharesViewItem *item = static_cast<Smb4KSharesViewItem *>(itemAt(e->pos()));
0258 
0259   if (item && !item->shareItem()->isInaccessible() && (item->flags() & Qt::ItemIsDropEnabled) && (e->proposedAction() & (Qt::CopyAction | Qt::MoveAction)))
0260   {
0261     QUrl url = QUrl::fromLocalFile(item->shareItem()->path());
0262 
0263     if (e->source() == this && e->mimeData()->urls().first() == url)
0264     {
0265       e->ignore();
0266     }
0267     else
0268     {
0269       e->accept();
0270     }
0271   }
0272   else
0273   {
0274     e->ignore();
0275   }
0276 }
0277 
0278 
0279 void Smb4KSharesView::dropEvent(QDropEvent *e)
0280 {
0281   // Get the item and process the drop event
0282   Smb4KSharesViewItem *item = static_cast<Smb4KSharesViewItem *>(itemAt(e->pos()));
0283 
0284   if (item && !item->shareItem()->isInaccessible() && (e->proposedAction() & (Qt::CopyAction|Qt::MoveAction)))
0285   {
0286     QUrl url = QUrl::fromLocalFile(item->shareItem()->path());
0287 
0288     if (e->source() == this && e->mimeData()->urls().first() == url)
0289     {
0290       e->ignore();
0291     }
0292     else
0293     {
0294       e->acceptProposedAction();
0295       emit acceptedDropEvent(item, e);
0296       e->accept();
0297     }
0298   }
0299   else
0300   {
0301     e->ignore();
0302   }
0303 }
0304 
0305 
0306 Qt::DropActions Smb4KSharesView::supportedDropActions() const
0307 {
0308   // Only allow copying and linking.
0309   return (Qt::CopyAction|Qt::LinkAction);
0310 }
0311 
0312 
0313 QMimeData *Smb4KSharesView::mimeData(const QList<QListWidgetItem *> list) const
0314 {
0315   QMimeData *mimeData = new QMimeData();
0316   QList<QUrl> urls;
0317 
0318   for (int i = 0; i < list.count(); ++i)
0319   {
0320     Smb4KSharesViewItem *item = static_cast<Smb4KSharesViewItem *>(list.at(i));
0321     urls << QUrl::fromLocalFile(item->shareItem()->path());
0322   }
0323 
0324   mimeData->setUrls(urls);
0325 
0326   return mimeData;
0327 }
0328 
0329 
0330 void Smb4KSharesView::startDrag(Qt::DropActions supported)
0331 {
0332   if (m_tooltipItem)
0333   {
0334     emit aboutToHideToolTip(m_tooltipItem);
0335     m_tooltipItem->tooltip()->hide();
0336     m_tooltipItem = 0;
0337   }
0338 
0339   QList<QListWidgetItem *> list = selectedItems();
0340 
0341   if (!list.isEmpty())
0342   {
0343     QMimeData *data = mimeData(list);
0344 
0345     if (!data)
0346     {
0347       return;
0348     }
0349 
0350     QDrag *drag = new QDrag(this);
0351 
0352     QPixmap pixmap;
0353 
0354     if (list.count() == 1)
0355     {
0356       Smb4KSharesViewItem *item = static_cast<Smb4KSharesViewItem *>(list.first());
0357       pixmap = item->icon().pixmap(KIconLoader::SizeMedium);
0358     }
0359     else
0360     {
0361       pixmap = KDE::icon("document-multiple").pixmap(KIconLoader::SizeMedium);
0362     }
0363 
0364     drag->setPixmap(pixmap);
0365     drag->setMimeData(data);
0366 
0367     drag->exec(supported, Qt::IgnoreAction);
0368   }
0369 }
0370 
0371 
0372 /////////////////////////////////////////////////////////////////////////////
0373 // SLOT IMPLEMENTATIONS
0374 /////////////////////////////////////////////////////////////////////////////
0375 
0376 void Smb4KSharesView::slotItemEntered(QListWidgetItem *item)
0377 {
0378   Smb4KSharesViewItem *share_item = static_cast<Smb4KSharesViewItem *>(item);
0379   
0380   if (m_tooltipItem && m_tooltipItem != share_item)
0381   {
0382     emit aboutToHideToolTip(m_tooltipItem);
0383     m_tooltipItem->tooltip()->hide();
0384     m_tooltipItem = 0;
0385   }
0386 }
0387 
0388 
0389 void Smb4KSharesView::slotViewportEntered()
0390 {
0391   // Hide the tool tip.
0392   if (m_tooltipItem)
0393   {
0394     emit aboutToHideToolTip(m_tooltipItem);
0395     m_tooltipItem->tooltip()->hide();
0396     m_tooltipItem = 0;
0397   }
0398 }
0399