⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mediabutton.cpp

📁 LINUX 下, 以 QT/KDE 写的档案管理员
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************                         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 + -