📄 mediabutton.cpp
字号:
/*************************************************************************** mediabutton.cpp - description ------------------- copyright : (C) 2006 + by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * 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. * * * ***************************************************************************/#include "mediabutton.h"#include "../krusader.h"#include "../krservices.h"#include "../kicons.h"#include "../krslots.h"#include "../MountMan/kdiskfreesp.h"#include "../MountMan/kmountman.h"#include <qpopupmenu.h>#include <qfile.h>#include <qfontmetrics.h>#include <klocale.h>#include <kiconloader.h>#include <kdeversion.h>#include <kio/job.h>#include <kmessagebox.h>#include <kmimetype.h>#include <kprotocolinfo.h>#include <kfileitem.h>#include <kprocess.h>#include <qcursor.h>#ifdef Q_OS_LINUX// For CD/DVD drive detection#include <fcntl.h>#include <sys/ioctl.h>#include <unistd.h>#include <stdint.h>#define CDROM_GET_CAPABILITY 0x5331#define CDSL_CURRENT ((int) (~0U>>1))#define CDC_DVD_R 0x10000 /* drive can write DVD-R */#define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */#define CDC_CD_R 0x2000 /* drive is a CD-R */#define CDC_CD_RW 0x4000 /* drive is a CD-RW */#define CDC_DVD 0x8000 /* drive is a DVD */#include <qfile.h>#endifMediaButton::MediaButton( QWidget *parent, const char *name ) : QToolButton( parent, name ), popupMenu( 0 ), rightMenu( 0 ), hasMedia( false ), waitingForMount( -1 ), mountCheckerTimer() { KIconLoader * iconLoader = new KIconLoader(); QPixmap icon = iconLoader->loadIcon( "blockdevice", KIcon::Toolbar, 16 ); setFixedSize( icon.width() + 4, icon.height() + 4 ); setPixmap( icon ); setTextLabel( i18n( "Open the available media list" ), true ); setPopupDelay( 1 ); // immediate press setAcceptDrops( false ); popupMenu = new QPopupMenu( this ); popupMenu->installEventFilter( this ); Q_CHECK_PTR( popupMenu ); setPopup( popupMenu ); connect( popupMenu, SIGNAL( aboutToShow() ), this, SLOT( slotAboutToShow() ) ); connect( popupMenu, SIGNAL( aboutToHide() ), this, SLOT( slotAboutToHide() ) ); connect( popupMenu, SIGNAL( activated( int ) ), this, SLOT( slotPopupActivated( int ) ) ); connect( &mountCheckerTimer, SIGNAL( timeout() ), this, SLOT( slotTimeout() ) );}MediaButton::~MediaButton() { busy = false;}void MediaButton::slotAboutToShow() { hasMedia = KProtocolInfo::isKnownProtocol( QString( "media" ) ); krConfig->setGroup( "Advanced" ); if( krConfig->readBoolEntry( "DontUseMediaProt", !hasMedia ) ) hasMedia = false; popupMenu->clear(); urls.clear(); mediaUrls.clear(); mimes.clear(); quasiMounted.clear(); waitingForMount = -1; if( hasMedia ) createListWithMedia(); else createListWithoutMedia(); mountCheckerTimer.start( 1000, true );}void MediaButton::slotAboutToHide() { if( rightMenu ) rightMenu->close(); if( waitingForMount < 0 ) mountCheckerTimer.stop();}void MediaButton::createListWithMedia() { KIO::ListJob *job = KIO::listDir( KURL( "media:/" ), false ); connect( job, SIGNAL( entries( KIO::Job*, const KIO::UDSEntryList& ) ), this, SLOT( slotEntries( KIO::Job*, const KIO::UDSEntryList& ) ) ); connect( job, SIGNAL( result( KIO::Job* ) ), this, SLOT( slotListResult( KIO::Job* ) ) ); busy = true; if( !busy ) qApp->processEvents();}void MediaButton::slotEntries( KIO::Job *, const KIO::UDSEntryList& entries ) { KMountPoint::List mountList = KMountPoint::currentMountPoints(); KIO::UDSEntryListConstIterator it = entries.begin(); KIO::UDSEntryListConstIterator end = entries.end(); while( it != end ) { KURL url; QString text; QString mime; QString localPath; bool mounted = false; KIO::UDSEntry::ConstIterator it2 = (*it).begin(); for( ; it2 != (*it).end(); it2++ ) { switch ((*it2).m_uds) { case KIO::UDS_NAME: text = KURL::decode_string((*it2).m_str); break; case KIO::UDS_URL: url = KURL::fromPathOrURL( (*it2).m_str ); break; case KIO::UDS_MIME_TYPE: mime = (*it2).m_str; if( !mime.endsWith( "unmounted" ) ) mounted = true; break;#if KDE_IS_VERSION(3,4,0) case KIO::UDS_LOCAL_PATH: localPath = (*it2).m_str; break;#endif } } if( text != "." && text != ".." ) { int index = popupMenu->count(); QPixmap pixmap = FL_LOADICON( KMimeType::mimeType( mime ) ->icon( QString::null, true ) ); mediaUrls.append( url ); if( mounted && !localPath.isEmpty() ) { url = KURL::fromPathOrURL( localPath ); if( !text.contains( url.path() ) ) text += " [" + url.path() + "]"; } else if( mounted ) { url = getLocalPath( url, &mountList ); if( url.isLocalFile() && !text.contains( url.path() ) ) text += " [" + url.path() + "]"; } popupMenu->insertItem( pixmap, text, index, index ); urls.append( url ); mimes.append( mime ); quasiMounted.append( false ); } ++it; }}void MediaButton::slotListResult( KIO::Job * ) { busy = false;}KURL MediaButton::getLocalPath( const KURL &url, KMountPoint::List *mountList ) { KMountPoint::List mountListRef; if( mountList == 0 ) { mountListRef = KMountPoint::currentMountPoints(); mountList = &mountListRef; } for (KMountPoint::List::iterator it = mountList->begin(); it != mountList->end(); ++it) { QString name = (*it)->mountedFrom(); name = name.mid( name.findRev( "/" ) + 1 ); if( name == url.fileName() ) { QString point = (*it)->mountPoint(); if( !point.isEmpty() ) return KURL::fromPathOrURL( point ); } } return url;}void MediaButton::createListWithoutMedia() { /* WORKAROUND CODE START */ /* 1. the menu is drawn when we know all the mount points 2. the menu is corrected, when the HDD volume sizes arrive from df when the volume sizes are added to the items, some cases widget resize is necessary. If transparency is set for the widget, QT produces weird looking widgets, and that's why this workaround is used. Here we add additional spaces to the mounted HDD elements for avoiding the buggy widget resize. These are extra spaces. */ extraSpaces = ""; QFontMetrics fm( popupMenu->font() ); int requiredWidth = fm.width( "999.9 GB " ); while( fm.width( extraSpaces ) < requiredWidth ) extraSpaces+=" "; /* WORKAROUND CODE END */ KMountPoint::List possibleMountList = KMountPoint::possibleMountPoints(); for (KMountPoint::List::iterator it = possibleMountList.begin(); it != possibleMountList.end(); ++it) { addMountPoint( *it, false ); } KMountPoint::List mountList = KMountPoint::currentMountPoints(); for (KMountPoint::List::iterator it = mountList.begin(); it != mountList.end(); ++it) { addMountPoint( *it, true ); }}QString MediaButton::detectType( KMountPoint *mp ){ QString typeName = QString::null;#ifdef Q_OS_LINUX // Guessing device types by mount point is not exactly accurate... // Do something accurate first, and fall back if necessary. bool isCd=false; QString devname=mp->mountedFrom().section('/', -1); if(devname.startsWith("scd") || devname.startsWith("sr")) { // SCSI CD/DVD drive isCd=true; } else if(devname.startsWith("hd")) { // IDE device -- we can't tell if this is a // CD/DVD drive or harddisk by just looking at the // filename QFile m(QString("/proc/ide/") + devname + "/media"); if(m.open(IO_ReadOnly)) { QTextStream in(&m); QString buf=in.readLine(); if(buf.contains("cdrom")) isCd=true; m.close(); } } if(isCd) { int device=::open((const char *)QFile::encodeName(mp->mountedFrom()), O_RDONLY | O_NONBLOCK ); if(device>=0) { int drv=::ioctl(device, CDROM_GET_CAPABILITY, CDSL_CURRENT); if(drv>=0) { if((drv & CDC_DVD_R) || (drv & CDC_DVD_RAM)) typeName = "dvdwriter"; else if((drv & CDC_CD_R) || (drv & CDC_CD_RW)) typeName = "cdwriter"; else if(drv & CDC_DVD) typeName = "dvd"; else typeName = "cdrom"; } ::close(device); } } if( !typeName.isNull() ) return typeName;#elif defined(__FreeBSD__) if (-1!=mp->mountedFrom().find("/acd",0,FALSE)) typeName="cdrom"; else if (-1!=mp->mountedFrom().find("/scd",0,FALSE)) typeName="cdrom"; else if (-1!=mp->mountedFrom().find("/ad",0,FALSE)) typeName="hdd"; else if (-1!=mp->mountedFrom().find("/da",0,FALSE)) typeName="hdd"; else if (-1!=mp->mountedFrom().find("/afd",0,FALSE)) typeName="zip"; else#endif /* Guessing of cdrom and cd recorder devices */ if (-1!=mp->mountPoint().find("cdrom",0,FALSE)) typeName="cdrom"; else if (-1!=mp->mountedFrom().find("cdrom",0,FALSE)) typeName="cdrom"; else if (-1!=mp->mountPoint().find("cdwriter",0,FALSE)) typeName="cdwriter"; else if (-1!=mp->mountedFrom().find("cdwriter",0,FALSE)) typeName="cdwriter"; else if (-1!=mp->mountedFrom().find("cdrw",0,FALSE)) typeName="cdwriter"; else if (-1!=mp->mountPoint().find("cdrw",0,FALSE)) typeName="cdwriter"; else if (-1!=mp->mountedFrom().find("cdrecorder",0,FALSE)) typeName="cdwriter"; else if (-1!=mp->mountPoint().find("cdrecorder",0,FALSE)) typeName="cdwriter"; else if (-1!=mp->mountedFrom().find("dvdrecorder",0,FALSE)) typeName="dvdwriter"; else if (-1!=mp->mountPoint().find("dvdrecorder",0,FALSE)) typeName="dvdwriter"; else if (-1!=mp->mountPoint().find("dvdwriter",0,FALSE)) typeName="dvdwriter"; else if (-1!=mp->mountedFrom().find("dvdwriter",0,FALSE)) typeName="dvdwriter"; else if (-1!=mp->mountPoint().find("dvd",0,FALSE)) typeName="dvd"; else if (-1!=mp->mountedFrom().find("dvd",0,FALSE)) typeName="dvd"; else if (-1!=mp->mountedFrom().find("/dev/scd",0,FALSE)) typeName="cdrom"; else if (-1!=mp->mountedFrom().find("/dev/sr",0,FALSE)) typeName="cdrom"; /* Guessing of floppy types */ else if (-1!=mp->mountedFrom().find("fd",0,FALSE)) { if (-1!=mp->mountedFrom().find("360",0,FALSE)) typeName="floppy5"; if (-1!=mp->mountedFrom().find("1200",0,FALSE)) typeName="floppy5";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -