diff --git a/CMakeLists.txt b/CMakeLists.txt index aa450babc..37b65eef0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -369,43 +369,45 @@ if (TAGLIB_FOUND) SET(CANTATA_SRCS ${CANTATA_SRCS} replaygain/ebur128.c replaygain/scanner.cpp replaygain/rgdialog.cpp replaygain/tagreader.cpp replaygain/jobcontroller.cpp ) SET(CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} replaygain/scanner.h replaygain/rgdialog.h replaygain/tagreader.h replaygain/jobcontroller.h ) endif(FFMPEG_FOUND AND MPG123_FOUND) -endif (TAGLIB_FOUND) -add_subdirectory(po) - -IF( ENABLE_KDE_SUPPORT ) - if (TAGLIB_FOUND) - set (ENABLE_TAG_EDITOR_SUPPORT 1) + if (NOT WIN32) set (ENABLE_DEVICES_SUPPORT 1) + if (NOT ENABLE_KDE_SUPPORT) + add_subdirectory(solid-lite) + endif (NOT ENABLE_KDE_SUPPORT) if (ENABLE_MTP) find_package(Mtp) endif (ENABLE_MTP) + if (MTP_FOUND) + SET( CANTATA_SRCS ${CANTATA_SRCS} devices/mtpdevice.cpp ) + SET( CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} devices/mtpdevice.h ) + endif (MTP_FOUND) - SET( CANTATA_SRCS ${CANTATA_SRCS} devices/mediadevicecache.cpp devices/devicespage.cpp + SET( CANTATA_SRCS ${CANTATA_SRCS} devices/mediadevicecache.cpp devices/devicespage.cpp devices/filejob.cpp devices/device.cpp devices/fsdevice.cpp devices/umsdevice.cpp models/devicesmodel.cpp devices/filetyperesolver.cpp devices/actiondialog.cpp devices/devicepropertieswidget.cpp - devices/devicepropertiesdialog.cpp devices/encoders.cpp + devices/devicepropertiesdialog.cpp devices/encoders.cpp devices/freespaceinfo.cpp devices/transcodingjob.cpp devices/valueslider.cpp devices/syncdialog.cpp devices/synccollectionwidget.cpp) - SET( CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} devices/mediadevicecache.h devices/devicespage.h + SET( CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} devices/mediadevicecache.h devices/devicespage.h devices/filejob.h devices/device.h devices/fsdevice.h devices/umsdevice.h models/devicesmodel.h devices/actiondialog.h devices/devicepropertieswidget.h devices/devicepropertiesdialog.h devices/transcodingjob.h devices/valueslider.h devices/syncdialog.h devices/synccollectionwidget.h) SET( CANTATA_UIS ${CANTATA_UIS} devices/devicespage.ui devices/actiondialog.ui devices/devicepropertieswidget.ui devices/synccollectionwidget.ui) - if (ENABLE_REMOTE_DEVICES) + if (NOT WIN32 AND ENABLE_REMOTE_DEVICES) SET(CANTATA_SRCS ${CANTATA_SRCS} devices/remotefsdevice.cpp devices/remotedevicepropertiesdialog.cpp devices/remotedevicepropertieswidget.cpp) SET(CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} devices/remotefsdevice.h devices/remotedevicepropertiesdialog.h devices/remotedevicepropertieswidget.h) SET(CANTATA_UIS ${CANTATA_UIS} devices/remotedevicepropertieswidget.ui) - endif (ENABLE_REMOTE_DEVICES) - if (MTP_FOUND) - SET( CANTATA_SRCS ${CANTATA_SRCS} devices/mtpdevice.cpp ) - SET( CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} devices/mtpdevice.h ) - endif (MTP_FOUND) - endif (TAGLIB_FOUND) + endif (NOT WIN32 AND ENABLE_REMOTE_DEVICES) + endif (NOT WIN32) +endif (TAGLIB_FOUND) +add_subdirectory(po) + +IF( ENABLE_KDE_SUPPORT ) macro_ensure_version("4.7.0" ${KDE_VERSION} KDE_VERSION_47) if (NOT KDE_VERSION_47) @@ -418,14 +420,10 @@ IF( ENABLE_KDE_SUPPORT ) QT4_ADD_RESOURCES( CANTATA_RC_SRCS ${CANTATA_RCS} ) KDE4_ADD_UI_FILES( CANTATA_UI_HDRS ${CANTATA_UIS} ) KDE4_ADD_EXECUTABLE( cantata ${CANTATA_SRCS} ${CANTATA_MOC_SRCS} ${CANTATA_RC_SRCS} ${CANTATA_UI_HDRS} ) - TARGET_LINK_LIBRARIES( cantata ${KDE4_KDEWEBKIT_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${KDE4_SOLID_LIBS} ) - if (MTP_FOUND) - TARGET_LINK_LIBRARIES(cantata ${MTP_LIBRARIES}) - include_directories( ${MTP_INCLUDE_DIR}) - endif (MTP_FOUND) - if (ENABLE_REMOTE_DEVICES) + TARGET_LINK_LIBRARIES( cantata ${KDE4_KDEWEBKIT_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS} ${KDE4_SOLID_LIBS} ) + if (NOT WIN32 AND TAGLIB_FOUND AND ENABLE_REMOTE_DEVICES) TARGET_LINK_LIBRARIES(cantata ${KDE4_KFILE_LIBS}) - endif (ENABLE_REMOTE_DEVICES) + endif (NOT WIN32 AND TAGLIB_FOUND AND ENABLE_REMOTE_DEVICES) install( TARGETS cantata ${INSTALL_TARGETS_DEFAULT_ARGS} ) install( PROGRAMS dynamic/cantata-dynamic DESTINATION bin) install( FILES cantataui.rc DESTINATION ${DATA_INSTALL_DIR}/cantata ) @@ -467,6 +465,11 @@ ELSE( ENABLE_KDE_SUPPORT ) include_directories(${CMAKE_BINARY_DIR}/qtsingleapplication) ENDIF( ENABLE_KDE_SUPPORT ) +if (MTP_FOUND AND NOT WIN32) + TARGET_LINK_LIBRARIES(cantata ${MTP_LIBRARIES}) + include_directories( ${MTP_INCLUDE_DIR}) +endif (MTP_FOUND AND NOT WIN32) + ADD_SUBDIRECTORY( icons ) TARGET_LINK_LIBRARIES(cantata ${QT_QTXML_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTDBUS_LIBRARY}) @@ -488,6 +491,9 @@ if (TAGLIB_FOUND) include_directories( ${SPEEXDSP_INCLUDE_DIRS}) endif(SPEEXDSP_FOUND) endif(FFMPEG_FOUND AND MPG123_FOUND) + if (NOT ENABLE_KDE_SUPPORT) + TARGET_LINK_LIBRARIES(cantata solidlite) + endif (NOT ENABLE_KDE_SUPPORT) endif (TAGLIB_FOUND) if (PHONON_FOUND) @@ -515,48 +521,38 @@ configure_file(config.h.cmake ${CMAKE_BINARY_DIR}/config.h) message("") IF( ENABLE_KDE_SUPPORT ) message("INFO: Building with KDE support") - if (TAGLIB_FOUND) - message(" Extra enabled features:") - message(" - UMS device sync") - if (MTP_FOUND) - message(" - MTP device sync") - endif (MTP_FOUND) - if (ENABLE_REMOTE_DEVICES) - message(" - Remote device sync (EXPERIMENTAL)") - endif (ENABLE_REMOTE_DEVICES) - if( NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT FFMPEG_FOUND OR NOT MPG123_FOUND ) - message(" Disabled features:") - if (NOT TAGLIB_FOUND) - message(" - Tag Editor (taglib required)") - message(" - Track Organizer (taglib required)") - message(" - Commandline support (taglib required)") - message(" - HTTP server support (taglib required)") - endif (NOT TAGLIB_FOUND) - if (NOT MTP_FOUND) - message(" - MTP device sync (taglib and libmtp required)") - endif (NOT MTP_FOUND) - #if (NOT ENABLE_REMOTE_DEVICES) - # message(" - Remote device sync (EXPERIMENTAL)") - #endif (NOT ENABLE_REMOTE_DEVICES) - if(NOT FFMPEG_FOUND OR NOT MPG123_FOUND) - message(" - ReplayGain calculation (taglib, ffmpeg, and mpg123 required)") - endif(NOT FFMPEG_FOUND OR NOT MPG123_FOUND) - endif( NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT FFMPEG_FOUND OR NOT MPG123_FOUND ) - endif (TAGLIB_FOUND) -ELSE( ENABLE_KDE_SUPPORT ) +else ( ENABLE_KDE_SUPPORT ) if (NOT WIN32) - message("INFO: Building WITHOUT KDE support - Device sync support DISABLED") - if( NOT TAGLIB_FOUND OR NOT FFMPEG_FOUND OR NOT MPG123_FOUND ) - message(" Disabled features:") - if (NOT TAGLIB_FOUND) - message(" - Tag Editor (taglib required)") - message(" - Track Organizer (taglib required)") - message(" - Commandline support (taglib required)") - message(" - HTTP server support (taglib required)") - endif (NOT TAGLIB_FOUND) - message(" - ReplayGain calculation (taglib, ffmpeg, and mpg123 required)") - endif( NOT TAGLIB_FOUND OR NOT FFMPEG_FOUND OR NOT MPG123_FOUND ) + message("INFO: Building WITHOUT KDE support") endif (NOT WIN32) +endif ( ENABLE_KDE_SUPPORT ) + +if (TAGLIB_FOUND) + if (ENABLE_REMOTE_DEVICES) + message(" Extra enabled features:") + message(" - Remote device sync (EXPERIMENTAL)") + endif (ENABLE_REMOTE_DEVICES) + if( NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT FFMPEG_FOUND OR NOT MPG123_FOUND ) + message(" Disabled features:") + if (NOT TAGLIB_FOUND) + message(" - Tag Editor (taglib required)") + message(" - Track Organizer (taglib required)") + message(" - Commandline support (taglib required)") + message(" - HTTP server support (taglib required)") + if (NOT WIN32) + message(" - UMS device sync (taglib required)") + endif (NOT WIN32) + endif (NOT TAGLIB_FOUND) + if (NOT MTP_FOUND AND NOT WIN32) + message(" - MTP device sync (taglib and libmtp required)") + endif (NOT MTP_FOUND AND NOT WIN32) + if(NOT FFMPEG_FOUND OR NOT MPG123_FOUND) + message(" - ReplayGain calculation (taglib, ffmpeg, and mpg123 required)") + endif(NOT FFMPEG_FOUND OR NOT MPG123_FOUND) + endif( NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT FFMPEG_FOUND OR NOT MPG123_FOUND ) +endif (TAGLIB_FOUND) + +IF ( NOT ENABLE_KDE_SUPPORT ) message("") message("*************************************************************") message("*************************************************************") @@ -565,5 +561,5 @@ ELSE( ENABLE_KDE_SUPPORT ) message("*************************************************************") message("*************************************************************") message("") -ENDIF( ENABLE_KDE_SUPPORT ) +ENDIF( NOT ENABLE_KDE_SUPPORT ) message("") diff --git a/ChangeLog b/ChangeLog index 109bd4835..ce8e4eb99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,8 @@ languages that have more than 1 plural form, it is suggested that BOTH strings are translatated to the format "Items: %1" - e.g. "1 Track" becomes "Tracks: 1", and "%1 Tracks" becomes "Tracks: %1" +11. Device sync support for Qt-only builds. To support this, a cut-down version + of Solid is included. 0.8.3.1 ------- diff --git a/cmake/FindUDev.cmake b/cmake/FindUDev.cmake new file mode 100644 index 000000000..4c8390db6 --- /dev/null +++ b/cmake/FindUDev.cmake @@ -0,0 +1,19 @@ +# - Try to find UDev +# Once done this will define +# +# UDEV_FOUND - system has UDev +# UDEV_INCLUDE_DIR - the libudev include directory +# UDEV_LIBS - The libudev libraries + +# Copyright (c) 2010, Rafael Fernández López, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +find_path(UDEV_INCLUDE_DIR libudev.h) +find_library(UDEV_LIBS udev) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(UDev DEFAULT_MSG UDEV_INCLUDE_DIR UDEV_LIBS) + +mark_as_advanced(UDEV_INCLUDE_DIR UDEV_LIBS) diff --git a/cmake/MacroLogFeature.cmake b/cmake/MacroLogFeature.cmake new file mode 100644 index 000000000..45e27b6df --- /dev/null +++ b/cmake/MacroLogFeature.cmake @@ -0,0 +1,157 @@ +# This file defines the Feature Logging macros. +# +# MACRO_LOG_FEATURE(VAR FEATURE DESCRIPTION URL [REQUIRED [MIN_VERSION [COMMENTS]]]) +# Logs the information so that it can be displayed at the end +# of the configure run +# VAR : TRUE or FALSE, indicating whether the feature is supported +# FEATURE: name of the feature, e.g. "libjpeg" +# DESCRIPTION: description what this feature provides +# URL: home page +# REQUIRED: TRUE or FALSE, indicating whether the featue is required +# MIN_VERSION: minimum version number. empty string if unneeded +# COMMENTS: More info you may want to provide. empty string if unnecessary +# +# MACRO_DISPLAY_FEATURE_LOG() +# Call this to display the collected results. +# Exits CMake with a FATAL error message if a required feature is missing +# +# Example: +# +# INCLUDE(MacroLogFeature) +# +# FIND_PACKAGE(JPEG) +# MACRO_LOG_FEATURE(JPEG_FOUND "libjpeg" "Support JPEG images" "http://www.ijg.org" TRUE "3.2a" "") +# ... +# MACRO_DISPLAY_FEATURE_LOG() + +# Copyright (c) 2006, Alexander Neundorf, +# Copyright (c) 2006, Allen Winter, +# Copyright (c) 2009, Sebastian Trueg, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT _macroLogFeatureAlreadyIncluded) + SET(_file ${CMAKE_BINARY_DIR}/MissingRequirements.txt) + IF (EXISTS ${_file}) + FILE(REMOVE ${_file}) + ENDIF (EXISTS ${_file}) + + SET(_file ${CMAKE_BINARY_DIR}/EnabledFeatures.txt) + IF (EXISTS ${_file}) + FILE(REMOVE ${_file}) + ENDIF (EXISTS ${_file}) + + SET(_file ${CMAKE_BINARY_DIR}/DisabledFeatures.txt) + IF (EXISTS ${_file}) + FILE(REMOVE ${_file}) + ENDIF (EXISTS ${_file}) + + SET(_macroLogFeatureAlreadyIncluded TRUE) + + INCLUDE(FeatureSummary) + +ENDIF (NOT _macroLogFeatureAlreadyIncluded) + + +MACRO(MACRO_LOG_FEATURE _var _package _description _url ) # _required _minvers _comments) + + STRING(TOUPPER "${ARGV4}" _required) + SET(_minvers "${ARGV5}") + SET(_comments "${ARGV6}") + + IF (${_var}) + SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/EnabledFeatures.txt) + ELSE (${_var}) + IF ("${_required}" STREQUAL "TRUE") + SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/MissingRequirements.txt) + ELSE ("${_required}" STREQUAL "TRUE") + SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/DisabledFeatures.txt) + ENDIF ("${_required}" STREQUAL "TRUE") + ENDIF (${_var}) + + SET(_logtext " * ${_package}") + + IF (NOT ${_var}) + IF (${_minvers} MATCHES ".*") + SET(_logtext "${_logtext} (${_minvers} or higher)") + ENDIF (${_minvers} MATCHES ".*") + SET(_logtext "${_logtext} <${_url}>\n ") + ELSE (NOT ${_var}) + SET(_logtext "${_logtext} - ") + ENDIF (NOT ${_var}) + + SET(_logtext "${_logtext}${_description}") + + IF (NOT ${_var}) + IF (${_comments} MATCHES ".*") + SET(_logtext "${_logtext}\n ${_comments}") + ENDIF (${_comments} MATCHES ".*") +# SET(_logtext "${_logtext}\n") #double-space missing features? + ENDIF (NOT ${_var}) + + FILE(APPEND "${_LOGFILENAME}" "${_logtext}\n") + + IF(COMMAND SET_PACKAGE_INFO) # in FeatureSummary.cmake since CMake 2.8.3 + SET_PACKAGE_INFO("${_package}" "\"${_description}\"" "${_url}" "\"${_comments}\"") + ENDIF(COMMAND SET_PACKAGE_INFO) + +ENDMACRO(MACRO_LOG_FEATURE) + + +MACRO(MACRO_DISPLAY_FEATURE_LOG) + IF(COMMAND FEATURE_SUMMARY) # in FeatureSummary.cmake since CMake 2.8.3 + FEATURE_SUMMARY(FILENAME ${CMAKE_CURRENT_BINARY_DIR}/FindPackageLog.txt + WHAT ALL) + ENDIF(COMMAND FEATURE_SUMMARY) + + SET(_missingFile ${CMAKE_BINARY_DIR}/MissingRequirements.txt) + SET(_enabledFile ${CMAKE_BINARY_DIR}/EnabledFeatures.txt) + SET(_disabledFile ${CMAKE_BINARY_DIR}/DisabledFeatures.txt) + + IF (EXISTS ${_missingFile} OR EXISTS ${_enabledFile} OR EXISTS ${_disabledFile}) + SET(_printSummary TRUE) + ENDIF (EXISTS ${_missingFile} OR EXISTS ${_enabledFile} OR EXISTS ${_disabledFile}) + + IF(_printSummary) + SET(_missingDeps 0) + IF (EXISTS ${_enabledFile}) + FILE(READ ${_enabledFile} _enabled) + FILE(REMOVE ${_enabledFile}) + SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- The following external packages were located on your system.\n-- This installation will have the extra features provided by these packages.\n-----------------------------------------------------------------------------\n${_enabled}") + ENDIF (EXISTS ${_enabledFile}) + + + IF (EXISTS ${_disabledFile}) + SET(_missingDeps 1) + FILE(READ ${_disabledFile} _disabled) + FILE(REMOVE ${_disabledFile}) + SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- The following OPTIONAL packages could NOT be located on your system.\n-- Consider installing them to enable more features from this software.\n-----------------------------------------------------------------------------\n${_disabled}") + ENDIF (EXISTS ${_disabledFile}) + + + IF (EXISTS ${_missingFile}) + SET(_missingDeps 1) + FILE(READ ${_missingFile} _requirements) + SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- The following REQUIRED packages could NOT be located on your system.\n-- You must install these packages before continuing.\n-----------------------------------------------------------------------------\n${_requirements}") + FILE(REMOVE ${_missingFile}) + SET(_haveMissingReq 1) + ENDIF (EXISTS ${_missingFile}) + + + IF (NOT ${_missingDeps}) + SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- Congratulations! All external packages have been found.") + ENDIF (NOT ${_missingDeps}) + + + MESSAGE(${_summary}) + MESSAGE("-----------------------------------------------------------------------------\n") + + + IF(_haveMissingReq) + MESSAGE(FATAL_ERROR "Exiting: Missing Requirements") + ENDIF(_haveMissingReq) + + ENDIF(_printSummary) + +ENDMACRO(MACRO_DISPLAY_FEATURE_LOG) diff --git a/cmake/MacroOptionalFindPackage.cmake b/cmake/MacroOptionalFindPackage.cmake new file mode 100644 index 000000000..d4ed48e33 --- /dev/null +++ b/cmake/MacroOptionalFindPackage.cmake @@ -0,0 +1,48 @@ +# - MACRO_OPTIONAL_FIND_PACKAGE() combines FIND_PACKAGE() with an OPTION() +# MACRO_OPTIONAL_FIND_PACKAGE( [QUIT] ) +# This macro is a combination of OPTION() and FIND_PACKAGE(), it +# works like FIND_PACKAGE(), but additionally it automatically creates +# an option name WITH_, which can be disabled via the cmake GUI. +# or via -DWITH_=OFF +# The standard _FOUND variables can be used in the same way +# as when using the normal FIND_PACKAGE() + +# Copyright (c) 2006-2010 Alexander Neundorf, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# This is just a helper macro to set a bunch of variables empty. +# We don't know whether the package uses UPPERCASENAME or CamelCaseName, so we try both: +macro(_MOFP_SET_EMPTY_IF_DEFINED _name _var) + if(DEFINED ${_name}_${_var}) + set(${_name}_${_var} "") + endif(DEFINED ${_name}_${_var}) + + string(TOUPPER ${_name} _nameUpper) + if(DEFINED ${_nameUpper}_${_var}) + set(${_nameUpper}_${_var} "") + endif(DEFINED ${_nameUpper}_${_var}) +endmacro(_MOFP_SET_EMPTY_IF_DEFINED _package _var) + + +macro (MACRO_OPTIONAL_FIND_PACKAGE _name ) + option(WITH_${_name} "Search for ${_name} package" ON) + if (WITH_${_name}) + find_package(${_name} ${ARGN}) + else (WITH_${_name}) + string(TOUPPER ${_name} _nameUpper) + set(${_name}_FOUND FALSE) + set(${_nameUpper}_FOUND FALSE) + + _mofp_set_empty_if_defined(${_name} INCLUDE_DIRS) + _mofp_set_empty_if_defined(${_name} INCLUDE_DIR) + _mofp_set_empty_if_defined(${_name} INCLUDES) + _mofp_set_empty_if_defined(${_name} LIBRARY) + _mofp_set_empty_if_defined(${_name} LIBRARIES) + _mofp_set_empty_if_defined(${_name} LIBS) + _mofp_set_empty_if_defined(${_name} FLAGS) + _mofp_set_empty_if_defined(${_name} DEFINITIONS) + endif (WITH_${_name}) +endmacro (MACRO_OPTIONAL_FIND_PACKAGE) + diff --git a/devices/actiondialog.cpp b/devices/actiondialog.cpp index 3b565702e..bfc957d6d 100644 --- a/devices/actiondialog.cpp +++ b/devices/actiondialog.cpp @@ -35,12 +35,10 @@ #include "mpdconnection.h" #include "encoders.h" #include "localize.h" -#include -#include -#include -#include -#include -#include +#include "messagebox.h" +#include "filejob.h" +#include "freespaceinfo.h" +#include static int iCount=0; @@ -113,10 +111,10 @@ void ActionDialog::copy(const QString &srcUdi, const QString &dstUdi, const QLis capacityString=dev->capacityString(); usedCapacity=dev->usedCapacity(); } else { - KDiskFreeSpaceInfo inf=KDiskFreeSpaceInfo::freeSpaceInfo(MPDConnection::self()->getDetails().dir); + FreeSpaceInfo inf=FreeSpaceInfo(MPDConnection::self()->getDetails().dir); spaceAvailable=inf.size()-inf.used(); usedCapacity=(inf.used()*1.0)/(inf.size()*1.0); - capacityString=i18n("%1 free", KGlobal::locale()->formatByteSize(inf.size()-inf.used()), 1); + capacityString=i18n("%1 free").arg(Utils::formatByteSize(inf.size()-inf.used())); } bool enoughSpace=spaceAvailable>spaceRequired; @@ -133,9 +131,8 @@ void ActionDialog::copy(const QString &srcUdi, const QString &dstUdi, const QLis namingOptions.load(mpdCfgName, true); setPage(PAGE_START); mode=Copy; - capacity->setText(capacityString); - capacity->setValue((usedCapacity*100)+0.5); - capacity->setDrawTextMode(KCapacityBar::DrawTextInline); + + capacity->update(capacityString, (usedCapacity*100)+0.5); bool destIsDev=sourceUdi.isEmpty(); mpdConfigured=DeviceOptions::isConfigured(mpdCfgName, true); @@ -143,17 +140,17 @@ void ActionDialog::copy(const QString &srcUdi, const QString &dstUdi, const QLis configureSourceLabel->setVisible((!destIsDev && !dev->isConfigured()) || (destIsDev && !mpdConfigured)); show(); if (!enoughSpace) { - KMessageBox::information(this, i18n("There is insufficient space left on the destination device.\n" - "The selected songs consume %1, but there is only %2 left.\n" - "The songs will need to be transcoded to a smaller filesize in order to be successfully copied.", - KGlobal::locale()->formatByteSize(spaceRequired), - KGlobal::locale()->formatByteSize(spaceAvailable))); + MessageBox::information(this, i18n("There is insufficient space left on the destination device.\n" + "The selected songs consume %1, but there is only %2 left.\n" + "The songs will need to be transcoded to a smaller filesize in order to be successfully copied.") + .arg(Utils::formatByteSize(spaceRequired)) + .arg(Utils::formatByteSize(spaceAvailable))); } } else { - KMessageBox::error(parentWidget(), i18n("There is insufficient space left on the destination.\n" - "The selected songs consume %1, but there is only %2 left.", - KGlobal::locale()->formatByteSize(spaceRequired), - KGlobal::locale()->formatByteSize(spaceAvailable))); + MessageBox::error(parentWidget(), i18n("There is insufficient space left on the destination.\n" + "The selected songs consume %1, but there is only %2 left.") + .arg(Utils::formatByteSize(spaceRequired)) + .arg(Utils::formatByteSize(spaceAvailable))); deleteLater(); } } @@ -212,11 +209,11 @@ void ActionDialog::slotButtonClicked(int button) case Ok: if (haveVariousArtists && ((configureDestLabel->isVisible() && - KMessageBox::No==KMessageBox::warningYesNo(this, i18n("

You have not configured the destination device.
" - "Continue with the default settings?

"))) || + MessageBox::No==MessageBox::warningYesNo(this, i18n("

You have not configured the destination device.
" + "Continue with the default settings?

"))) || (configureSourceLabel->isVisible() && - KMessageBox::No==KMessageBox::warningYesNo(this, i18n("

You have not configured the source device.
" - "Continue with the default settings?

"))))) { + MessageBox::No==MessageBox::warningYesNo(this, i18n("

You have not configured the source device.
" + "Continue with the default settings?

"))))) { return; } Settings::self()->saveOverwriteSongs(overwrite->isChecked()); @@ -264,7 +261,7 @@ void ActionDialog::slotButtonClicked(int button) break; case PAGE_PROGRESS: paused=true; - if (KMessageBox::Yes==KMessageBox::questionYesNo(this, i18n("Are you sure you wish to cancel?"))) { + if (MessageBox::Yes==MessageBox::questionYesNo(this, i18n("Are you sure you wish to cancel?"))) { refreshLibrary(); reject(); // Need to call this - if not, when dialog is closed by window X control, it is not deleted!!!! @@ -298,7 +295,7 @@ Device * ActionDialog::getDevice(const QString &udi) if (isVisible()) { setPage(PAGE_ERROR, error); } else { - KMessageBox::error(parentWidget(), error); + MessageBox::error(parentWidget(), error); } return 0; @@ -396,35 +393,35 @@ void ActionDialog::actionStatus(int status) } break; case Device::FileExists: - setPage(PAGE_SKIP, i18n("The destination filename already exists!
%1", formatSong(currentSong, true))); + setPage(PAGE_SKIP, i18n("The destination filename already exists!
%1").arg(formatSong(currentSong, true))); break; case Device::SongExists: - setPage(PAGE_SKIP, i18n("Song already exists!
%1", formatSong(currentSong))); + setPage(PAGE_SKIP, i18n("Song already exists!
%1").arg(formatSong(currentSong))); break; case Device::SongDoesNotExist: - setPage(PAGE_SKIP, i18n("Song does not exist!
%1", formatSong(currentSong))); + setPage(PAGE_SKIP, i18n("Song does not exist!
%1").arg(formatSong(currentSong))); break; case Device::DirCreationFaild: - setPage(PAGE_SKIP, i18n("Failed to create destination folder!
Please check you have sufficient permissions.
%1", formatSong(currentSong, true))); + setPage(PAGE_SKIP, i18n("Failed to create destination folder!
Please check you have sufficient permissions.
%1").arg(formatSong(currentSong, true))); break; case Device::SourceFileDoesNotExist: - setPage(PAGE_SKIP, i18n("Source file no longer exists?

%1", formatSong(currentSong, true))); + setPage(PAGE_SKIP, i18n("Source file no longer exists?

%1").arg(formatSong(currentSong, true))); break; case Device::Failed: - setPage(PAGE_SKIP, Copy==mode ? i18n("Failed to copy.
%1", formatSong(currentSong)) - : i18n("Failed to delete.
%1", formatSong(currentSong))); + setPage(PAGE_SKIP, Copy==mode ? i18n("Failed to copy.
%1").arg(formatSong(currentSong)) + : i18n("Failed to delete.
%1").arg(formatSong(currentSong))); break; case Device::NotConnected: - setPage(PAGE_ERROR, i18n("Not connected to device.
%1", formatSong(currentSong))); + setPage(PAGE_ERROR, i18n("Not connected to device.
%1").arg(formatSong(currentSong))); break; case Device::CodecNotAvailable: - setPage(PAGE_ERROR, i18n("Selected codec is not available.
%1", formatSong(currentSong))); + setPage(PAGE_ERROR, i18n("Selected codec is not available.
%1").arg(formatSong(currentSong))); break; case Device::TranscodeFailed: - setPage(PAGE_SKIP, i18n("Transcoding failed.

%1", formatSong(currentSong))); + setPage(PAGE_SKIP, i18n("Transcoding failed.

%1").arg(formatSong(currentSong))); break; case Device::FailedToCreateTempFile: - setPage(PAGE_ERROR, i18n("Failed to create temporary file.
(Required for transcoding to MTP devices.)
%1", formatSong(currentSong))); + setPage(PAGE_ERROR, i18n("Failed to create temporary file.
(Required for transcoding to MTP devices.)
%1").arg(formatSong(currentSong))); break; default: break; @@ -523,21 +520,21 @@ QString ActionDialog::formatSong(const Song &s, bool showFiles) "Track:%3" "Source file:%4" "Destination file:%5" - "", s.albumArtist(), s.album, - s.trackAndTitleStr(Song::isVariousArtists(s.albumArtist()) && !Song::isVariousArtists(s.artist)), s.file, destFile) + "").arg(s.albumArtist()).arg(s.album) + .arg(s.trackAndTitleStr(Song::isVariousArtists(s.albumArtist()) && !Song::isVariousArtists(s.artist))).arg(s.file).arg(destFile) : i18n("" "" "" "" "" - "
Artist:%1
Album:%2
Track:%3
File:%4
", s.albumArtist(), s.album, - s.trackAndTitleStr(Song::isVariousArtists(s.albumArtist()) && !Song::isVariousArtists(s.artist)), s.file) + "").arg(s.albumArtist()).arg(s.album) + .arg(s.trackAndTitleStr(Song::isVariousArtists(s.albumArtist()) && !Song::isVariousArtists(s.artist))).arg(s.file) : i18n("" "" "" "" - "
Artist:%1
Album:%2
Track:%3
", s.albumArtist(), s.album, - s.trackAndTitleStr(Song::isVariousArtists(s.albumArtist()) && !Song::isVariousArtists(s.artist))); + "").arg(s.albumArtist()).arg(s.album) + .arg(s.trackAndTitleStr(Song::isVariousArtists(s.albumArtist()) && !Song::isVariousArtists(s.artist))); } void ActionDialog::refreshLibrary() @@ -566,13 +563,13 @@ void ActionDialog::removeSong(const Song &s) return; } - KIO::SimpleJob *job=KIO::file_delete(KUrl(s.file), KIO::HideProgressInfo); - connect(job, SIGNAL(result(KJob *)), SLOT(removeSongResult(KJob *))); + DeleteJob *job=new DeleteJob(s.file); + connect(job, SIGNAL(result(int)), SLOT(removeSongResult(int))); } -void ActionDialog::removeSongResult(KJob *job) +void ActionDialog::removeSongResult(int status) { - if (job->error()) { + if (FileJob::StatusOk!=status) { actionStatus(Device::Failed); } else { MusicLibraryModel::self()->removeSongFromList(currentSong); @@ -595,4 +592,3 @@ void ActionDialog::incProgress() progressBar->setValue(progressBar->value()+1); } } - diff --git a/devices/actiondialog.h b/devices/actiondialog.h index 88e5ba59a..7c50cbb84 100644 --- a/devices/actiondialog.h +++ b/devices/actiondialog.h @@ -29,8 +29,6 @@ #include "device.h" #include "ui_actiondialog.h" -class KJob; - class ActionDialog : public Dialog, Ui::ActionDialog { Q_OBJECT @@ -63,7 +61,7 @@ private Q_SLOTS: void saveProperties(); void actionStatus(int status); void doNext(); - void removeSongResult(KJob *job); + void removeSongResult(int status); void copyPercent(unsigned long percent); private: diff --git a/devices/device.cpp b/devices/device.cpp index 9d183912f..7de477499 100644 --- a/devices/device.cpp +++ b/devices/device.cpp @@ -35,9 +35,15 @@ #include "musiclibraryitemalbum.h" #include "musiclibraryitemsong.h" #include "localize.h" +#ifdef ENABLE_KDE_SUPPORT #include #include #include +#else +#include "solid-lite/portablemediaplayer.h" +#include "solid-lite/storageaccess.h" +#include "solid-lite/storagedrive.h" +#endif #include #include @@ -313,5 +319,5 @@ void Device::setStatusMessage(const QString &msg) void Device::songCount(int c) { - setStatusMessage(i18n("Updating (%1)...", c)); + setStatusMessage(i18n("Updating (%1)...").arg(c)); } diff --git a/devices/device.h b/devices/device.h index a229d6d82..435a5dec8 100644 --- a/devices/device.h +++ b/devices/device.h @@ -29,7 +29,11 @@ #include "encoders.h" #include "deviceoptions.h" #include +#ifdef ENABLE_KDE_SUPPORT #include +#else +#include "solid-lite/device.h" +#endif class QWidget; class DevicesModel; diff --git a/devices/deviceoptions.cpp b/devices/deviceoptions.cpp index cf20cc216..1ab2a61a8 100644 --- a/devices/deviceoptions.cpp +++ b/devices/deviceoptions.cpp @@ -24,14 +24,7 @@ #include "deviceoptions.h" #include "song.h" #include "localize.h" -#ifdef ENABLE_KDE_SUPPORT -#include -#include -#include -#include -#else -#include -#endif +#include "settings.h" #include #include @@ -193,7 +186,7 @@ DeviceOptions::DeviceOptions() , asciiOnly(false) , ignoreThe(false) , replaceSpaces(false) - #ifdef ENABLE_KDE_SUPPORT + #ifdef ENABLE_DEVICES_SUPPORT , fixVariousArtists(false) , transcoderValue(0) , transcoderWhenDifferent(false) @@ -220,65 +213,56 @@ bool DeviceOptions::isConfigured(const QString &group, bool isMpd) void DeviceOptions::load(const QString &group, bool isMpd) { #ifdef ENABLE_KDE_SUPPORT - KConfigGroup grp(KGlobal::config(), !isMpd || group.isEmpty() || KGlobal::config()->hasGroup(group) ? group : constMpdGroup); - scheme=grp.readEntry("scheme", scheme); - vfatSafe=grp.readEntry("vfatSafe", vfatSafe); - asciiOnly=grp.readEntry("asciiOnly", asciiOnly); - ignoreThe=grp.readEntry("ignoreThe", ignoreThe); - replaceSpaces=grp.readEntry("replaceSpaces", replaceSpaces); - if (!isMpd) { - fixVariousArtists=grp.readEntry("fixVariousArtists", fixVariousArtists); - transcoderCodec=grp.readEntry("transcoderCodec", transcoderCodec); - transcoderValue=grp.readEntry("transcoderValue", transcoderValue); - transcoderWhenDifferent=grp.readEntry("transcoderWhenDifferent", transcoderWhenDifferent); - } + KConfigGroup cfg(KGlobal::config(), !isMpd || group.isEmpty() || KGlobal::config()->hasGroup(group) ? group : constMpdGroup); #else - #define GET_STRING(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toString() : QString(DEF)) - #define GET_BOOL(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toBool() : DEF) - QSettings cfg; - QString sep=group.isEmpty() ? QString() : ((-1==cfg.childGroups().indexOf(group) && isMpd ? constMpdGroup : group)+"/"); - scheme=GET_STRING(sep+"scheme", scheme); - vfatSafe=GET_BOOL(sep+"vfatSafe", vfatSafe); - asciiOnly=GET_BOOL(sep+"asciiOnly", asciiOnly); - ignoreThe=GET_BOOL(sep+"ignoreThe", ignoreThe); - replaceSpaces=GET_BOOL(sep+"replaceSpaces", replaceSpaces); + cfg.beginGroup(!isMpd || group.isEmpty() || HAS_GROUP(group) ? group : constMpdGroup); + #endif + scheme=GET_STRING("scheme", scheme); + vfatSafe=GET_BOOL("vfatSafe", vfatSafe); + asciiOnly=GET_BOOL("asciiOnly", asciiOnly); + ignoreThe=GET_BOOL("ignoreThe", ignoreThe); + replaceSpaces=GET_BOOL("replaceSpaces", replaceSpaces); + #ifdef ENABLE_DEVICES_SUPPORT + if (!isMpd) { + fixVariousArtists=GET_BOOL("fixVariousArtists", fixVariousArtists); + transcoderCodec=GET_STRING("transcoderCodec", transcoderCodec); + transcoderValue=GET_INT("transcoderValue", transcoderValue); + transcoderWhenDifferent=GET_BOOL("transcoderWhenDifferent", transcoderWhenDifferent); + } #endif } void DeviceOptions::save(const QString &group, bool isMpd) { #ifdef ENABLE_KDE_SUPPORT - KConfigGroup grp(KGlobal::config(), group); - grp.writeEntry("scheme", scheme); - grp.writeEntry("vfatSafe", vfatSafe); - grp.writeEntry("asciiOnly", asciiOnly); - grp.writeEntry("ignoreThe", ignoreThe); - grp.writeEntry("replaceSpaces", replaceSpaces); - if (!isMpd) { - grp.writeEntry("fixVariousArtists", fixVariousArtists); - grp.writeEntry("transcoderCodec", transcoderCodec); - grp.writeEntry("transcoderValue", transcoderValue); - grp.writeEntry("transcoderWhenDifferent", transcoderWhenDifferent); - } - grp.sync(); - - if (isMpd && KGlobal::config()->hasGroup(constMpdGroup)) { - KGlobal::config()->deleteGroup(constMpdGroup); - } + KConfigGroup cfg(KGlobal::config(), !isMpd || group.isEmpty() || KGlobal::config()->hasGroup(group) ? group : constMpdGroup); #else QSettings cfg; - QString sep=group.isEmpty() ? QString() : (group+"/"); - cfg.setValue(sep+"scheme", scheme); - cfg.setValue(sep+"vfatSafe", vfatSafe); - cfg.setValue(sep+"asciiOnly", asciiOnly); - cfg.setValue(sep+"ignoreThe", ignoreThe); - cfg.setValue(sep+"replaceSpaces", replaceSpaces); + cfg.beginGroup(!isMpd || group.isEmpty() || HAS_GROUP(group) ? group : constMpdGroup); + #endif - if (isMpd && -1!=cfg.childGroups().indexOf(constMpdGroup)) { - cfg.remove(constMpdGroup); + SET_VALUE("scheme", scheme); + SET_VALUE("vfatSafe", vfatSafe); + SET_VALUE("asciiOnly", asciiOnly); + SET_VALUE("ignoreThe", ignoreThe); + SET_VALUE("replaceSpaces", replaceSpaces); + #ifdef ENABLE_DEVICES_SUPPORT + if (!isMpd) { + SET_VALUE("fixVariousArtists", fixVariousArtists); + SET_VALUE("transcoderCodec", transcoderCodec); + SET_VALUE("transcoderValue", transcoderValue); + SET_VALUE("transcoderWhenDifferent", transcoderWhenDifferent); } #endif + CFG_SYNC; + + #ifndef ENABLE_KDE_SUPPORT + cfg.endGroup(); + #endif + if (isMpd && HAS_GROUP(constMpdGroup)) { + REMOVE_GROUP(constMpdGroup); + } } QString DeviceOptions::clean(const QString &str) const diff --git a/devices/deviceoptions.h b/devices/deviceoptions.h index 298695952..077dad136 100644 --- a/devices/deviceoptions.h +++ b/devices/deviceoptions.h @@ -25,7 +25,8 @@ #define DEVICE_OPTIONS_H #include -#ifdef ENABLE_KDE_SUPPORT +#include "config.h" +#ifdef ENABLE_DEVICES_SUPPORT #include "encoders.h" #endif @@ -51,7 +52,7 @@ struct DeviceOptions { bool operator==(const DeviceOptions &o) const { return vfatSafe==o.vfatSafe && asciiOnly==o.asciiOnly && ignoreThe==o.ignoreThe && replaceSpaces==o.replaceSpaces && scheme==o.scheme - #ifdef ENABLE_KDE_SUPPORT + #ifdef ENABLE_DEVICES_SUPPORT && fixVariousArtists==o.fixVariousArtists && useCache==o.useCache && transcoderCodec==o.transcoderCodec && autoScan==o.autoScan && (transcoderCodec.isEmpty() || (transcoderValue==o.transcoderValue && transcoderWhenDifferent==o.transcoderWhenDifferent)) @@ -70,7 +71,7 @@ struct DeviceOptions { bool asciiOnly; bool ignoreThe; bool replaceSpaces; - #ifdef ENABLE_KDE_SUPPORT + #ifdef ENABLE_DEVICES_SUPPORT bool fixVariousArtists; QString transcoderCodec; int transcoderValue; diff --git a/devices/devicepropertieswidget.cpp b/devices/devicepropertieswidget.cpp index ede204298..740e4340c 100644 --- a/devices/devicepropertieswidget.cpp +++ b/devices/devicepropertieswidget.cpp @@ -25,8 +25,6 @@ #include "filenameschemedialog.h" #include "covers.h" #include "localize.h" -#include -#include #include #include @@ -145,7 +143,7 @@ void DevicePropertiesWidget::update(const QString &path, const QString &coverNam transcoderFrame->setVisible(false); } else { foreach (const Encoders::Encoder &e, encs) { - transcoderName->addItem(i18n("Transcode to \"%1\"", e.name), e.codec); + transcoderName->addItem(i18n("Transcode to \"%1\"").arg(e.name), e.codec); } if (opts.transcoderCodec.isEmpty()) { diff --git a/devices/devicespage.cpp b/devices/devicespage.cpp index b22507f08..c42da8634 100644 --- a/devices/devicespage.cpp +++ b/devices/devicespage.cpp @@ -33,9 +33,8 @@ #include #include #ifdef ENABLE_KDE_SUPPORT -#include -#include #include +#include #else #include #endif @@ -57,27 +56,15 @@ DevicesPage::DevicesPage(MainWindow *p) { setupUi(this); - configureAction = p->actionCollection()->addAction("configuredevice"); - configureAction->setText(i18n("Configure Device")); - configureAction->setIcon(QIcon::fromTheme("configure")); - refreshAction = p->actionCollection()->addAction("refreshdevice"); - refreshAction->setText(i18n("Refresh Device")); - refreshAction->setIcon(QIcon::fromTheme("view-refresh")); - copyAction = p->actionCollection()->addAction("copytolibrary"); - copyAction->setText(i18n("Copy To Library")); - copyAction->setIcon(QIcon::fromTheme("document-import")); + configureAction = p->createAction("configuredevice", i18n("Configure Device"), "configure"); + refreshAction = p->createAction("refreshdevice", i18n("Refresh Device"), "view-refresh"); + copyAction = p->createAction("copytolibrary", i18n("Copy To Library"), "document-import"); copyToLibraryButton->setDefaultAction(copyAction); - syncAction = p->actionCollection()->addAction("syncdevice"); - syncAction->setText(i18n("Sync")); - syncAction->setIcon(QIcon::fromTheme("folder-sync")); + syncAction = p->createAction("syncdevice", i18n("Sync"), "folder-sync"); connect(syncAction, SIGNAL(triggered()), this, SLOT(sync())); #ifdef ENABLE_REMOTE_DEVICES - forgetDeviceAction=p->actionCollection()->addAction("forgetdevice"); - forgetDeviceAction->setText(i18n("Forget Device")); - forgetDeviceAction->setIcon(QIcon::fromTheme("list-remove")); - toggleDeviceAction=p->actionCollection()->addAction("toggledevice"); - toggleDeviceAction->setText(i18n("Toggle Device")); - toggleDeviceAction->setIcon(QIcon::fromTheme("network-connect")); + forgetDeviceAction=p->createAction("forgetdevice", i18n("Forget Device"), "list-remove"); + toggleDeviceAction=p->createAction("toggledevice", i18n("Toggle Device"), "network-connect"); connect(forgetDeviceAction, SIGNAL(triggered()), this, SLOT(forgetRemoteDevice())); connect(toggleDeviceAction, SIGNAL(triggered()), this, SLOT(toggleDevice())); #endif @@ -117,9 +104,7 @@ DevicesPage::DevicesPage(MainWindow *p) menu->addAction(refreshAction); menu->addSeparator(); #ifdef ENABLE_REMOTE_DEVICES - KAction *addRemote=p->actionCollection()->addAction("adddevice"); - addRemote->setText(i18n("Add Device")); - addRemote->setIcon(QIcon::fromTheme("network-server")); + Action *addRemote=p->createAction("adddevice", i18n("Add Device"), "network-server"); connect(addRemote, SIGNAL(triggered()), this, SLOT(addRemoteDevice())); menu->addAction(addRemote); menu->addAction(forgetDeviceAction); @@ -368,13 +353,13 @@ void DevicesPage::refreshDevice() bool full=true; if (dev->childCount() && Device::Mtp!=dev->devType()) { QString udi=dev->udi(); - switch (KMessageBox::questionYesNoCancel(this, i18n("

Which type of refresh do you wish to perform?

    " - "
  • Partial - Only new songs are scanned (quick)
  • " - "
  • Full - All songs are rescanned (slow)

"), - i18n("Refresh"), KGuiItem(i18n("Partial")), KGuiItem(i18n("Full")))) { - case KMessageBox::Yes: + switch (MessageBox::questionYesNoCancel(this, i18n("

Which type of refresh do you wish to perform?

    " + "
  • Partial - Only new songs are scanned (quick)
  • " + "
  • Full - All songs are rescanned (slow)

"), + i18n("Refresh"), KGuiItem(i18n("Partial")), KGuiItem(i18n("Full")))) { + case MessageBox::Yes: full=false; - case KMessageBox::No: + case MessageBox::No: break; default: return; diff --git a/devices/devicespage.h b/devices/devicespage.h index 184e7a0ff..c64657fe7 100644 --- a/devices/devicespage.h +++ b/devices/devicespage.h @@ -33,8 +33,6 @@ #include "remotefsdevice.h" #endif -class KAction; - class DevicesPage : public QWidget, public Ui::DevicesPage { Q_OBJECT @@ -73,14 +71,14 @@ Q_SIGNALS: private: MainWindow *mw; MusicLibraryProxyModel proxy; - KAction *configureAction; - KAction *refreshAction; - KAction *copyAction; + Action *configureAction; + Action *refreshAction; + Action *copyAction; #ifdef ENABLE_REMOTE_DEVICES - KAction *forgetDeviceAction; - KAction *toggleDeviceAction; + Action *forgetDeviceAction; + Action *toggleDeviceAction; #endif - KAction *syncAction; + Action *syncAction; QSet genres; }; diff --git a/devices/encoders.cpp b/devices/encoders.cpp index 66a4f58c6..e58b09713 100644 --- a/devices/encoders.cpp +++ b/devices/encoders.cpp @@ -25,7 +25,6 @@ #include "encoders.h" #include "utils.h" #include "localize.h" -#include #include #include @@ -42,9 +41,9 @@ static void init() if (!initialised) { initialised=true; - ffmpeg=KStandardDirs::findExe("ffmpeg"); + ffmpeg=Utils::findExe("ffmpeg"); if (ffmpeg.isEmpty()) { - ffmpeg=KStandardDirs::findExe("avconv"); + ffmpeg=Utils::findExe("avconv"); usingAvconv=true; } if (ffmpeg.isEmpty()) { @@ -81,17 +80,17 @@ static void init() QLatin1String("libfaac"), QLatin1String("-aq"), i18n("Expected average bitrate for variable bitrate encoding"), - QList() << Setting(i18n(vbr, 25), 30) - << Setting(i18n(vbr, 50), 55) - << Setting(i18n(vbr, 70), 80) - << Setting(i18n(vbr, 90), 105) - << Setting(i18n(vbr, 120), 125) - << Setting(i18n(vbr, 150), 155) - << Setting(i18n(vbr, 170), 180) - << Setting(i18n(vbr, 180), 205) - << Setting(i18n(vbr, 190), 230) - << Setting(i18n(vbr, 200), 255) - << Setting(i18n(vbr, 210), 280), + QList() << Setting(i18n(vbr).arg(25), 30) + << Setting(i18n(vbr).arg(50), 55) + << Setting(i18n(vbr).arg(70), 80) + << Setting(i18n(vbr).arg(90), 105) + << Setting(i18n(vbr).arg(120), 125) + << Setting(i18n(vbr).arg(150), 155) + << Setting(i18n(vbr).arg(170), 180) + << Setting(i18n(vbr).arg(180), 205) + << Setting(i18n(vbr).arg(190), 230) + << Setting(i18n(vbr).arg(200), 255) + << Setting(i18n(vbr).arg(210), 280), i18n("Smaller file"), i18n("Better sound quality"), 5)); @@ -172,16 +171,16 @@ static void init() QLatin1String("libmp3lame"), QLatin1String("-aq"), i18n("Expected average bitrate for variable bitrate encoding"), - QList() << Setting(i18n(vbr, 80), 9) - << Setting(i18n(vbr, 100), 8) - << Setting(i18n(vbr, 120), 7) - << Setting(i18n(vbr, 140), 6) - << Setting(i18n(vbr, 160), 5) - << Setting(i18n(vbr, 175), 4) - << Setting(i18n(vbr, 190), 3) - << Setting(i18n(vbr, 205), 2) - << Setting(i18n(vbr, 220), 1) - << Setting(i18n(vbr, 240), 0), + QList() << Setting(i18n(vbr).arg(80), 9) + << Setting(i18n(vbr).arg(100), 8) + << Setting(i18n(vbr).arg(120), 7) + << Setting(i18n(vbr).arg(140), 6) + << Setting(i18n(vbr).arg(160), 5) + << Setting(i18n(vbr).arg(175), 4) + << Setting(i18n(vbr).arg(190), 3) + << Setting(i18n(vbr).arg(205), 2) + << Setting(i18n(vbr).arg(220), 1) + << Setting(i18n(vbr).arg(240), 0), i18n("Smaller file"), i18n("Better sound quality"), 4)); @@ -214,18 +213,18 @@ static void init() QLatin1String("libvorbis"), QLatin1String("-aq"), i18n("Quality rating"), - QList() << Setting(i18n(quality, -1, 45), -1) - << Setting(i18n(quality, 0, 64), 0) - << Setting(i18n(quality, 1, 80), 1) - << Setting(i18n(quality, 2, 96), 2) - << Setting(i18n(quality, 3, 112), 3) - << Setting(i18n(quality, 4, 128), 4) - << Setting(i18n(quality, 5, 160), 5) - << Setting(i18n(quality, 6, 192), 6) - << Setting(i18n(quality, 7, 224), 7) - << Setting(i18n(quality, 8, 256), 8) - << Setting(i18n(quality, 9, 320), 9) - << Setting(i18n(quality, 10, 500), 10), + QList() << Setting(i18n(quality).arg(-1).arg(45), -1) + << Setting(i18n(quality).arg(0).arg(64), 0) + << Setting(i18n(quality).arg(1).arg(80), 1) + << Setting(i18n(quality).arg(2).arg(96), 2) + << Setting(i18n(quality).arg(3).arg(112), 3) + << Setting(i18n(quality).arg(4).arg(128), 4) + << Setting(i18n(quality).arg(5).arg(160), 5) + << Setting(i18n(quality).arg(6).arg(192), 6) + << Setting(i18n(quality).arg(7).arg(224), 7) + << Setting(i18n(quality).arg(8).arg(256), 8) + << Setting(i18n(quality).arg(9).arg(320), 9) + << Setting(i18n(quality).arg(10).arg(500), 10), i18n("Smaller file"), i18n("Better sound quality"), 6)); @@ -251,14 +250,14 @@ static void init() QLatin1String("wmav2"), QLatin1String("-ab"), i18n("Bitrate"), - QList() << Setting(i18n(cbr, 64), 65*1000) - << Setting(i18n(cbr, 80), 75*1000) - << Setting(i18n(cbr, 96), 88*1000) - << Setting(i18n(cbr, 112), 106*1000) - << Setting(i18n(cbr, 136), 133*1000) - << Setting(i18n(cbr, 182), 180*1000) - << Setting(i18n(cbr, 275), 271*1000) - << Setting(i18n(cbr, 550), 545*1000), + QList() << Setting(i18n(cbr).arg(64), 65*1000) + << Setting(i18n(cbr).arg(80), 75*1000) + << Setting(i18n(cbr).arg(96), 88*1000) + << Setting(i18n(cbr).arg(112), 106*1000) + << Setting(i18n(cbr).arg(136), 133*1000) + << Setting(i18n(cbr).arg(182), 180*1000) + << Setting(i18n(cbr).arg(275), 271*1000) + << Setting(i18n(cbr).arg(550), 545*1000), i18n("Smaller file"), i18n("Better sound quality"), 4)); diff --git a/devices/filejob.cpp b/devices/filejob.cpp new file mode 100644 index 000000000..621788a70 --- /dev/null +++ b/devices/filejob.cpp @@ -0,0 +1,147 @@ +/* + * Cantata + * + * Copyright (c) 2011-2012 Craig Drummond + * + * ---- + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "filejob.h" +#include "utils.h" +#include +#include +#include + +#ifdef ENABLE_KDE_SUPPORT +#include +K_GLOBAL_STATIC(FileScheduler, instance) +#endif + +FileScheduler * FileScheduler::self() +{ + #ifdef ENABLE_KDE_SUPPORT + return instance; + #else + static FileScheduler *instance=0; + if(!instance) { + instance=new FileScheduler; + } + return instance; + #endif +} + +FileScheduler::FileScheduler() + : thread(0) +{ +} + +void FileScheduler::addJob(FileJob *job) +{ + if (!thread) { + thread=new QThread(); + moveToThread(thread); + thread->start(); + } + job->moveToThread(thread); + QTimer::singleShot(0, job, SLOT(start())); +} + +void FileScheduler::stop() +{ + if (thread) { + Utils::stopThread(thread); + thread=0; + } +} + +void FileJob::setPercent(int pc) +{ + if (pc!=progressPercent) { + progressPercent=pc; + emit percent(progressPercent); + } +} + +static const int constChunkSize=32*1024; + +void CopyJob::start() +{ + QFile src(srcFile); + + if (!src.open(QIODevice::ReadOnly)) { + emit result(StatusFailed); + return; + } + + QFile dest(destFile); + if (!dest.open(QIODevice::WriteOnly)) { + emit result(StatusFailed); + return; + } + + char buffer[constChunkSize]; + qint64 totalBytes = src.size(); + qint64 readPos = 0; + qint64 bytesRead = 0; + + do { + if (stopRequested) { + emit result(StatusCancelled); + return; + } + bytesRead = src.read(buffer, constChunkSize); + readPos+=bytesRead; + if (bytesRead<0) { + emit result(StatusFailed); + return; + } + + if (stopRequested) { + emit result(StatusCancelled); + return; + } + + qint64 writePos=0; + do { + qint64 bytesWritten = dest.write(&buffer[writePos], bytesRead - writePos); + if (stopRequested) { + emit result(StatusCancelled); + return; + } + if (-1==bytesWritten) { + emit result(StatusFailed); + return; + } + writePos+=bytesWritten; + } while (writePos + * + * ---- + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef FILE_JOB_H +#define FILE_JOB_H + +#include + +class QThread; +class FileJob; + +class FileScheduler : public QObject +{ + Q_OBJECT +public: + static FileScheduler * self(); + + FileScheduler(); + void addJob(FileJob *job); + void stop(); +private: + QThread *thread; +}; + +class FileJob : public QObject +{ + Q_OBJECT + +public: + enum Status { + StatusOk, + StatusFailed, + StatusCancelled + }; + + FileJob() + : stopRequested(false) + , progressPercent(0) { + FileScheduler::self()->addJob(this); + } + virtual ~FileJob() { } + + void setPercent(int pc); + bool wasStarted() const { return 0!=progressPercent && 100!=progressPercent; } + +Q_SIGNALS: + void percent(int pc); + void result(int status); + +public: + virtual void stop() { stopRequested=true; } + +protected Q_SLOTS: + virtual void start()=0; + +protected: + bool stopRequested; + int progressPercent; +}; + +class CopyJob : public FileJob +{ +public: + CopyJob(const QString &src, const QString &dest) + : srcFile(src) + , destFile(dest) { + } +private: + void start(); +private: + QString srcFile; + QString destFile; +}; + +class DeleteJob : public FileJob +{ +public: + DeleteJob(const QString &file) + : fileName(file) { + } +private: + void start(); +private: + QString fileName; +}; + +#endif diff --git a/devices/filetyperesolver.cpp b/devices/filetyperesolver.cpp index dcc0124ef..21305175d 100644 --- a/devices/filetyperesolver.cpp +++ b/devices/filetyperesolver.cpp @@ -25,9 +25,9 @@ #include #include -// #include +#ifdef ENABLE_KDE_SUPPORT #include - +#endif #ifdef TAGLIB_EXTRAS_FOUND #include #include @@ -52,101 +52,90 @@ TagLib::File *Meta::Tag::FileTypeResolver::createFile(TagLib::FileName fileName, { TagLib::File* result = 0; - QString fn = QFile::decodeName( fileName ); - QString suffix = QFileInfo( fn ).suffix(); - KMimeType::Ptr mimetype = KMimeType::findByPath( fn ); + QString fn = QFile::decodeName(fileName); + QString suffix = QFileInfo(fn).suffix(); + + #ifdef ENABLE_KDE_SUPPORT + KMimeType::Ptr mimetype = KMimeType::findByPath(fn); // -- check by mime type - if( mimetype->is( QLatin1String("audio/mpeg") ) - || mimetype->is( QLatin1String("audio/x-mpegurl") ) - || mimetype->is( QLatin1String("audio/mpeg") )) - { + if (mimetype->is(QLatin1String("audio/mpeg")) || mimetype->is(QLatin1String("audio/x-mpegurl")) + || mimetype->is(QLatin1String("audio/mpeg"))) { result = new TagLib::MPEG::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/mp4") ) - || mimetype->is( QLatin1String("video/mp4") ) ) - { + else if (mimetype->is(QLatin1String("audio/mp4")) || mimetype->is(QLatin1String("video/mp4"))) { result = new TagLib::MP4::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/x-ms-wma") ) - /*|| mimetype->is( QLatin1String("video/x-ms-asf") ) - || mimetype->is( QLatin1String("video/x-msvideo") ) - || mimetype->is( QLatin1String("video/x-ms-wmv") )*/ ) - { + else if (mimetype->is(QLatin1String("audio/x-ms-wma")) /*|| mimetype->is(QLatin1String("video/x-ms-asf")) + || mimetype->is(QLatin1String("video/x-msvideo")) || mimetype->is(QLatin1String("video/x-ms-wmv"))*/) { result = new TagLib::ASF::File(fileName, readProperties, propertiesStyle); } -#ifdef TAGLIB_EXTRAS_FOUND - else if( mimetype->is( QLatin1String("audio/vnd.rn-realaudio") ) - || mimetype->is( QLatin1String("audio/x-pn-realaudioplugin") ) - /*|| mimetype->is( QLatin1String("audio/vnd.rn-realvideo") )*/ ) - { + #ifdef TAGLIB_EXTRAS_FOUND + else if (mimetype->is(QLatin1String("audio/vnd.rn-realaudio")) || mimetype->is(QLatin1String("audio/x-pn-realaudioplugin")) + /*|| mimetype->is(QLatin1String("audio/vnd.rn-realvideo"))*/) { result = new TagLibExtras::RealMedia::File(fileName, readProperties, propertiesStyle); } -#endif - else if( mimetype->is( QLatin1String("audio/x-vorbis+ogg") ) ) - { + #endif + else if (mimetype->is(QLatin1String("audio/x-vorbis+ogg"))) { result = new TagLib::Ogg::Vorbis::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/x-flac+ogg") ) ) - { + else if (mimetype->is(QLatin1String("audio/x-flac+ogg"))) { result = new TagLib::Ogg::FLAC::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/x-aiff") ) ) - { + else if (mimetype->is(QLatin1String("audio/x-aiff"))) { result = new TagLib::RIFF::AIFF::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/x-flac") ) ) - { + else if (mimetype->is(QLatin1String("audio/x-flac"))) { result = new TagLib::FLAC::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/x-musepack") ) ) - { + else if (mimetype->is(QLatin1String("audio/x-musepack"))) { result = new TagLib::MPC::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/x-wav") ) ) - { + else if (mimetype->is(QLatin1String("audio/x-wav"))) { result = new TagLib::RIFF::WAV::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/x-wavpack") ) ) - { + else if (mimetype->is(QLatin1String("audio/x-wavpack"))) { result = new TagLib::WavPack::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/x-tta") ) ) - { + else if (mimetype->is(QLatin1String("audio/x-tta"))) { result = new TagLib::TrueAudio::File(fileName, readProperties, propertiesStyle); } - else if( mimetype->is( QLatin1String("audio/x-speex") ) - || mimetype->is( QLatin1String("audio/x-speex+ogg") ) ) - { + else if (mimetype->is(QLatin1String("audio/x-speex")) || mimetype->is(QLatin1String("audio/x-speex+ogg"))) { result = new TagLib::TrueAudio::File(fileName, readProperties, propertiesStyle); } // -- check by extension - else if( suffix == QLatin1String("m4a") - || suffix == QLatin1String("m4b") - || suffix == QLatin1String("m4p") - || suffix == QLatin1String("mp4") - /*|| suffix == QLatin1String("m4v") - || suffix == QLatin1String("mp4v") */) - { + #else // ENABLE_KDE_SUPPORT + if (suffix == QLatin1String("mp3")) { + result = new TagLib::MPEG::File(fileName, readProperties, propertiesStyle); + } else if (suffix == QLatin1String("ogg") || suffix == QLatin1String("flac")) { + result = new TagLib::Ogg::Vorbis::File(fileName, readProperties, propertiesStyle); + if (!result->isValid()) { + delete result; + result = new TagLib::Ogg::FLAC::File(fileName, readProperties, propertiesStyle); + } + } else if (suffix == QLatin1String("wma")) { + result = new TagLib::ASF::File(fileName, readProperties, propertiesStyle); + } + #endif // + else if (suffix == QLatin1String("m4a") || suffix == QLatin1String("m4b") + || suffix == QLatin1String("m4p") || suffix == QLatin1String("mp4") + /*|| suffix == QLatin1String("m4v") || suffix == QLatin1String("mp4v") */) { result = new TagLib::MP4::File(fileName, readProperties, propertiesStyle); } - else if( suffix == QLatin1String("wav") ) - { + else if (suffix == QLatin1String("wav")) { result = new TagLib::RIFF::WAV::File(fileName, readProperties, propertiesStyle); } - else if( suffix == QLatin1String("wma") - /*|| suffix == QLatin1String("asf")*/ ) - { + else if (suffix == QLatin1String("wma") /*|| suffix == QLatin1String("asf")*/) { result = new TagLib::ASF::File(fileName, readProperties, propertiesStyle); } // #ifndef Q_OS_WIN -// if( !result ) +// if (!result) // qDebug() << "kmimetype filetype guessing failed for" << fileName; // #endif - if( result && !result->isValid() ) { + if (result && !result->isValid()) { delete result; result = 0; } diff --git a/devices/freespaceinfo.cpp b/devices/freespaceinfo.cpp new file mode 100644 index 000000000..1bc83eed9 --- /dev/null +++ b/devices/freespaceinfo.cpp @@ -0,0 +1,87 @@ +/* + * Cantata + * + * Copyright (c) 2011-2012 Craig Drummond + * + * ---- + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "freespaceinfo.h" +#ifdef ENABLE_KDE_SUPPORT +#include +#elif defined(Q_OS_UNIX) +#include +#elif defined Q_OS_WIN +#include "windows.h" +#endif + +FreeSpaceInfo::FreeSpaceInfo(const QString &path) + : location(path) + , isDirty(true) + , totalSize(0) + , usedSpace(0) +{ +} + +void FreeSpaceInfo::setPath(const QString &path) +{ + if (location!=path) { + location=path; + isDirty=true; + } +} + +qulonglong FreeSpaceInfo::size() +{ + if (isDirty) { + update(); + } + return totalSize; +} + +qulonglong FreeSpaceInfo::used() +{ + if (isDirty) { + update(); + } + return usedSpace; +} + +void FreeSpaceInfo::update() +{ + #ifdef ENABLE_KDE_SUPPORT + KDiskFreeSpaceInfo inf=KDiskFreeSpaceInfo::freeSpaceInfo(location); + totalSize=inf.size(); + usedSpace=inf.used(); + #elif defined(Q_OS_UNIX) + struct statvfs fs_info; + if (0==statvfs(location.toLocal8Bit().constData(), &fs_info)) { + totalSize=quint64(fs_info.f_blocks) * quint64(fs_info.f_bsize); + usedSpace=totalSize-(quint64(fs_info.f_bavail) * quint64(fs_info.f_bsize)); + } + #elif defined(Q_OS_WIN32) + _ULARGE_INTEGER totalRet; + _ULARGE_INTEGER freeRet; + if (0!=GetDiskFreeSpaceEx(QDir::toNativeSeparators(location).toLocal8Bit().constData(), &freeRet, &totalRet, NULL)) { + totalSize=totalRet.QuadPart; + usedSpace=totalRet.QuadPart-freeRet.QuadPart; + } + #endif + isDirty=false; +} + diff --git a/devices/freespaceinfo.h b/devices/freespaceinfo.h new file mode 100644 index 000000000..bf8f7b650 --- /dev/null +++ b/devices/freespaceinfo.h @@ -0,0 +1,49 @@ +/* + * Cantata + * + * Copyright (c) 2011-2012 Craig Drummond + * + * ---- + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef FREESPACEINFO_H +#define FREESPACEINFO_H + +#include + +class FreeSpaceInfo +{ +public: + FreeSpaceInfo(const QString &path=QString()); + + void setPath(const QString &path); + void setDirty() { isDirty=true; } + quint64 size(); + quint64 used(); + +private: + void update(); + +private: + QString location; + bool isDirty; + quint64 totalSize; + quint64 usedSpace; +}; + +#endif diff --git a/devices/fsdevice.cpp b/devices/fsdevice.cpp index d5aa4f73f..d3693c3e2 100644 --- a/devices/fsdevice.cpp +++ b/devices/fsdevice.cpp @@ -42,11 +42,6 @@ #include #include #include -#include -#include -#include -#include -#include static const QLatin1String constCantataCacheFile("/.cache.xml"); @@ -231,8 +226,7 @@ void FsDevice::addSong(const Song &s, bool overwrite) return; } - KUrl dest(destFile); - QDir dir(dest.directory()); + QDir dir(Utils::getDir(destFile)); if(!dir.exists() && !Utils::createDir(dir.absolutePath(), QString())) { emit actionStatus(DirCreationFaild); } @@ -240,15 +234,14 @@ void FsDevice::addSong(const Song &s, bool overwrite) currentSong=s; if (encoder.codec.isEmpty() || (opts.transcoderWhenDifferent && !encoder.isDifferent(s.file))) { transcoding=false; - KIO::FileCopyJob *job=KIO::file_copy(KUrl(s.file), dest, -1, KIO::HideProgressInfo|(overwrite ? KIO::Overwrite : KIO::DefaultFlags)); - connect(job, SIGNAL(result(KJob *)), SLOT(addSongResult(KJob *))); - connect(job, SIGNAL(percent(KJob *, unsigned long)), SLOT(percent(KJob *, unsigned long))); + CopyJob *job=new CopyJob(s.file, destFile); + connect(job, SIGNAL(result(int)), SLOT(addSongResult(int))); + connect(job, SIGNAL(percent(int)), SLOT(percent(int))); } else { transcoding=true; TranscodingJob *job=new TranscodingJob(encoder.params(opts.transcoderValue, s.file, destFile)); - connect(job, SIGNAL(result(KJob *)), SLOT(addSongResult(KJob *))); - connect(job, SIGNAL(percent(KJob *, unsigned long)), SLOT(percent(KJob *, unsigned long))); - job->start(); + connect(job, SIGNAL(result(int)), SLOT(addSongResult(int))); + connect(job, SIGNAL(percent(int)), SLOT(percent(int))); } } @@ -288,17 +281,17 @@ void FsDevice::copySongTo(const Song &s, const QString &baseDir, const QString & currentBaseDir=baseDir; currentMusicPath=musicPath; - KUrl dest(currentBaseDir+currentMusicPath); - QDir dir(dest.directory()); + QString dest(currentBaseDir+currentMusicPath); + QDir dir(Utils::getDir(dest)); if (!dir.exists() && !Utils::createDir(dir.absolutePath(), baseDir)) { emit actionStatus(DirCreationFaild); return; } currentSong=s; - KIO::FileCopyJob *job=KIO::file_copy(KUrl(source), dest, -1, KIO::HideProgressInfo|(overwrite ? KIO::Overwrite : KIO::DefaultFlags)); - connect(job, SIGNAL(result(KJob *)), SLOT(copySongToResult(KJob *))); - connect(job, SIGNAL(percent(KJob *, unsigned long)), SLOT(percent(KJob *, unsigned long))); + CopyJob *job=new CopyJob(source, dest); + connect(job, SIGNAL(result(int)), SLOT(copySongToResult(int))); + connect(job, SIGNAL(percent(int)), SLOT(percent(int))); } void FsDevice::removeSong(const Song &s) @@ -317,8 +310,8 @@ void FsDevice::removeSong(const Song &s) } currentSong=s; - KIO::SimpleJob *job=KIO::file_delete(KUrl(audioFolder+s.file), KIO::HideProgressInfo); - connect(job, SIGNAL(result(KJob *)), SLOT(removeSongResult(KJob *))); + DeleteJob *job=new DeleteJob(audioFolder+s.file); + connect(job, SIGNAL(result(int)), SLOT(removeSongResult(int))); } void FsDevice::cleanDirs(const QSet &dirs) @@ -328,28 +321,33 @@ void FsDevice::cleanDirs(const QSet &dirs) } } -void FsDevice::percent(KJob *job, unsigned long percent) +void FsDevice::percent(int percent) { if (jobAbortRequested && 100!=percent) { - job->kill(KJob::EmitResult); + FileJob *job=qobject_cast(sender()); + if (job) { + job->stop(); + } return; } emit progress(percent); } -void FsDevice::addSongResult(KJob *job) +void FsDevice::addSongResult(int status) { + spaceInfo.setDirty(); QString destFileName=opts.createFilename(currentSong); if (transcoding) { destFileName=encoder.changeExtension(destFileName); } if (jobAbortRequested) { - if (0!=job->percent() && 100!=job->percent() && QFile::exists(audioFolder+destFileName)) { + FileJob *job=qobject_cast(sender()); + if (job && job->wasStarted() && QFile::exists(audioFolder+destFileName)) { QFile::remove(audioFolder+destFileName); } return; } - if (job->error()) { + if (FileJob::StatusOk!=status) { emit actionStatus(transcoding ? TranscodeFailed : Failed); } else { QString sourceDir=MPDParseUtils::getDir(currentSong.file); @@ -367,15 +365,17 @@ void FsDevice::addSongResult(KJob *job) } } -void FsDevice::copySongToResult(KJob *job) +void FsDevice::copySongToResult(int status) { + spaceInfo.setDirty(); if (jobAbortRequested) { - if (0!=job->percent() && 100!=job->percent() && QFile::exists(currentBaseDir+currentMusicPath)) { + FileJob *job=qobject_cast(sender()); + if (job && job->wasStarted() && QFile::exists(currentBaseDir+currentMusicPath)) { QFile::remove(currentBaseDir+currentMusicPath); } return; } - if (job->error()) { + if (FileJob::StatusOk!=status) { emit actionStatus(Failed); } else { QString sourceDir=MPDParseUtils::getDir(currentSong.file); @@ -391,12 +391,13 @@ void FsDevice::copySongToResult(KJob *job) } } -void FsDevice::removeSongResult(KJob *job) +void FsDevice::removeSongResult(int status) { + spaceInfo.setDirty(); if (jobAbortRequested) { return; } - if (job->error()) { + if (FileJob::StatusOk!=status) { emit actionStatus(Failed); } else { removeSongFromList(currentSong); diff --git a/devices/fsdevice.h b/devices/fsdevice.h index 80bb313ee..25b604f45 100644 --- a/devices/fsdevice.h +++ b/devices/fsdevice.h @@ -27,7 +27,7 @@ #include "device.h" #include "song.h" #include "utils.h" -#include +#include "freespaceinfo.h" #include #include @@ -97,16 +97,17 @@ protected: protected Q_SLOTS: void cacheRead(); void libraryUpdated(); - void percent(KJob *job, unsigned long percent); - void addSongResult(KJob *job); - void copySongToResult(KJob *job); - void removeSongResult(KJob *job); + void percent(int percent); + void addSongResult(int status); + void copySongToResult(int status); + void removeSongResult(int status); protected: bool scanned; MusicScanner *scanner; QString audioFolder; QString coverFileName; + FreeSpaceInfo spaceInfo; }; #endif diff --git a/devices/mediadevicecache.cpp b/devices/mediadevicecache.cpp index 12caae9cb..a27cf593d 100644 --- a/devices/mediadevicecache.cpp +++ b/devices/mediadevicecache.cpp @@ -22,6 +22,7 @@ #include "mediadevicecache.h" +#ifdef ENABLE_KDE_SUPPORT #include #include #include @@ -35,10 +36,21 @@ #include #include #include - #include - #include +#else +#include "solid-lite/device.h" +#include "solid-lite/deviceinterface.h" +#include "solid-lite/devicenotifier.h" +#include "solid-lite/genericinterface.h" +#include "solid-lite/opticaldisc.h" +#include "solid-lite/portablemediaplayer.h" +#include "solid-lite/storageaccess.h" +#include "solid-lite/storagedrive.h" +#include "solid-lite/block.h" +#include "solid-lite/storagevolume.h" +#include +#endif #include #include @@ -57,14 +69,10 @@ MediaDeviceCache::MediaDeviceCache() : QObject() { DEBUG_BLOCK s_instance = this; - connect( Solid::DeviceNotifier::instance(), SIGNAL( deviceAdded( const QString & ) ), - this, SLOT( slotAddSolidDevice( const QString & ) ) ); - connect( Solid::DeviceNotifier::instance(), SIGNAL( deviceRemoved( const QString & ) ), - this, SLOT( slotRemoveSolidDevice( const QString & ) ) ); -// connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotTimeout())); - -// m_timer.setSingleShot(true); -// m_timer.start(1000); + connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(const QString &)), + this, SLOT(slotAddDevice(const QString &))); + connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(const QString &)), + this, SLOT(slotRemoveDevice(const QString &))); } MediaDeviceCache::~MediaDeviceCache() @@ -72,176 +80,144 @@ MediaDeviceCache::~MediaDeviceCache() s_instance = 0; } -void -MediaDeviceCache::refreshCache() +void MediaDeviceCache::refreshCache() { DEBUG_BLOCK m_type.clear(); m_name.clear(); - QList deviceList = Solid::Device::listFromType( Solid::DeviceInterface::PortableMediaPlayer ); - foreach( const Solid::Device &device, deviceList ) - { - if( device.as() ) - { + QList deviceList = Solid::Device::listFromType(Solid::DeviceInterface::PortableMediaPlayer); + foreach (const Solid::Device &device, deviceList) { + if (device.as()) { debug() << "Found Solid PMP that is also a StorageDrive, skipping"; continue; } debug() << "Found Solid::DeviceInterface::PortableMediaPlayer with udi = " << device.udi(); debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); - m_type[device.udi()] = MediaDeviceCache::SolidPMPType; + m_type[device.udi()] = MediaDeviceCache::PMPType; m_name[device.udi()] = device.vendor() + " - " + device.product(); } - deviceList = Solid::Device::listFromType( Solid::DeviceInterface::StorageAccess ); - foreach( const Solid::Device &device, deviceList ) + deviceList = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess); + foreach (const Solid::Device &device, deviceList) { debug() << "Found Solid::DeviceInterface::StorageAccess with udi = " << device.udi(); debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); const Solid::StorageAccess* ssa = device.as(); - if( ssa ) - { + if (ssa) { // Commented out - as we want a signal when any storage device is added/removed - so we can check for MPD dir accessibility. // device.cpp contains the check to ensure the device is a USB bevice before adding it to the list... -// if( (!device.parent().as() || Solid::StorageDrive::Usb!=device.parent().as()->bus()) && -// (!device.as() || Solid::StorageDrive::Usb!=device.as()->bus()) ) -// { +// if ((!device.parent().as() || Solid::StorageDrive::Usb!=device.parent().as()->bus()) && +// (!device.as() || Solid::StorageDrive::Usb!=device.as()->bus())) { // debug() << "Found Solid::DeviceInterface::StorageAccess that is not usb, skipping"; // continue; // } - if( !m_volumes.contains( device.udi() ) ) - { - connect( ssa, SIGNAL( accessibilityChanged(bool, const QString&) ), - this, SLOT( slotAccessibilityChanged(bool, const QString&) ) ); - m_volumes.append( device.udi() ); + if (!m_volumes.contains(device.udi())) { + connect(ssa, SIGNAL(accessibilityChanged(bool, const QString&)), + this, SLOT(slotAccessibilityChanged(bool, const QString&))); + m_volumes.append(device.udi()); } - if( ssa->isAccessible() ) - { - m_type[device.udi()] = MediaDeviceCache::SolidVolumeType; + if (ssa->isAccessible()) { + m_type[device.udi()] = MediaDeviceCache::VolumeType; m_name[device.udi()] = ssa->filePath(); m_accessibility[ device.udi() ] = true; - } - else - { + } else { m_accessibility[ device.udi() ] = false; debug() << "Solid device is not accessible, will wait until it is to consider it added."; } } } -// deviceList = Solid::Device::listFromType( Solid::DeviceInterface::StorageDrive ); -// foreach( const Solid::Device &device, deviceList ) -// { +// deviceList = Solid::Device::listFromType(Solid::DeviceInterface::StorageDrive); +// foreach (const Solid::Device &device, deviceList) { // debug() << "Found Solid::DeviceInterface::StorageDrive with udi = " << device.udi(); // debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); // -// if( device.as() ) -// { -// m_type[device.udi()] = MediaDeviceCache::SolidGenericType; +// if (device.as()) { +// m_type[device.udi()] = MediaDeviceCache::GenericType; // m_name[device.udi()] = device.vendor() + " - " + device.product(); // } // } -// deviceList = Solid::Device::listFromType( Solid::DeviceInterface::OpticalDisc ); -// foreach( const Solid::Device &device, deviceList ) -// { +// deviceList = Solid::Device::listFromType(Solid::DeviceInterface::OpticalDisc); +// foreach (const Solid::Device &device, deviceList) { // debug() << "Found Solid::DeviceInterface::OpticalDisc with udi = " << device.udi(); // debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); // // const Solid::OpticalDisc * opt = device.as(); // -// if ( opt && opt->availableContent() & Solid::OpticalDisc::Audio ) -// { +// if (opt && opt->availableContent() & Solid::OpticalDisc::Audio) { // debug() << "device is an Audio CD"; -// m_type[device.udi()] = MediaDeviceCache::SolidAudioCdType; +// m_type[device.udi()] = MediaDeviceCache::AudioCdType; // m_name[device.udi()] = device.vendor() + " - " + device.product(); // } // } // deviceList = Solid::Device::allDevices(); -// foreach( const Solid::Device &device, deviceList ) -// { -// if( const Solid::GenericInterface *generic = device.as() ) -// { -// if( m_type.contains( device.udi() ) ) +// foreach (const Solid::Device &device, deviceList) { +// if (const Solid::GenericInterface *generic = device.as()) { +// if (m_type.contains(device.udi())) // continue; // // const QMap properties = generic->allProperties(); -// if( !properties.contains("info.capabilities") ) +// if (!properties.contains("info.capabilities")) // continue; // // const QStringList capabilities = properties["info.capabilities"].toStringList(); -// if( !capabilities.contains("afc") ) +// if (!capabilities.contains("afc")) // continue; // // debug() << "Found AFC capable Solid::DeviceInterface::GenericInterface with udi = " << device.udi(); // debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); // -// m_type[device.udi()] = MediaDeviceCache::SolidGenericType; +// m_type[device.udi()] = MediaDeviceCache::GenericType; // m_name[device.udi()] = device.vendor() + " - " + device.product(); // } // } -// KConfigGroup config(KGlobal::config(), "PortableDevices" ); +// KConfigGroup config(KGlobal::config(), "PortableDevices"); // const QStringList manualDeviceKeys = config.entryMap().keys(); -// foreach( const QString &udi, manualDeviceKeys ) -// { -// if( udi.startsWith( "manual" ) ) -// { +// foreach (const QString &udi, manualDeviceKeys) { +// if (udi.startsWith("manual")) { // debug() << "Found manual device with udi = " << udi; // m_type[udi] = MediaDeviceCache::ManualType; -// m_name[udi] = udi.split( '|' )[1]; +// m_name[udi] = udi.split('|')[1]; // } // } } -void -MediaDeviceCache::slotAddSolidDevice( const QString &udi ) +void MediaDeviceCache::slotAddDevice(const QString &udi) { DEBUG_BLOCK - Solid::Device device( udi ); + Solid::Device device(udi); debug() << "Found new Solid device with udi = " << device.udi(); debug() << "Device name is = " << device.product() << " and was made by " << device.vendor(); Solid::StorageAccess *ssa = device.as(); - Solid::OpticalDisc * opt = device.as(); - if ( opt && opt->availableContent() & Solid::OpticalDisc::Audio ) - { + if (opt && opt->availableContent() & Solid::OpticalDisc::Audio) { debug() << "device is an Audio CD"; - m_type[udi] = MediaDeviceCache::SolidAudioCdType; + m_type[udi] = MediaDeviceCache::AudioCdType; m_name[udi] = device.vendor() + " - " + device.product(); - } - else if( ssa ) - { + } else if (ssa) { debug() << "volume is generic storage"; - if( !m_volumes.contains( device.udi() ) ) - { - connect( ssa, SIGNAL( accessibilityChanged(bool, const QString&) ), - this, SLOT( slotAccessibilityChanged(bool, const QString&) ) ); - m_volumes.append( device.udi() ); + if (!m_volumes.contains(device.udi())) { + connect(ssa, SIGNAL(accessibilityChanged(bool, const QString&)), + this, SLOT(slotAccessibilityChanged(bool, const QString&))); + m_volumes.append(device.udi()); } - if( ssa->isAccessible() ) - { - m_type[udi] = MediaDeviceCache::SolidVolumeType; + if (ssa->isAccessible()) { + m_type[udi] = MediaDeviceCache::VolumeType; m_name[udi] = ssa->filePath(); - } - else - { + } else { debug() << "storage volume is not accessible right now, not adding."; return; } - } - else if( device.is() ) - { + } else if (device.is()) { debug() << "device is a Storage drive, still need a volume"; - m_type[udi] = MediaDeviceCache::SolidGenericType; + m_type[udi] = MediaDeviceCache::GenericType; m_name[udi] = device.vendor() + " - " + device.product(); - } - else if( device.is() ) - { + } else if (device.is()) { debug() << "device is a PMP"; - m_type[udi] = MediaDeviceCache::SolidPMPType; + m_type[udi] = MediaDeviceCache::PMPType; m_name[udi] = device.vendor() + " - " + device.product(); - } - else if( const Solid::GenericInterface *generic = device.as() ) - { + } else if (const Solid::GenericInterface *generic = device.as()) { const QMap properties = generic->allProperties(); /* At least iPod touch 3G and iPhone 3G do not advertise AFC (Apple File * Connection) capabilities. Therefore we have to white-list them so that they are @@ -250,207 +226,88 @@ MediaDeviceCache::slotAddSolidDevice( const QString &udi ) * @see IpodConnectionAssistant::identify() for a quirk that is currently also * needed for proper identification of iPhone-like devices. */ - if ( !device.product().contains("iPod") && !device.product().contains("iPhone")) - { - if( !properties.contains("info.capabilities") ) - { + if (!device.product().contains("iPod") && !device.product().contains("iPhone")) { + if (!properties.contains("info.capabilities")) { debug() << "udi " << udi << " does not describe a portable media player or storage volume"; return; } const QStringList capabilities = properties["info.capabilities"].toStringList(); - if( !capabilities.contains("afc") ) - { + if (!capabilities.contains("afc")) { debug() << "udi " << udi << " does not describe a portable media player or storage volume"; return; } } debug() << "udi" << udi << "is AFC cabable (Apple mobile device)"; - m_type[udi] = MediaDeviceCache::SolidGenericType; + m_type[udi] = MediaDeviceCache::GenericType; m_name[udi] = device.vendor() + " - " + device.product(); - } - else - { + } else { debug() << "udi " << udi << " does not describe a portable media player or storage volume"; return; } - emit deviceAdded( udi ); + emit deviceAdded(udi); } -void -MediaDeviceCache::slotRemoveSolidDevice( const QString &udi ) +void MediaDeviceCache::slotRemoveDevice(const QString &udi) { DEBUG_BLOCK debug() << "udi is: " << udi; - Solid::Device device( udi ); - if( m_volumes.contains( udi ) ) - { - disconnect( device.as(), SIGNAL( accessibilityChanged(bool, const QString&) ), - this, SLOT( slotAccessibilityChanged(bool, const QString&) ) ); - m_volumes.removeAll( udi ); - emit deviceRemoved( udi ); + Solid::Device device(udi); + if (m_volumes.contains(udi)) { + disconnect(device.as(), SIGNAL(accessibilityChanged(bool, const QString&)), + this, SLOT(slotAccessibilityChanged(bool, const QString&))); + m_volumes.removeAll(udi); +// emit deviceRemoved(udi); } - if( m_type.contains( udi ) ) - { - m_type.remove( udi ); - m_name.remove( udi ); - emit deviceRemoved( udi ); - return; + if (m_type.contains(udi)) { + m_type.remove(udi); + m_name.remove(udi); +// emit deviceRemoved(udi); } debug() << "Odd, got a deviceRemoved at udi " << udi << " but it did not seem to exist in the first place..."; - emit deviceRemoved( udi ); + emit deviceRemoved(udi); } -// void MediaDeviceCache::slotTimeout() -// { -// KMountPoint::List possibleMountList = KMountPoint::possibleMountPoints(); -// KMountPoint::List currentMountList = KMountPoint::currentMountPoints(); -// QList deviceList = Solid::Device::listFromType( Solid::DeviceInterface::StorageAccess ); -// -// for (KMountPoint::List::iterator it = possibleMountList.begin(); it != possibleMountList.end(); ++it) { -// if ((*it)->mountType() == "nfs" || (*it)->mountType() == "nfs4" || -// (*it)->mountType() == "smb" || (*it)->mountType() == "cifs") { -// QString path = (*it)->mountPoint(); -// bool mounted = false; -// QString udi = QString(); -// -// foreach( const Solid::Device &device, deviceList ) -// { -// const Solid::StorageAccess* ssa = device.as(); -// if( ssa && path == ssa->filePath()) -// udi = device.udi(); -// } -// -// for (KMountPoint::List::iterator it2 = currentMountList.begin(); it2 != currentMountList.end(); ++it2) { -// if ( (*it)->mountType() == (*it2)->mountType() && -// (*it)->mountPoint() == (*it2)->mountPoint() ) { -// mounted = true; -// break; -// } -// } -// -// if ( m_accessibility[udi] != mounted ) { -// m_accessibility[udi] = mounted; -// slotAccessibilityChanged( mounted, udi); -// } -// } -// } -// -// m_timer.setSingleShot(true); -// m_timer.start(1000); -// } - -void -MediaDeviceCache::slotAccessibilityChanged( bool accessible, const QString &udi ) +void MediaDeviceCache::slotAccessibilityChanged(bool accessible, const QString &udi) { debug() << "accessibility of device " << udi << " has changed to accessible = " << (accessible ? "true":"false"); - if( accessible ) - { - Solid::Device device( udi ); - m_type[udi] = MediaDeviceCache::SolidVolumeType; + if (accessible) { + Solid::Device device(udi); + m_type[udi] = MediaDeviceCache::VolumeType; Solid::StorageAccess *ssa = device.as(); - if( ssa ) + if (ssa) { m_name[udi] = ssa->filePath(); - emit deviceAdded( udi ); + } + emit deviceAdded(udi); return; - } - else - { - if( m_type.contains( udi ) ) - { - m_type.remove( udi ); - m_name.remove( udi ); - emit deviceRemoved( udi ); + } else { + if (m_type.contains(udi)) { + m_type.remove(udi); + m_name.remove(udi); + emit deviceRemoved(udi); return; } debug() << "Got accessibility changed to false but was not there in the first place..."; } - emit accessibilityChanged( accessible, udi ); + emit accessibilityChanged(accessible, udi); } -MediaDeviceCache::DeviceType -MediaDeviceCache::deviceType( const QString &udi ) const +MediaDeviceCache::DeviceType MediaDeviceCache::deviceType(const QString &udi) const { - if( m_type.contains( udi ) ) - { + if (m_type.contains(udi)) { return m_type[udi]; } return MediaDeviceCache::InvalidType; } -const QString -MediaDeviceCache::deviceName( const QString &udi ) const +const QString MediaDeviceCache::deviceName(const QString &udi) const { - if( m_name.contains( udi ) ) - { + if (m_name.contains(udi)) { return m_name[udi]; } return "ERR_NO_NAME"; //Should never happen! } -const QString -MediaDeviceCache::device( const QString &udi ) const -{ - DEBUG_BLOCK - Solid::Device device( udi ); - Solid::Device parent( device.parent() ); - if( !parent.isValid() ) - { - debug() << udi << "has no parent, returning null string."; - return QString(); - } - - Solid::Block* sb = parent.as(); - if( !sb ) - { - debug() << parent.udi() << "failed to convert to Block, returning null string."; - return QString(); - } - - return sb->device(); -} - -bool -MediaDeviceCache::isGenericEnabled( const QString &udi ) const -{ - DEBUG_BLOCK - if( m_type[udi] != MediaDeviceCache::SolidVolumeType ) - { - debug() << "Not SolidVolumeType, returning false"; - return false; - } - Solid::Device device( udi ); - Solid::StorageAccess* ssa = device.as(); - if( !ssa || !ssa->isAccessible() ) - { - debug() << "Not able to convert to StorageAccess or not accessible, returning false"; - return false; - } - if( device.parent().as() ) - { - debug() << "Could convert parent to PortableMediaPlayer, returning true"; - return true; - } - if( QFile::exists( ssa->filePath() + QDir::separator() + ".is_audio_player" ) ) - { - return true; - } - return false; -} - -const QString -MediaDeviceCache::volumeMountPoint( const QString &udi ) const -{ - DEBUG_BLOCK - Solid::Device device( udi ); - Solid::StorageAccess* ssa = device.as(); - if( !ssa || !ssa->isAccessible() ) - { - debug() << "Not able to convert to StorageAccess or not accessible, returning empty"; - return QString(); - } - return ssa->filePath(); -} diff --git a/devices/mediadevicecache.h b/devices/mediadevicecache.h index 5f4cd8604..bc3a60897 100644 --- a/devices/mediadevicecache.h +++ b/devices/mediadevicecache.h @@ -27,55 +27,45 @@ #include #include #include -// #include - -namespace Solid { - class Device; -} class MediaDeviceCache : public QObject { Q_OBJECT - public: +public: - enum DeviceType { SolidPMPType, SolidVolumeType, ManualType, SolidAudioCdType, SolidGenericType, InvalidType }; + enum DeviceType { PMPType, VolumeType, ManualType, AudioCdType, GenericType, InvalidType }; - static MediaDeviceCache* self() { return s_instance ? s_instance : new MediaDeviceCache(); } + static MediaDeviceCache* self() { return s_instance ? s_instance : new MediaDeviceCache(); } - /** - * Creates a new MediaDeviceCache. - * - */ - MediaDeviceCache(); - ~MediaDeviceCache(); + /** + * Creates a new MediaDeviceCache. + * + */ + MediaDeviceCache(); + ~MediaDeviceCache(); - void refreshCache(); - const QStringList getAll() const { return m_type.keys(); } - MediaDeviceCache::DeviceType deviceType( const QString &udi ) const; - const QString deviceName( const QString &udi ) const; - const QString device( const QString & udi ) const; - bool isGenericEnabled( const QString &udi ) const; - const QString volumeMountPoint( const QString &udi ) const; + void refreshCache(); + const QStringList getAll() const { return m_type.keys(); } + MediaDeviceCache::DeviceType deviceType( const QString &udi ) const; + const QString deviceName( const QString &udi ) const; - Q_SIGNALS: - void deviceAdded( const QString &udi ); - void deviceRemoved( const QString &udi ); - void accessibilityChanged( bool accessible, const QString &udi ); +Q_SIGNALS: + void deviceAdded( const QString &udi ); + void deviceRemoved( const QString &udi ); + void accessibilityChanged( bool accessible, const QString &udi ); - public Q_SLOTS: - void slotAddSolidDevice( const QString &udi ); - void slotRemoveSolidDevice( const QString &udi ); - void slotAccessibilityChanged( bool accessible, const QString &udi ); -// void slotTimeout(); +public Q_SLOTS: + void slotAddDevice( const QString &udi ); + void slotRemoveDevice( const QString &udi ); + void slotAccessibilityChanged( bool accessible, const QString &udi ); - private: - QMap m_type; - QMap m_name; - QMap m_accessibility; - QStringList m_volumes; - static MediaDeviceCache* s_instance; -// QTimer m_timer; +private: + QMap m_type; + QMap m_name; + QMap m_accessibility; + QStringList m_volumes; + static MediaDeviceCache* s_instance; }; #endif /* AMAROK_MEDIADEVICECACHE_H */ diff --git a/devices/mtpdevice.cpp b/devices/mtpdevice.cpp index f0dac21ac..e72149a3b 100644 --- a/devices/mtpdevice.cpp +++ b/devices/mtpdevice.cpp @@ -37,14 +37,15 @@ #include "utils.h" #include "mpdparseutils.h" #include "localize.h" +#include "filejob.h" +#include "settings.h" #include #include #include -#include -#include -#include +#include +#ifdef ENABLE_KDE_SUPPORT #include -#include +#endif #include #include #include @@ -353,6 +354,7 @@ static char * createString(const QString &str) static LIBMTP_filetype_t mtpFileType(const Song &s) { + #ifdef ENABLE_KDE_SUPPORT KMimeType::Ptr mime=KMimeType::findByPath(s.file); if (mime->is("audio/mpeg")) { @@ -376,6 +378,29 @@ static LIBMTP_filetype_t mtpFileType(const Song &s) if (mime->is("audio/x-wav")) { return LIBMTP_FILETYPE_WAV; } + #else + if (s.file.endsWith(".mp3", Qt::CaseInsensitive)) { + return LIBMTP_FILETYPE_MP3; + } + if (s.file.endsWith(".ogg", Qt::CaseInsensitive)) { + return LIBMTP_FILETYPE_OGG; + } + if (s.file.endsWith(".wma", Qt::CaseInsensitive)) { + return LIBMTP_FILETYPE_WMA; + } + if (s.file.endsWith(".m4a", Qt::CaseInsensitive)) { + return LIBMTP_FILETYPE_M4A; // LIBMTP_FILETYPE_MP4 + } + if (s.file.endsWith(".aac", Qt::CaseInsensitive)) { + return LIBMTP_FILETYPE_AAC; + } + if (s.file.endsWith(".flac", Qt::CaseInsensitive)) { + return LIBMTP_FILETYPE_FLAC; + } + if (s.file.endsWith(".wav", Qt::CaseInsensitive)) { + return LIBMTP_FILETYPE_WAV; + } + #endif return LIBMTP_FILETYPE_UNDEF_AUDIO; } @@ -398,14 +423,15 @@ void MtpConnection::putSong(const Song &s, bool fixVa) } meta->item_id=0; QString fileName=song.file; - KTemporaryFile *temp=0; + QTemporaryFile *temp=0; if (fixVa) { // Need to 'workaround' broken various artists handling, so write to a temporary file first... - temp=new KTemporaryFile(); int index=song.file.lastIndexOf('.'); if (index>0) { - temp->setSuffix(song.file.mid(index)); + temp=new QTemporaryFile("cantata_XXXX"+song.file.mid(index)); + } else { + temp=new QTemporaryFile("cantata_XXXX"); } temp->setAutoRemove(false); if (temp->open()) { @@ -536,7 +562,10 @@ void MtpDevice::deviceDetails(const QString &s) serial=s; QString configKey=cfgKey(solidDev, serial); opts.load(configKey); - configured=KGlobal::config()->hasGroup(configKey); + #ifndef ENABLE_KDE_SUPPORT + QSettings cfg; + #endif + configured=HAS_GROUP(configKey); } } @@ -608,8 +637,7 @@ void MtpDevice::addSong(const Song &s, bool overwrite) if (!opts.transcoderWhenDifferent || encoder.isDifferent(s.file)) { deleteTemp(); - tempFile=new KTemporaryFile(); - tempFile->setSuffix("."+encoder.extension); + tempFile=new QTemporaryFile("cantata_XXXX"+encoder.extension); tempFile->setAutoRemove(false); if (!tempFile->open()) { @@ -624,8 +652,8 @@ void MtpDevice::addSong(const Song &s, bool overwrite) } transcoding=true; TranscodingJob *job=new TranscodingJob(encoder.params(opts.transcoderValue, s.file, destFile)); - connect(job, SIGNAL(result(KJob *)), SLOT(transcodeSongResult(KJob *))); - connect(job, SIGNAL(percent(KJob *, unsigned long)), SLOT(transcodePercent(KJob *, unsigned long))); + connect(job, SIGNAL(result(int)), SLOT(transcodeSongResult(int))); + connect(job, SIGNAL(percent(int)), SLOT(transcodePercent(int))); job->start(); currentSong.file=destFile; return; @@ -665,8 +693,8 @@ void MtpDevice::copySongTo(const Song &s, const QString &baseDir, const QString currentBaseDir=baseDir; currentMusicPath=musicPath; - KUrl dest(currentBaseDir+currentMusicPath); - QDir dir(dest.directory()); + QString dest(currentBaseDir+currentMusicPath); + QDir dir(Utils::getDir(dest)); if (!dir.exists() && !Utils::createDir(dir.absolutePath(), baseDir)) { emit actionStatus(DirCreationFaild); return; @@ -721,26 +749,28 @@ void MtpDevice::putSongStatus(bool ok, int id, const QString &file, bool fixedVa } } -void MtpDevice::transcodeSongResult(KJob *job) +void MtpDevice::transcodeSongResult(int status) { if (jobAbortRequested) { deleteTemp(); return; } - if (job->error()) { + if (FileJob::StatusOk!=status) { emit actionStatus(TranscodeFailed); } else { emit putSong(currentSong, needToFixVa); } } -void MtpDevice::transcodePercent(KJob *job, unsigned long percent) +void MtpDevice::transcodePercent(int percent) { if (jobAbortRequested) { - job->kill(KJob::EmitResult); // emit result so that temp file can be removed! + FileJob *job=qobject_cast(sender()); + if (job) { + job->stop(); + } return; } - Q_UNUSED(job) emit progress(percent/2); } @@ -802,7 +832,7 @@ QString MtpDevice::capacityString() return i18n("Not Connected"); } - return i18n("%1 free", KGlobal::locale()->formatByteSize(connection->capacity()-connection->usedSpace()), 1); + return i18n("%1 free").arg(Utils::formatByteSize(connection->capacity()-connection->usedSpace())); } qint64 MtpDevice::freeSpace() diff --git a/devices/mtpdevice.h b/devices/mtpdevice.h index e570be8cf..5910b260c 100644 --- a/devices/mtpdevice.h +++ b/devices/mtpdevice.h @@ -26,14 +26,17 @@ #include "device.h" #include "song.h" +#ifdef ENABLE_KDE_SUPPORT #include +#else +#include "solid-lite/portablemediaplayer.h" +#endif #include class MusicLibraryItemRoot; class QThread; class MtpDevice; -class KJob; -class KTemporaryFile; +class QTemporaryFile; class MtpConnection : public QObject { @@ -134,8 +137,8 @@ private Q_SLOTS: void libraryUpdated(); void rescan(bool full=true); void putSongStatus(bool ok, int id, const QString &file, bool fixedVa); - void transcodeSongResult(KJob *job); - void transcodePercent(KJob *job, unsigned long percent); + void transcodeSongResult(int status); + void transcodePercent(int percent); void emitProgress(unsigned long); void getSongStatus(bool ok); void delSongStatus(bool ok); @@ -149,7 +152,7 @@ private: Solid::PortableMediaPlayer *pmp; QThread *thread; MtpConnection *connection; - KTemporaryFile *tempFile; + QTemporaryFile *tempFile; Song currentSong; bool mtpUpdating; QString serial; diff --git a/devices/remotedevicepropertiesdialog.cpp b/devices/remotedevicepropertiesdialog.cpp index a964259a0..0055e79ef 100644 --- a/devices/remotedevicepropertiesdialog.cpp +++ b/devices/remotedevicepropertiesdialog.cpp @@ -27,9 +27,9 @@ #include "devicesmodel.h" #include "localize.h" #include "messagebox.h" +#include "icon.h" #include #include -#include RemoteDevicePropertiesDialog::RemoteDevicePropertiesDialog(QWidget *parent) : Dialog(parent) @@ -43,7 +43,7 @@ RemoteDevicePropertiesDialog::RemoteDevicePropertiesDialog(QWidget *parent) remoteProp=new RemoteDevicePropertiesWidget(tab); devProp=new DevicePropertiesWidget(tab); tab->addTab(remoteProp, QIcon::fromTheme("network-server"), i18n("Connection")); - tab->addTab(devProp, KIcon("cantata-view-media-library"), i18n("Music Library")); + tab->addTab(devProp, Icon("cantata-view-media-library"), i18n("Music Library")); setMainWidget(tab); } @@ -73,7 +73,7 @@ void RemoteDevicePropertiesDialog::slotButtonClicked(int button) case Ok: { RemoteFsDevice::Details d=remoteProp->details(); if (d.name!=remoteProp->origDetails().name && DevicesModel::self()->device(RemoteFsDevice::createUdi(d.name))) { - MessageBox::error(this, i18n("A remote device named \"%1\" already exists!\nPlease choose a different name", d.name)); + MessageBox::error(this, i18n("A remote device named \"%1\" already exists!\nPlease choose a different name").arg(d.name)); } else { emit updatedSettings(devProp->cover(), devProp->settings(), remoteProp->details()); accept(); diff --git a/devices/remotedevicepropertieswidget.cpp b/devices/remotedevicepropertieswidget.cpp index e47d781e4..ab63a9641 100644 --- a/devices/remotedevicepropertieswidget.cpp +++ b/devices/remotedevicepropertieswidget.cpp @@ -25,11 +25,12 @@ #include "filenameschemedialog.h" #include "covers.h" #include "localize.h" -#include -#include +#ifdef ENABLE_KDE_SUPPORT #include +#endif #include #include +#include #include "lineedit.h" #include "config.h" @@ -49,15 +50,19 @@ RemoteDevicePropertiesWidget::RemoteDevicePropertiesWidget(QWidget *parent) } type->addItem(i18n("Secure Shell (sshfs)"), (int)Type_SshFs); type->addItem(i18n("Locally Mounted Folder"), (int)Type_File); + #ifdef ENABLE_KDE_SUPPORT sshFolderButton->setIcon(QIcon::fromTheme("document-open")); fileFolder->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly); kioUrl->setMode(KFile::Directory|KFile::ExistingOnly); + #else + sshFolderButton->setVisible(false); + #endif } void RemoteDevicePropertiesWidget::update(const RemoteFsDevice::Details &d, bool create, bool isConnected) { - int t=d.url.isLocalFile() ? Type_File : Type_SshFs; - setEnabled(d.url.isLocalFile() || !isConnected); + int t=d.isLocalFile() ? Type_File : Type_SshFs; + setEnabled(d.isLocalFile() || !isConnected); infoLabel->setVisible(create); orig=d; name->setText(d.name); @@ -66,20 +71,26 @@ void RemoteDevicePropertiesWidget::update(const RemoteFsDevice::Details &d, bool sshHost->setText(QString()); sshUser->setText(QString()); fileFolder->setText(QString()); + #ifdef ENABLE_KDE_SUPPORT kioUrl->setUrl(KUrl()); + #else + kioUrl->setText(QString()); + #endif switch (t) { - case Type_SshFs: - sshFolder->setText(d.url.path()); - sshPort->setValue(d.url.port()); - sshHost->setText(d.url.host()); - sshUser->setText(d.url.user()); + case Type_SshFs: { + QUrl url(d.url); + sshFolder->setText(url.path()); + sshPort->setValue(url.port()); + sshHost->setText(url.host()); + sshUser->setText(url.userName()); break; + } case Type_File: - fileFolder->setText(d.url.path()); + fileFolder->setText(d.url); break; } - name->setEnabled(d.url.isLocalFile() || !isConnected); + name->setEnabled(d.isLocalFile() || !isConnected); connect(type, SIGNAL(currentIndexChanged(int)), this, SLOT(setType())); for (int i=1; icount(); ++i) { @@ -111,6 +122,7 @@ void RemoteDevicePropertiesWidget::setType() } } +#ifdef ENABLE_KDE_SUPPORT void RemoteDevicePropertiesWidget::browseSftpFolder() { RemoteFsDevice::Details det=details(); @@ -125,13 +137,16 @@ void RemoteDevicePropertiesWidget::browseSftpFolder() sshFolder->setText(url.path()); } } +#endif void RemoteDevicePropertiesWidget::checkSaveable() { RemoteFsDevice::Details det=details(); modified=det!=orig; saveable=!det.isEmpty(); - sshFolderButton->setEnabled(!det.url.host().isEmpty() && det.url.port()>0); + #ifdef ENABLE_KDE_SUPPORT + sshFolderButton->setEnabled(!det.url.isEmpty()); + #endif emit updated(); } @@ -147,14 +162,14 @@ RemoteFsDevice::Details RemoteDevicePropertiesWidget::details() QString u=sshUser->text().trimmed(); QString f=sshFolder->text().trimmed(); int p=sshPort->value(); - det.url=KUrl(RemoteFsDevice::constSshfsProtocol+QLatin1String("://")+ (u.isEmpty() ? QString() : (u+QChar('@'))) + det.url=QString(RemoteFsDevice::constSshfsProtocol+QLatin1String("://")+ (u.isEmpty() ? QString() : (u+QChar('@'))) + h + (p<=0 ? QString() : QString(QChar(':')+QString::number(p))) + (f.startsWith("/") ? f : (f.isEmpty() ? QString("/") : f))); break; } case Type_File: { QString f=fileFolder->text().trimmed(); - det.url=KUrl(QLatin1String("file://")+(f.startsWith("/") ? f : (f.isEmpty() ? QString("/") : f))); + det.url=QString(f.startsWith("/") ? f : (f.isEmpty() ? QString("/") : f)); break; } } diff --git a/devices/remotedevicepropertieswidget.h b/devices/remotedevicepropertieswidget.h index daeee1f3a..b786fa6a0 100644 --- a/devices/remotedevicepropertieswidget.h +++ b/devices/remotedevicepropertieswidget.h @@ -47,7 +47,9 @@ Q_SIGNALS: private Q_SLOTS: void checkSaveable(); void setType(); + #ifdef ENABLE_KDE_SUPPORT void browseSftpFolder(); + #endif private: RemoteFsDevice::Details orig; diff --git a/devices/remotedevicepropertieswidget.ui b/devices/remotedevicepropertieswidget.ui index 8623d1e7c..450ad9d98 100644 --- a/devices/remotedevicepropertieswidget.ui +++ b/devices/remotedevicepropertieswidget.ui @@ -142,7 +142,7 @@ - + @@ -159,7 +159,7 @@ - + @@ -207,9 +207,9 @@ - KUrlRequester - QFrame -
kurlrequester.h
+ DirRequester + QLineEdit +
dirrequester.h
LineEdit diff --git a/devices/remotefsdevice.cpp b/devices/remotefsdevice.cpp index 1f1118e8a..cf8ff053c 100644 --- a/devices/remotefsdevice.cpp +++ b/devices/remotefsdevice.cpp @@ -30,15 +30,15 @@ #include "network.h" #include "httpserver.h" #include "localize.h" +#include "settings.h" #include #include -#include -#include -#include -#include -#include +#include +#include +#ifdef ENABLE_KDE_SUPPORT #include #include +#endif #include #include @@ -46,70 +46,90 @@ const QLatin1String RemoteFsDevice::constSshfsProtocol("cantata-sshfs"); static QString mountPoint(const RemoteFsDevice::Details &details, bool create) { - if (details.url.isLocalFile()) { - return details.url.path(); + if (details.isLocalFile()) { + return details.url; } return Network::cacheDir(QLatin1String("mount/")+details.name, create); } void RemoteFsDevice::Details::load(const QString &group) { - KConfigGroup grp(KGlobal::config(), group); - name=grp.readEntry("name", name); - url=grp.readEntry("url", url); + #ifdef ENABLE_KDE_SUPPORT + KConfigGroup cfg(KGlobal::config(), group); + #else + QSettings cfg; + cfg.beginGroup(group); + #endif + name=GET_STRING("name", name); + url=GET_STRING("url", url); + #ifdef ENABLE_KDE_SUPPORT if (url.isEmpty()) { // Old, pre 0.7.0 remote device... - QString folder=grp.readEntry("folder", QString()); + QString folder=GET_STRING("folder", QString()); if (!folder.isEmpty()) { - if (1==grp.readEntry("protocol", 0)) { - QString host=grp.readEntry("host", QString()); - QString user=grp.readEntry("user", QString()); - int port=grp.readEntry("port", 0); + if (1==GET_INT("protocol", 0)) { + QString host=GET_STRING("host", QString()); + QString user=GET_STRING("user", QString()); + int port=GET_INT("port", 0); - url=KUrl(RemoteFsDevice::constSshfsProtocol+QLatin1String("://")+ (user.isEmpty() ? QString() : (user+QChar('@'))) + url=RemoteFsDevice::constSshfsProtocol+QLatin1String("://")+ (user.isEmpty() ? QString() : (user+QChar('@'))) + host + (port<=0 ? QString() : QString(QChar(':')+QString::number(port))) - + (folder.startsWith("/") ? folder : (folder.isEmpty() ? QString("/") : folder))); + + (folder.startsWith("/") ? folder : (folder.isEmpty() ? QString("/") : folder)); } else { - url=KUrl(QLatin1String("file://")+(folder.startsWith("/") ? folder : (folder.isEmpty() ? QString("/") : folder))); + url=(folder.startsWith("/") ? folder : (folder.isEmpty() ? QString("/") : folder)); } } - grp.deleteEntry("protocol"); - grp.deleteEntry("folder"); - grp.deleteEntry("host"); - grp.deleteEntry("user"); - grp.deleteEntry("port"); - grp.writeEntry("url", url); + // These are in case of old (KDE-only) entries... + REMOVE_ENTRY("protocol"); + REMOVE_ENTRY("folder"); + REMOVE_ENTRY("host"); + REMOVE_ENTRY("user"); + REMOVE_ENTRY("port"); + SET_VALUE("url", url); } + if (url.startsWith("file://")) { + url=url.mid(7); + } + #endif } void RemoteFsDevice::Details::save(const QString &group) const { - KConfigGroup grp(KGlobal::config(), group); - grp.writeEntry("name", name); - grp.writeEntry("url", url); - grp.sync(); + #ifdef ENABLE_KDE_SUPPORT + KConfigGroup cfg(KGlobal::config(), group); + #else + QSettings cfg; + cfg.beginGroup(group); + #endif + SET_VALUE("name", name); + SET_VALUE("url", url); + CFG_SYNC; } - static const QLatin1String constCfgPrefix("RemoteDevice-"); static const QLatin1String constCfgKey("remoteDevices"); QList RemoteFsDevice::loadAll(DevicesModel *m) { QList devices; - KConfigGroup grp(KGlobal::config(), "General"); - QStringList names=grp.readEntry(constCfgKey, QStringList()); + #ifdef ENABLE_KDE_SUPPORT + KConfigGroup cfg(KGlobal::config(), "General"); + #else + QSettings cfg; + cfg.beginGroup("General"); + #endif + QStringList names=GET_STRINGLIST(constCfgKey, QStringList()); foreach (const QString &n, names) { Details d; d.load(constCfgPrefix+n); if (d.isEmpty() || d.name!=n) { - KGlobal::config()->deleteGroup(constCfgPrefix+n); - } else if (d.url.isLocalFile() || constSshfsProtocol==d.url.protocol()) { + REMOVE_GROUP(constCfgPrefix+n); + } else if (d.isLocalFile() || d.url.startsWith(constSshfsProtocol)) { devices.append(new RemoteFsDevice(m, d)); } } if (devices.count()!=names.count()) { - KGlobal::config()->sync(); + CFG_SYNC; } return devices; } @@ -119,15 +139,20 @@ Device * RemoteFsDevice::create(DevicesModel *m, const QString &cover, const Dev if (d.isEmpty()) { return false; } - KConfigGroup grp(KGlobal::config(), "General"); - QStringList names=grp.readEntry(constCfgKey, QStringList()); + #ifdef ENABLE_KDE_SUPPORT + KConfigGroup cfg(KGlobal::config(), "General"); + #else + QSettings cfg; + cfg.beginGroup("General"); + #endif + QStringList names=GET_STRINGLIST(constCfgKey, QStringList()); if (names.contains(d.name)) { return false; } names.append(d.name); - grp.writeEntry(constCfgKey, names); + SET_VALUE(constCfgKey, names); d.save(constCfgPrefix+d.name); - if (d.url.isLocalFile() || constSshfsProtocol==d.url.protocol()) { + if (d.isLocalFile() || d.url.startsWith(constSshfsProtocol)) { return new RemoteFsDevice(m, cover, options, d); } return 0; @@ -138,15 +163,20 @@ void RemoteFsDevice::remove(Device *dev) if (!dev || RemoteFs!=dev->devType()) { return; } - KConfigGroup grp(KGlobal::config(), "General"); - QStringList names=grp.readEntry(constCfgKey, QStringList()); + #ifdef ENABLE_KDE_SUPPORT + KConfigGroup cfg(KGlobal::config(), "General"); + #else + QSettings cfg; + cfg.beginGroup("General"); + #endif + QStringList names=GET_STRINGLIST(constCfgKey, QStringList()); RemoteFsDevice *rfs=qobject_cast(dev); QString name=rfs ? rfs->details.name : QString(); if (names.contains(name)) { names.removeAll(name); - KGlobal::config()->deleteGroup(dev->udi()); - grp.writeEntry(constCfgKey, names); - KGlobal::config()->sync(); + REMOVE_GROUP(dev->udi()); + SET_VALUE(constCfgKey, names); + CFG_SYNC; } if (rfs) { rfs->stopScanner(false); @@ -164,17 +194,22 @@ QString RemoteFsDevice::createUdi(const QString &n) void RemoteFsDevice::renamed(const QString &oldName, const QString &newName) { - KConfigGroup grp(KGlobal::config(), "General"); - QStringList names=grp.readEntry(constCfgKey, QStringList()); + #ifdef ENABLE_KDE_SUPPORT + KConfigGroup cfg(KGlobal::config(), "General"); + #else + QSettings cfg; + cfg.beginGroup("General"); + #endif + QStringList names=GET_STRINGLIST(constCfgKey, QStringList()); if (names.contains(oldName)) { names.removeAll(oldName); - KGlobal::config()->deleteGroup(createUdi(oldName)); + REMOVE_GROUP(createUdi(oldName)); } if (!names.contains(newName)) { names.append(newName); } - grp.writeEntry(constCfgKey, names); - KGlobal::config()->sync(); + SET_VALUE(constCfgKey, names); + CFG_SYNC; } RemoteFsDevice::RemoteFsDevice(DevicesModel *m, const QString &cover, const DeviceOptions &options, const Details &d) @@ -185,7 +220,7 @@ RemoteFsDevice::RemoteFsDevice(DevicesModel *m, const QString &cover, const Devi { coverFileName=cover; opts=options; - details.url.setPath(MPDParseUtils::fixPath(details.url.path())); + details.url=MPDParseUtils::fixPath(details.url); load(); mount(); } @@ -196,7 +231,7 @@ RemoteFsDevice::RemoteFsDevice(DevicesModel *m, const Details &d) , details(d) , proc(0) { - details.url.setPath(MPDParseUtils::fixPath(details.url.path())); + details.url=MPDParseUtils::fixPath(details.url); setup(); } @@ -229,18 +264,36 @@ void RemoteFsDevice::mount() emit error(i18n("Password prompting does not work when cantata is started from the commandline.")); return; } - if (KStandardDirs::findExe("ksshaskpass").isEmpty()) { - emit error(i18n("\"ksshaskpass\" is not installed! This is required for entering passwords")); + QStringList askPassList; + const char *env=qgetenv("KDE_FULL_SESSION"); + QString dm=env && 0==strcmp(env, "true") ? QLatin1String("KDE") : QString(qgetenv("XDG_CURRENT_DESKTOP")); + if (dm.isEmpty() || QLatin1String("KDE")==dm) { + askPassList << QLatin1String("ksshaskpass") << QLatin1String("ssh-askpass") << QLatin1String("ssh-askpass-gnome"); + } else { + askPassList << QLatin1String("ssh-askpass-gnome") << QLatin1String("ssh-askpass") << QLatin1String("ksshaskpass"); + } + + QString askPass; + foreach (const QString &ap, askPassList) { + askPass=Utils::findExe(ap); + if (!askPass.isEmpty()) { + break; + } + } + + if (askPass.isEmpty()) { + emit error(i18n("No suitable ssh-askpass applicaiton installed! This is required for entering passwords.")); return; } - cmd=KStandardDirs::findExe("sshfs"); + cmd=Utils::findExe("sshfs"); if (!cmd.isEmpty()) { if (!QDir(mountPoint(details, true)).entryList(QDir::NoDot|QDir::NoDotDot|QDir::AllEntries|QDir::Hidden).isEmpty()) { - emit error(i18n("Mount point (\"%1\") is not empty!", mountPoint(details, true))); + emit error(i18n("Mount point (\"%1\") is not empty!").arg(mountPoint(details, true))); return; } - args << details.url.user()+QChar('@')+details.url.host()+QChar(':')+details.url.path() << QLatin1String("-p") - << QString::number(details.url.port()) << mountPoint(details, true) + QUrl url(details.url); + args << url.userName()+QChar('@')+url.host()+QChar(':')+url.path() << QLatin1String("-p") + << QString::number(url.port()) << mountPoint(details, true) << QLatin1String("-o") << QLatin1String("ServerAliveInterval=15"); //<< QLatin1String("-o") << QLatin1String("Ciphers=arcfour"); } else { @@ -272,7 +325,7 @@ void RemoteFsDevice::unmount() if (!details.isLocalFile()) { QString mp=mountPoint(details, false); if (!mp.isEmpty()) { - cmd=KStandardDirs::findExe("fusermount"); + cmd=Utils::findExe("fusermount"); if (!cmd.isEmpty()) { args << QLatin1String("-u") << QLatin1String("-z") << mp; } else { @@ -297,8 +350,8 @@ void RemoteFsDevice::procFinished(int exitCode) proc=0; if (0!=exitCode) { - emit error(wasMount ? i18n("Failed to connect to \"%1\"", details.name) - : i18n("Failed to disconnect from \"%1\"", details.name)); + emit error(wasMount ? i18n("Failed to connect to \"%1\"").arg(details.name) + : i18n("Failed to disconnect from \"%1\"").arg(details.name)); setStatusMessage(QString()); } else if (wasMount) { setStatusMessage(i18n("Updating tracks...")); @@ -313,7 +366,7 @@ void RemoteFsDevice::procFinished(int exitCode) bool RemoteFsDevice::isConnected() const { if (details.isLocalFile()) { - return QDir(details.url.path()).exists(); + return QDir(details.url).exists(); } QString mp=mountPoint(details, false); @@ -328,12 +381,24 @@ bool RemoteFsDevice::isConnected() const if (mp.endsWith('/')) { mp=mp.left(mp.length()-1); } + #ifdef ENABLE_KDE_SUPPORT KMountPoint::List list=KMountPoint::currentMountPoints(); foreach (KMountPoint::Ptr p, list) { if (p->mountPoint()==mp) { return true; } } + #else + QFile mtab("/proc/mounts"); + if (mtab.open(QIODevice::ReadOnly)) { + while (!mtab.atEnd()) { + QStringList parts = QString(mtab.readLine()).split(' '); + if (parts.size()>=2 && parts.at(1)==mp) { + return true; + } + } + } + #endif return false; } @@ -343,8 +408,8 @@ double RemoteFsDevice::usedCapacity() return -1.0; } - KDiskFreeSpaceInfo inf=KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint(details, false)); - return inf.size()>0 ? (inf.used()*1.0)/(inf.size()*1.0) : -1.0; + spaceInfo.setPath(mountPoint(details, false)); + return spaceInfo.size()>0 ? (spaceInfo.used()*1.0)/(spaceInfo.size()*1.0) : -1.0; } QString RemoteFsDevice::capacityString() @@ -356,8 +421,9 @@ QString RemoteFsDevice::capacityString() if (!details.isLocalFile()) { return i18n("Capacity Unknown"); } - KDiskFreeSpaceInfo inf=KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint(details, false)); - return i18n("%1 free", KGlobal::locale()->formatByteSize(inf.size()-inf.used()), 1); + + spaceInfo.setPath(mountPoint(details, false)); + return i18n("%1 free").arg(Utils::formatByteSize(spaceInfo.size()-spaceInfo.used())); } qint64 RemoteFsDevice::freeSpace() @@ -366,8 +432,8 @@ qint64 RemoteFsDevice::freeSpace() return 0; } - KDiskFreeSpaceInfo inf=KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint(details, false)); - return inf.size()-inf.used(); + spaceInfo.setPath(mountPoint(details, false)); + return spaceInfo.size()-spaceInfo.used(); } void RemoteFsDevice::load() @@ -385,11 +451,24 @@ void RemoteFsDevice::setup() QString key=udi(); opts.load(key); details.load(key); - details.url.setPath(MPDParseUtils::fixPath(details.url.path())); - KConfigGroup grp(KGlobal::config(), key); - opts.useCache=grp.readEntry("useCache", true); - coverFileName=grp.readEntry("coverFileName", "cover.jpg"); - configured=KGlobal::config()->hasGroup(key); + details.url=MPDParseUtils::fixPath(details.url); + #ifndef ENABLE_KDE_SUPPORT + QSettings cfg; + #endif + if (HAS_GROUP(key)) { + #ifdef ENABLE_KDE_SUPPORT + KConfigGroup cfg(KGlobal::config(), key); + #else + cfg.beginGroup(key); + #endif + opts.useCache=GET_BOOL("useCache", true); + coverFileName=GET_STRING("coverFileName", "cover.jpg"); + configured=true; + } else { + opts.useCache=true; + coverFileName=QLatin1String("cover.jpg"); + configured=false; + } load(); } @@ -446,7 +525,7 @@ void RemoteFsDevice::saveProperties(const QString &newCoverFileName, const Devic configured=true; Details oldDetails=details; - newDetails.url.setPath(MPDParseUtils::fixPath(newDetails.url.path())); + newDetails.url=MPDParseUtils::fixPath(newDetails.url); if (opts.useCache!=newOpts.useCache || newDetails.url!=oldDetails.url) { // Cache/url settings changed if (opts.useCache && newDetails.url==oldDetails.url) { @@ -468,9 +547,14 @@ void RemoteFsDevice::saveProperties(const QString &newCoverFileName, const Devic QString key=udi(); details.save(key); opts.save(key); - KConfigGroup grp(KGlobal::config(), key); - grp.writeEntry("useCache", opts.useCache); - grp.writeEntry("coverFileName", coverFileName); + #ifdef ENABLE_KDE_SUPPORT + KConfigGroup cfg(KGlobal::config(), key); + #else + QSettings cfg; + cfg.beginGroup(key); + #endif + SET_VALUE("useCache", opts.useCache); + SET_VALUE("coverFileName", coverFileName); if (newName) { QString oldMount=mountPoint(oldDetails, false); diff --git a/devices/remotefsdevice.h b/devices/remotefsdevice.h index f2d383a4c..bae200d71 100644 --- a/devices/remotefsdevice.h +++ b/devices/remotefsdevice.h @@ -26,7 +26,6 @@ #include "fsdevice.h" #include -#include class QProcess; class RemoteFsDevice : public FsDevice @@ -49,10 +48,10 @@ public: return name.isEmpty() || url.isEmpty(); } bool isLocalFile() const { - return url.isLocalFile(); + return !url.startsWith(constSshfsProtocol); } QString name; - KUrl url; + QString url; }; static const QLatin1String constSshfsProtocol; @@ -70,7 +69,7 @@ public: void toggle(); void mount(); void unmount(); - bool supportsDisconnect() const { return !details.url.isLocalFile(); } + bool supportsDisconnect() const { return !details.isLocalFile(); } bool isConnected() const; double usedCapacity(); QString capacityString(); @@ -80,7 +79,7 @@ public: DevType devType() const { return RemoteFs; } QString udi() const { return createUdi(details.name); } QString icon() const { - return QLatin1String(details.url.isLocalFile() ? "inode-directory" : "network-server"); + return QLatin1String(details.isLocalFile() ? "inode-directory" : "network-server"); } bool canPlaySongs() const; diff --git a/devices/synccollectionwidget.cpp b/devices/synccollectionwidget.cpp index dd3f2eb2b..a92ff9c5c 100644 --- a/devices/synccollectionwidget.cpp +++ b/devices/synccollectionwidget.cpp @@ -25,9 +25,8 @@ #include "treeview.h" #include "musiclibrarymodel.h" #include "musiclibraryproxymodel.h" -#include -#include -#include +#include "icon.h" +#include SyncCollectionWidget::SyncCollectionWidget(QWidget *parent, const QString &title, const QString &action) : QWidget(parent) @@ -45,7 +44,7 @@ SyncCollectionWidget::SyncCollectionWidget(QWidget *parent, const QString &title connect(tree, SIGNAL(itemsSelected(bool)), button, SLOT(setEnabled(bool))); connect(button, SIGNAL(clicked()), SLOT(copySongs())); - KAction *act=new KAction(action, this); + QAction *act=new QAction(action, this); connect(act, SIGNAL(triggered(bool)), SLOT(copySongs())); tree->addAction(act); tree->setAlternatingRowColors(false); // Otherwise background gets corrrupted. @@ -57,7 +56,7 @@ SyncCollectionWidget::~SyncCollectionWidget() void SyncCollectionWidget::setIcon(const QString &iconName) { - tree->setPixmap(KIcon(iconName).pixmap(128, 128)); + tree->setPixmap(QIcon::fromTheme(iconName).pixmap(128, 128)); } void SyncCollectionWidget::update(const QSet &songs) diff --git a/devices/synccollectionwidget.ui b/devices/synccollectionwidget.ui index f1390125e..f4bcd9af0 100644 --- a/devices/synccollectionwidget.ui +++ b/devices/synccollectionwidget.ui @@ -34,7 +34,7 @@ - + @@ -42,11 +42,6 @@ - - KPushButton - QPushButton -
kpushbutton.h
-
TreeView QTreeView diff --git a/devices/syncdialog.cpp b/devices/syncdialog.cpp index b94d7dffb..e3127e532 100644 --- a/devices/syncdialog.cpp +++ b/devices/syncdialog.cpp @@ -157,7 +157,7 @@ bool SyncDialog::updateSongs(bool showMessage) if (0==inDev.count() && 0==inLib.count()) { if (showMessage) { - KMessageBox::information(isVisible() ? this : parentWidget(), i18n("Device and library are in sync.")); + MessageBox::information(isVisible() ? this : parentWidget(), i18n("Device and library are in sync.")); } deleteLater(); hide(); diff --git a/devices/transcodingjob.cpp b/devices/transcodingjob.cpp index 9cb50b6c0..db71fa431 100644 --- a/devices/transcodingjob.cpp +++ b/devices/transcodingjob.cpp @@ -2,55 +2,76 @@ * Cantata * * Copyright (c) 2011-2012 Craig Drummond + * + * ---- + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, */ -/**************************************************************************************** - * Copyright (c) 2010 Téo Mrnjavac * - * * - * 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. * - * * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY * - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * - * PARTICULAR PURPOSE. See the GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License along with * - * this program. If not, see . * - ****************************************************************************************/ #include "transcodingjob.h" -TranscodingJob::TranscodingJob(const QStringList ¶ms, QObject *parent) - : KJob(parent) +TranscodingJob::TranscodingJob(const QStringList ¶ms) + : parameters(params) + , process(0) , duration(-1) { - QStringList p(params); - QString cmd=p.takeFirst(); +} - process = new KProcess(this); - process->setOutputChannelMode(KProcess::MergedChannels); - process->setProgram(cmd); - *process << p; - - connect(process, SIGNAL(readyRead()), this, SLOT(processOutput())); - connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus))); +TranscodingJob::~TranscodingJob() +{ + delete process; } void TranscodingJob::start() { - process->start(); + process = new QProcess; + connect(process, SIGNAL(readyReadStandardError()), this, SLOT(processOutput())); + connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput())); + connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus))); + QString cmd=parameters.takeFirst(); + process->start(cmd, parameters); +} + +void TranscodingJob::stop() +{ + if (process) { + process->close(); + process->deleteLater(); + process=0; + emit result(StatusCancelled); + } } void TranscodingJob::finished(int exitCode, QProcess::ExitStatus exitStatus) { - Q_UNUSED(exitCode); Q_UNUSED(exitStatus); - emitResult(); + if (!process) { + return; + } + if (stopRequested) { + emit result(StatusCancelled); + return; + } + emit result(0==exitCode ? StatusOk : StatusFailed); } void TranscodingJob::processOutput() { + if (stopRequested) { + return; + } QString output = process->readAllStandardOutput().data(); if(output.simplified().isEmpty()) { return; @@ -58,14 +79,13 @@ void TranscodingJob::processOutput() if (-1==duration) { duration = computeDuration(output); - if(duration >= 0) { - setTotalAmount(KJob::Bytes, duration); - } } - qint64 progress = computeProgress(output); - if(progress > -1) { - setProcessedAmount(KJob::Bytes, progress); + if (duration>0) { + qint64 prog = computeProgress(output); + if (prog>-1) { + setPercent(prog/duration); + } } } diff --git a/devices/transcodingjob.h b/devices/transcodingjob.h index f1d21e95c..080dd487d 100644 --- a/devices/transcodingjob.h +++ b/devices/transcodingjob.h @@ -22,17 +22,19 @@ #ifndef TRANSCODING_JOB_H #define TRANSCODING_JOB_H +#include "filejob.h" #include -#include -#include +#include -class TranscodingJob : public KJob +class TranscodingJob : public FileJob { Q_OBJECT public: - explicit TranscodingJob(const QStringList ¶ms, QObject *parent = 0); + explicit TranscodingJob(const QStringList ¶ms); + ~TranscodingJob(); void start(); + void stop(); private Q_SLOTS: void processOutput(); @@ -43,7 +45,8 @@ private: inline qint64 computeProgress(const QString &output); private: - KProcess *process; + QStringList parameters; + QProcess *process; qint64 duration; //in csec }; diff --git a/devices/umsdevice.cpp b/devices/umsdevice.cpp index b28a30eb4..8b002e1b7 100644 --- a/devices/umsdevice.cpp +++ b/devices/umsdevice.cpp @@ -32,10 +32,11 @@ #include #include #include +#ifdef ENABLE_KDE_SUPPORT #include -#include #include #include +#endif static const QLatin1String constSettingsFile("/.is_audio_player"); static const QLatin1String constMusicFolderKey("audio_folder"); @@ -59,6 +60,7 @@ UmsDevice::UmsDevice(DevicesModel *m, Solid::Device &dev) : FsDevice(m, dev) , access(dev.as()) { + spaceInfo.setPath(access->filePath()); setup(); } @@ -76,8 +78,7 @@ double UmsDevice::usedCapacity() return -1.0; } - KDiskFreeSpaceInfo inf=KDiskFreeSpaceInfo::freeSpaceInfo(access->filePath()); - return inf.size()>0 ? (inf.used()*1.0)/(inf.size()*1.0) : -1.0; + return spaceInfo.size()>0 ? (spaceInfo.used()*1.0)/(spaceInfo.size()*1.0) : -1.0; } QString UmsDevice::capacityString() @@ -86,8 +87,7 @@ QString UmsDevice::capacityString() return i18n("Not Connected"); } - KDiskFreeSpaceInfo inf=KDiskFreeSpaceInfo::freeSpaceInfo(access->filePath()); - return i18n("%1 free", KGlobal::locale()->formatByteSize(inf.size()-inf.used()), 1); + return i18n("%1 free").arg(Utils::formatByteSize(spaceInfo.size()-spaceInfo.used())); } qint64 UmsDevice::freeSpace() @@ -96,8 +96,7 @@ qint64 UmsDevice::freeSpace() return 0; } - KDiskFreeSpaceInfo inf=KDiskFreeSpaceInfo::freeSpaceInfo(access->filePath()); - return inf.size()-inf.used(); + return spaceInfo.size()-spaceInfo.used(); } void UmsDevice::setup() @@ -119,10 +118,14 @@ void UmsDevice::setup() while (!in.atEnd()) { QString line = in.readLine(); if (line.startsWith(constMusicFolderKey+"=")) { + #ifdef ENABLE_KDE_SUPPORT KUrl url = KUrl(path); url.addPath(line.section('=', 1, 1)); url.cleanPath(); audioFolderSetting=audioFolder=url.toLocalFile(); + #else + audioFolderSetting=Utils::cleanPath(path+'/'+line.section('=', 1, 1)); + #endif if (!QDir(audioFolder).exists()) { audioFolder = path; } diff --git a/devices/umsdevice.h b/devices/umsdevice.h index cfdbd162b..5e4164d9a 100644 --- a/devices/umsdevice.h +++ b/devices/umsdevice.h @@ -25,6 +25,11 @@ #define UMSDEVICE_H #include "fsdevice.h" +#ifdef ENABLE_KDE_SUPPORT +#include +#else +#include "solid-lite/storageaccess.h" +#endif class UmsDevice : public FsDevice { diff --git a/devices/utils.cpp b/devices/utils.cpp index 204198a53..d63377cc8 100644 --- a/devices/utils.cpp +++ b/devices/utils.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "mpdparseutils.h" #include "covers.h" +#include "localize.h" #include #include #include @@ -304,3 +305,216 @@ void Utils::stopThread(QThread *thread) } } +#ifndef ENABLE_KDE_SUPPORT +// Copied from KDE... START +#include + +QString Utils::formatByteSize(double size) +{ + static QLocale locale; + + int unit = 0; + double multiplier = 1024.0; + + while (qAbs(size) >= multiplier && unit < 3) { + size /= multiplier; + unit++; + } + + switch(unit) { + case 0: return i18n("%1 B").arg(size); + case 1: return i18n("%1 KiB").arg(locale.toString(size, 'f', 1)); + case 2: return i18n("%1 MiB").arg(locale.toString(size, 'f', 1)); + default: + case 3: return i18n("%1 GiB").arg(locale.toString(size, 'f', 1)); + } +} + +#if defined Q_OS_WIN +#define KPATH_SEPARATOR ';' +// #define KDIR_SEPARATOR '\\' /* faster than QDir::separator() */ +#else +#define KPATH_SEPARATOR ':' +// #define KDIR_SEPARATOR '/' /* faster than QDir::separator() */ +#endif + +static inline QString equalizePath(QString &str) +{ + #ifdef Q_WS_WIN + // filter pathes through QFileInfo to have always + // the same case for drive letters + QFileInfo f(str); + if (f.isAbsolute()) + return f.absoluteFilePath(); + else + #endif + return str; +} + +static void tokenize(QStringList &tokens, const QString &str, const QString &delim) +{ + const int len = str.length(); + QString token; + + for(int index = 0; index < len; index++) { + if (delim.contains(str[index])) { + tokens.append(equalizePath(token)); + token.clear(); + } else { + token += str[index]; + } + } + if (!token.isEmpty()) { + tokens.append(equalizePath(token)); + } +} + +#ifdef Q_OS_WIN +static QStringList executableExtensions() +{ + QStringList ret = QString::fromLocal8Bit(qgetenv("PATHEXT")).split(QLatin1Char(';')); + if (!ret.contains(QLatin1String(".exe"), Qt::CaseInsensitive)) { + // If %PATHEXT% does not contain .exe, it is either empty, malformed, or distorted in ways that we cannot support, anyway. + ret.clear(); + ret << QLatin1String(".exe") + << QLatin1String(".com") + << QLatin1String(".bat") + << QLatin1String(".cmd"); + } + return ret; +} +#endif + +static QStringList systemPaths(const QString &pstr) +{ + QStringList tokens; + QString p = pstr; + + if( p.isEmpty() ) { + p = QString::fromLocal8Bit( qgetenv( "PATH" ) ); + } + + QString delimiters(QLatin1Char(KPATH_SEPARATOR)); + delimiters += QLatin1Char('\b'); + tokenize( tokens, p, delimiters ); + + QStringList exePaths; + + // split path using : or \b as delimiters + for( int i = 0; i < tokens.count(); i++ ) { + exePaths << /*KShell::tildeExpand(*/ tokens[ i ] /*)*/; // TODO + } + + return exePaths; +} + +#ifdef Q_WS_MAC +static QString getBundle(const QString &path) +{ + //kDebug(180) << "getBundle(" << path << ", " << ignore << ") called"; + QFileInfo info; + QString bundle = path; + bundle += QLatin1String(".app/Contents/MacOS/") + bundle.section(QLatin1Char('/'), -1); + info.setFile( bundle ); + FILE *file; + if (file = fopen(info.absoluteFilePath().toUtf8().constData(), "r")) { + fclose(file); + struct stat _stat; + if ((stat(info.absoluteFilePath().toUtf8().constData(), &_stat)) < 0) { + return QString(); + } + if ( _stat.st_mode & S_IXUSR ) { + if ( ((_stat.st_mode & S_IFMT) == S_IFREG) || ((_stat.st_mode & S_IFMT) == S_IFLNK) ) { + //kDebug(180) << "getBundle(): returning " << bundle; + return bundle; + } + } + } + return QString(); +} +#endif + +static QString checkExecutable( const QString& path ) +{ + #ifdef Q_WS_MAC + QString bundle = getBundle( path ); + if ( !bundle.isEmpty() ) { + //kDebug(180) << "findExe(): returning " << bundle; + return bundle; + } + #endif + QFileInfo info( path ); + QFileInfo orig = info; + #if defined(Q_OS_DARWIN) || defined(Q_OS_MAC) + FILE *file; + if (file = fopen(orig.absoluteFilePath().toUtf8().constData(), "r")) { + fclose(file); + struct stat _stat; + if ((stat(orig.absoluteFilePath().toUtf8().constData(), &_stat)) < 0) { + return QString(); + } + if ( _stat.st_mode & S_IXUSR ) { + if ( ((_stat.st_mode & S_IFMT) == S_IFREG) || ((_stat.st_mode & S_IFMT) == S_IFLNK) ) { + orig.makeAbsolute(); + return orig.filePath(); + } + } + } + return QString(); + #else + if( info.exists() && info.isSymLink() ) + info = QFileInfo( info.canonicalFilePath() ); + if( info.exists() && info.isExecutable() && info.isFile() ) { + // return absolute path, but without symlinks resolved in order to prevent + // problems with executables that work differently depending on name they are + // run as (for example gunzip) + orig.makeAbsolute(); + return orig.filePath(); + } + //kDebug(180) << "checkExecutable(): failed, returning empty string"; + return QString(); + #endif +} + +QString Utils::findExe(const QString &appname, const QString &pstr) +{ + #ifdef Q_OS_WIN + QStringList executable_extensions = executableExtensions(); + if (!executable_extensions.contains(appname.section(QLatin1Char('.'), -1, -1, QString::SectionIncludeLeadingSep), Qt::CaseInsensitive)) { + QString found_exe; + foreach (const QString& extension, executable_extensions) { + found_exe = findExe(appname + extension, pstr); + if (!found_exe.isEmpty()) { + return found_exe; + } + } + return QString(); + } + #endif + + const QStringList exePaths = systemPaths( pstr ); + for (QStringList::ConstIterator it = exePaths.begin(); it != exePaths.end(); ++it) { + QString p = (*it) + QLatin1Char('/'); + p += appname; + + QString result = checkExecutable(p); + if (!result.isEmpty()) { + return result; + } + } + + return QString(); +} +// Copied from KDE... END + +QString Utils::cleanPath(const QString &p) +{ + QString path(p); + while(path.contains("//")) { + path.replace("//", "/"); + } + return dirSyntax(path); +} + +#endif + diff --git a/devices/utils.h b/devices/utils.h index 8b5ceac95..0f10d021d 100644 --- a/devices/utils.h +++ b/devices/utils.h @@ -27,6 +27,12 @@ #include #include #include +#include +#ifdef ENABLE_KDE_SUPPORT +#include +#include +#include +#endif class QString; class QThread; @@ -53,6 +59,15 @@ namespace Utils extern void msleep(int msecs); inline void sleep() { msleep(100); } extern void stopThread(QThread *thread); + + #ifdef ENABLE_KDE_SUPPORT + inline QString findExe(const QString &appname, const QString &pathstr=QString()) { return KStandardDirs::findExe(appname, pathstr); } + inline QString formatByteSize(double size) { return KGlobal::locale()->formatByteSize(size, 1); } + #else + extern QString findExe(const QString &appname, const QString &pathstr=QString()); + extern QString formatByteSize(double size); + extern QString cleanPath(const QString &p); + #endif }; #endif diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index c8c2fae52..12fa24dc0 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -78,7 +78,8 @@ #include "lyricspage.h" #include "infopage.h" #include "serverinfopage.h" -#if defined ENABLE_DEVICES_SUPPORT && defined TAGLIB_FOUND +#if defined ENABLE_DEVICES_SUPPORT +#include "filejob.h" #include "devicespage.h" #include "devicesmodel.h" #include "actiondialog.h" @@ -915,6 +916,9 @@ MainWindow::~MainWindow() } Utils::stopThread(mpdThread); Covers::self()->stop(); + #if defined ENABLE_DEVICES_SUPPORT + FileScheduler::self()->stop(); + #endif } void MainWindow::initSizes() diff --git a/gui/mainwindow.h b/gui/mainwindow.h index c0a4ecf96..d95ad22e3 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -71,7 +71,7 @@ class LyricsPage; class StreamsPage; class InfoPage; class ServerInfoPage; -#if defined ENABLE_KDE_SUPPORT && defined TAGLIB_FOUND +#ifdef ENABLE_DEVICES_SUPPORT class DevicesPage; #endif class QThread; @@ -165,7 +165,7 @@ public: PAGE_INFO, #endif PAGE_SERVER_INFO - #ifdef ENABLE_KDE_SUPPORT + #ifdef ENABLE_DEVICES_SUPPORT , PAGE_DEVICES #endif }; diff --git a/gui/settings.cpp b/gui/settings.cpp index e4dd7e2e7..d3c3501e5 100644 --- a/gui/settings.cpp +++ b/gui/settings.cpp @@ -111,39 +111,6 @@ struct MpdDefaults static MpdDefaults mpdDefaults; -#ifdef ENABLE_KDE_SUPPORT -#define CFG_GET_STRING(CFG, KEY, DEF) (CFG.readEntry(KEY, QString(DEF))) -#define CFG_GET_STRINGLIST(CFG, KEY, DEF) (CFG.readEntry(KEY, DEF)) -#define CFG_GET_BOOL(CFG, KEY, DEF) (CFG.readEntry(KEY, DEF)) -#define CFG_GET_INT(CFG, KEY, DEF) (CFG.readEntry(KEY, DEF)) -#define CFG_GET_BYTE_ARRAY(CFG, KEY) (CFG.readEntry(KEY, QByteArray())) -#define CFG_GET_SIZE(CFG, KEY) (CFG.readEntry(KEY, QSize())) -#define CFG_SET_VALUE(CFG, KEY, V) (CFG.writeEntry(KEY, V)) -#define HAS_GROUP(GRP) (KGlobal::config()->hasGroup(GRP)) -#define REMOVE_GROUP(GRP) (KGlobal::config()->deleteGroup(GRP)) -#define REMOVE_ENTRY(KEY) (cfg.deleteEntry(KEY)) -#define GET_STRING(KEY, DEF) CFG_GET_STRING(cfg, KEY, DEF) -#define GET_STRINGLIST(KEY, DEF) CFG_GET_STRINGLIST(cfg, KEY, DEF) -#define GET_BOOL(KEY, DEF) CFG_GET_BOOL(cfg, KEY, DEF) -#define GET_INT(KEY, DEF) CFG_GET_INT(cfg, KEY, DEF) -#define GET_BYTE_ARRAY(KEY) CFG_GET_BYTE_ARRAY(cfg, KEY) -#define GET_SIZE(KEY) CFG_GET_SIZE(cfg, KEY) -#define SET_VALUE(KEY, V) CFG_SET_VALUE(cfg, KEY, V) -#define HAS_ENTRY(KEY) (cfg.hasKey(KEY)) -#else -#define GET_STRING(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toString() : QString(DEF)) -#define GET_STRINGLIST(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toStringList() : DEF) -#define GET_BOOL(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toBool() : DEF) -#define GET_INT(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toInt() : DEF) -#define GET_BYTE_ARRAY(KEY) (cfg.value(KEY).toByteArray()) -#define GET_SIZE(KEY) (cfg.contains(KEY) ? cfg.value(KEY).toSize() : QSize()) -#define SET_VALUE(KEY, V) (cfg.setValue(KEY, V)) -#define HAS_GROUP(GRP) (-1!=cfg.childGroups().indexOf(GRP)) -#define REMOVE_GROUP(GRP) (cfg.remove(GRP)) -#define REMOVE_ENTRY(KEY) (cfg.remove(KEY)) -#define HAS_ENTRY(KEY) (cfg.contains(KEY)) -#endif - Settings::Settings() : isFirstRun(false) , timer(0) @@ -904,11 +871,7 @@ void Settings::save(bool force) { if (force) { SET_VALUE("version", PACKAGE_VERSION); - #ifdef ENABLE_KDE_SUPPORT - KGlobal::config()->sync(); - #else - cfg.sync(); - #endif + CFG_SYNC; if (timer) { timer->stop(); } diff --git a/gui/settings.h b/gui/settings.h index f4a0ca623..af7c46f43 100644 --- a/gui/settings.h +++ b/gui/settings.h @@ -25,6 +25,8 @@ #define SETTINGS_H #ifdef ENABLE_KDE_SUPPORT +#include +#include #include namespace KWallet { class Wallet; @@ -37,6 +39,41 @@ class Wallet; #define CANTATA_MAKE_VERSION(a, b, c) (((a) << 16) | ((b) << 8) | (c)) +#ifdef ENABLE_KDE_SUPPORT +#define CFG_GET_STRING(CFG, KEY, DEF) (CFG.readEntry(KEY, QString(DEF))) +#define CFG_GET_STRINGLIST(CFG, KEY, DEF) (CFG.readEntry(KEY, DEF)) +#define CFG_GET_BOOL(CFG, KEY, DEF) (CFG.readEntry(KEY, DEF)) +#define CFG_GET_INT(CFG, KEY, DEF) (CFG.readEntry(KEY, DEF)) +#define CFG_GET_BYTE_ARRAY(CFG, KEY) (CFG.readEntry(KEY, QByteArray())) +#define CFG_GET_SIZE(CFG, KEY) (CFG.readEntry(KEY, QSize())) +#define CFG_SET_VALUE(CFG, KEY, V) (CFG.writeEntry(KEY, V)) +#define HAS_GROUP(GRP) (KGlobal::config()->hasGroup(GRP)) +#define REMOVE_GROUP(GRP) (KGlobal::config()->deleteGroup(GRP)) +#define REMOVE_ENTRY(KEY) (cfg.deleteEntry(KEY)) +#define GET_STRING(KEY, DEF) CFG_GET_STRING(cfg, KEY, DEF) +#define GET_STRINGLIST(KEY, DEF) CFG_GET_STRINGLIST(cfg, KEY, DEF) +#define GET_BOOL(KEY, DEF) CFG_GET_BOOL(cfg, KEY, DEF) +#define GET_INT(KEY, DEF) CFG_GET_INT(cfg, KEY, DEF) +#define GET_BYTE_ARRAY(KEY) CFG_GET_BYTE_ARRAY(cfg, KEY) +#define GET_SIZE(KEY) CFG_GET_SIZE(cfg, KEY) +#define SET_VALUE(KEY, V) CFG_SET_VALUE(cfg, KEY, V) +#define HAS_ENTRY(KEY) (cfg.hasKey(KEY)) +#define CFG_SYNC KGlobal::config()->sync() +#else +#define GET_STRING(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toString() : QString(DEF)) +#define GET_STRINGLIST(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toStringList() : DEF) +#define GET_BOOL(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toBool() : DEF) +#define GET_INT(KEY, DEF) (cfg.contains(KEY) ? cfg.value(KEY).toInt() : DEF) +#define GET_BYTE_ARRAY(KEY) (cfg.value(KEY).toByteArray()) +#define GET_SIZE(KEY) (cfg.contains(KEY) ? cfg.value(KEY).toSize() : QSize()) +#define SET_VALUE(KEY, V) (cfg.setValue(KEY, V)) +#define HAS_GROUP(GRP) (-1!=cfg.childGroups().indexOf(GRP)) +#define REMOVE_GROUP(GRP) (cfg.remove(GRP)) +#define REMOVE_ENTRY(KEY) (cfg.remove(KEY)) +#define HAS_ENTRY(KEY) (cfg.contains(KEY)) +#define CFG_SYNC cfg.sync() +#endif + class QTimer; class Settings : public QObject diff --git a/gui/tageditor.cpp b/gui/tageditor.cpp index e812a8a64..3870f4028 100644 --- a/gui/tageditor.cpp +++ b/gui/tageditor.cpp @@ -745,17 +745,17 @@ Device * TagEditor::getDevice(const QString &udi, QWidget *p) { Device *dev=DevicesModel::self()->device(udi); if (!dev) { - KMessageBox::error(p ? p : this, i18n("Device has been removed!")); + MessageBox::error(p ? p : this, i18n("Device has been removed!")); reject(); return 0; } if (!dev->isConnected()) { - KMessageBox::error(p ? p : this, i18n("Device is not connected.")); + MessageBox::error(p ? p : this, i18n("Device is not connected.")); reject(); return 0; } if (!dev->isIdle()) { - KMessageBox::error(p ? p : this, i18n("Device is busy?")); + MessageBox::error(p ? p : this, i18n("Device is busy?")); reject(); return 0; } diff --git a/models/musiclibraryitemalbum.cpp b/models/musiclibraryitemalbum.cpp index 7a685b037..1fce5372d 100644 --- a/models/musiclibraryitemalbum.cpp +++ b/models/musiclibraryitemalbum.cpp @@ -32,7 +32,7 @@ #include "covers.h" #include "config.h" #include "icon.h" -#if defined ENABLE_KDE_SUPPORT && defined TAGLIB_FOUND +#ifdef ENABLE_DEVICES_SUPPORT #include "device.h" #include "utils.h" #endif @@ -204,7 +204,7 @@ const QPixmap & MusicLibraryItemAlbum::cover() song.album=m_itemData; song.year=m_year; song.file=firstSong->file(); - #if defined ENABLE_KDE_SUPPORT && defined TAGLIB_FOUND + #ifdef ENABLE_DEVICES_SUPPORT if (!song.file.startsWith("/") && parent() && parent()->parent() && qobject_cast(parent()->parent())) { QString root=static_cast(parent()->parent())->path(); if (!root.isEmpty()) { diff --git a/models/musiclibraryitemartist.cpp b/models/musiclibraryitemartist.cpp index 3c2d0e457..e474c62fe 100644 --- a/models/musiclibraryitemartist.cpp +++ b/models/musiclibraryitemartist.cpp @@ -34,7 +34,7 @@ #include "localize.h" #include "covers.h" #include "icon.h" -#if defined ENABLE_KDE_SUPPORT && defined TAGLIB_FOUND +#ifdef ENABLE_DEVICES_SUPPORT #include "device.h" #include "utils.h" #endif @@ -121,7 +121,7 @@ const QPixmap & MusicLibraryItemArtist::cover() if (firstSong) { song.file=firstSong->file(); - #if defined ENABLE_KDE_SUPPORT && defined TAGLIB_FOUND + #ifdef ENABLE_DEVICES_SUPPORT if (!song.file.startsWith("/") && parent() && qobject_cast(parent())) { QString root=static_cast(parent())->path(); if (!root.isEmpty()) { diff --git a/po/generate.sh b/po/generate.sh index 46758c935..7bfd1b4a5 100755 --- a/po/generate.sh +++ b/po/generate.sh @@ -26,7 +26,7 @@ echo "Done preparing rc files" echo "Extracting messages" cd ${BASEDIR} # see above on sorting -find . -name '*.cpp' -o -name '*.h' -o -name '*.c' | sort > ${WDIR}/infiles.list +find . -name '*.cpp' -o -name '*.h' -o -name '*.c' | grep -v "solid-lite" | sort > ${WDIR}/infiles.list echo "rc.cpp" >> ${WDIR}/infiles.list cd ${WDIR} @@ -35,7 +35,7 @@ xgettext --from-code=UTF-8 -C -kde -ci18n -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki1 --msgid-bugs-address="${BUGADDR}" \ --files-from=infiles.list -D ${BASEDIR} -D ${WDIR} -o ${PROJECT}_kde.pot || { echo "error while calling xgettext. aborting."; exit 1; } -find .. -name '*.cpp' | xargs grep -l 'QObject::tr(' | sort > ${WDIR}/infiles.qt.list +find .. -name '*.cpp' | xargs grep -l 'QObject::tr(' | grep -v "solid-lite" | sort > ${WDIR}/infiles.qt.list echo "../qtplural.h" >> ${WDIR}/infiles.qt.list lupdate @infiles.qt.list -ts ${PROJECT}.ts && lconvert -i ${PROJECT}.ts -o ${PROJECT}_qt.po && msguniq -o ${PROJECT}_qt.pot ${PROJECT}_qt.po && rm ${PROJECT}.ts ${PROJECT}_qt.po diff --git a/replaygain/rgdialog.cpp b/replaygain/rgdialog.cpp index 5b70057e2..0b0c21066 100644 --- a/replaygain/rgdialog.cpp +++ b/replaygain/rgdialog.cpp @@ -45,7 +45,7 @@ #include #endif -#ifdef ENABLE_DEVICES_SUPPORT +#ifdef ENABLE_KDE_SUPPORT static QString formatNumber(double number, int precision) { return KGlobal::locale()->formatNumber(number, precision); @@ -121,7 +121,7 @@ RgDialog::RgDialog(QWidget *parent) layout->addWidget(statusLabel); layout->addWidget(progress); setMainWidget(mainWidet); - #ifdef ENABLE_DEVICES_SUPPORT + #ifdef ENABLE_KDE_SUPPORT setButtonGuiItem(Ok, KStandardGuiItem::save()); setButtonGuiItem(Cancel, KStandardGuiItem::close()); #else @@ -236,7 +236,7 @@ void RgDialog::startScanning() if (!all && origTags.count()==origSongs.count()) { return; } - #ifdef ENABLE_DEVICES_SUPPORT + #ifdef ENABLE_KDE_SUPPORT setButtonGuiItem(Cancel, KStandardGuiItem::cancel()); #else setButtonGuiItem(Cancel, KGuiItem(i18n("Cancel"), "dialog-cancel")); @@ -271,7 +271,7 @@ void RgDialog::stopScanning() JobController::self()->cancel(); clearScanners(); - #ifdef ENABLE_DEVICES_SUPPORT + #ifdef ENABLE_KDE_SUPPORT setButtonGuiItem(Cancel, KStandardGuiItem::cancel()); #else setButtonGuiItem(Cancel, KGuiItem(i18n("Close"), "dialog-close")); @@ -312,7 +312,7 @@ void RgDialog::startReadingTags() if (tagReader) { return; } - #ifdef ENABLE_DEVICES_SUPPORT + #ifdef ENABLE_KDE_SUPPORT setButtonGuiItem(Cancel, KStandardGuiItem::cancel()); #else setButtonGuiItem(Cancel, KGuiItem(i18n("Cancel"), "dialog-cancel")); @@ -418,7 +418,7 @@ void RgDialog::updateView() progress->setVisible(false); statusLabel->setVisible(false); state=State_Idle; - #ifdef ENABLE_DEVICES_SUPPORT + #ifdef ENABLE_KDE_SUPPORT setButtonGuiItem(Cancel, KStandardGuiItem::close()); #else setButtonGuiItem(Cancel, KGuiItem(i18n("Close"), "dialog-close")); @@ -435,17 +435,17 @@ Device * RgDialog::getDevice(const QString &udi, QWidget *p) { Device *dev=DevicesModel::self()->device(udi); if (!dev) { - KMessageBox::error(p ? p : this, i18n("Device has been removed!")); + MessageBox::error(p ? p : this, i18n("Device has been removed!")); reject(); return 0; } if (!dev->isConnected()) { - KMessageBox::error(p ? p : this, i18n("Device is not connected.")); + MessageBox::error(p ? p : this, i18n("Device is not connected.")); reject(); return 0; } if (!dev->isIdle()) { - KMessageBox::error(p ? p : this, i18n("Device is busy?")); + MessageBox::error(p ? p : this, i18n("Device is busy?")); reject(); return 0; } diff --git a/solid-lite/CMakeLists.txt b/solid-lite/CMakeLists.txt new file mode 100644 index 000000000..16457fde7 --- /dev/null +++ b/solid-lite/CMakeLists.txt @@ -0,0 +1,310 @@ +INCLUDE(MacroOptionalFindPackage) +INCLUDE(MacroLogFeature) + +add_subdirectory( ifaces ) +include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${QT_INCLUDES}) + +file(MAKE_DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR}/backends/hal + ${CMAKE_CURRENT_BINARY_DIR}/backends/udev + ${CMAKE_CURRENT_BINARY_DIR}/backends/wmi +) + +set(solidlite_LIB_SRCS + solidnamespace.cpp + managerbase.cpp + device.cpp + devicemanager.cpp + deviceinterface.cpp + genericinterface.cpp + block.cpp + storagedrive.cpp + opticaldrive.cpp + storagevolume.cpp + opticaldisc.cpp + storageaccess.cpp + portablemediaplayer.cpp + predicate.cpp + predicateparse.cpp + predicate_lexer.c + predicate_parser.c + xdgbasedirs.cpp + + ifaces/block.cpp + ifaces/opticaldrive.cpp + ifaces/device.cpp + ifaces/deviceinterface.cpp + ifaces/devicemanager.cpp + ifaces/genericinterface.cpp + ifaces/opticaldisc.cpp + ifaces/portablemediaplayer.cpp + ifaces/storagedrive.cpp + ifaces/storagevolume.cpp + ifaces/storageaccess.cpp + + backends/shared/rootdevice.cpp +) + +set(solidlite_LIB_MOC_HDRS + block.h + deviceinterface.h + devicemanager_p.h + devicenotifier.h + device_p.h + genericinterface.h + opticaldisc.h + opticaldrive.h + portablemediaplayer.h + storageaccess.h + storagedrive.h + storagevolume.h + ifaces/device.h + ifaces/devicemanager.h + backends/shared/rootdevice.h +) + macro_optional_find_package( UDev ) + macro_log_feature( UDEV_FOUND "UDev" "UDev support for Solid" "http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html" FALSE "" "Allows Solid to use UDev to provide information about devices on Linux" ) + configure_file( config-solid.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-solid.h ) + + + if ( UDEV_FOUND ) + message(STATUS "Building Solid UDev backend." ) + set(solidlite_LIB_SRCS ${solidlite_LIB_SRCS} + backends/udev/udevdevice.cpp + backends/udev/udevmanager.cpp + backends/udev/udevdeviceinterface.cpp + backends/udev/udevgenericinterface.cpp + backends/udev/udevportablemediaplayer.cpp + backends/udev/udevblock.cpp + backends/shared/udevqtclient.cpp + backends/shared/udevqtdevice.cpp + ) + + set(solidlite_LIB_MOC_HDRS ${solidlite_LIB_MOC_HDRS} + backends/udev/udevblock.h + backends/udev/udevdevice.h + backends/udev/udevdeviceinterface.h + backends/udev/udevgenericinterface.h + backends/udev/udevmanager.h + backends/udev/udevportablemediaplayer.h + backends/shared/udevqt.h + ) + # check for media-player-info (runtime-only optional dependency) + set(XDG_DATA_DIRS_ENV $ENV{XDG_DATA_DIRS}) # if(ENV{..}) does not work for me + if(XDG_DATA_DIRS_ENV) + find_path(MEDIAPLAYERINFO_PATH sony_psp.mpi + PATHS ENV XDG_DATA_DIRS + PATH_SUFFIXES "media-player-info" NO_DEFAULT_PATH + ) + else(XDG_DATA_DIRS_ENV) + set(XDG_DATA_DIRS "/usr/share") + message(STATUS "Warning: environment variable XDG_DATA_DIRS not set, falling back to ${XDG_DATA_DIRS}") + find_path(MEDIAPLAYERINFO_PATH sony_psp.mpi + PATHS "${XDG_DATA_DIRS}" + PATH_SUFFIXES "media-player-info" NO_DEFAULT_PATH + ) + endif(XDG_DATA_DIRS_ENV) + + macro_log_feature(MEDIAPLAYERINFO_PATH + "media-player-info" + "Enables identification and querying of portable media players" + "http://www.freedesktop.org/wiki/Software/media-player-info" + FALSE + "" + "Runtime-only dependency of the udev solid backend. Support for m-p-i is included even if not found during build" + ) + endif( UDEV_FOUND ) + + + message(STATUS "Building Solid HAL backend." ) + set(solidlite_LIB_SRCS ${solidlite_LIB_SRCS} + backends/hal/halblock.cpp + backends/hal/halcdrom.cpp + backends/hal/haldeviceinterface.cpp + backends/hal/halfstabhandling.cpp + backends/hal/halgenericinterface.cpp + backends/hal/haldevice.cpp + backends/hal/halmanager.cpp + backends/hal/halopticaldisc.cpp + backends/hal/halportablemediaplayer.cpp + backends/hal/halstorageaccess.cpp + backends/hal/halstorage.cpp + backends/hal/halvolume.cpp + ) + set(solidlite_LIB_MOC_HDRS ${solidlite_LIB_MOC_HDRS} + backends/hal/halblock.h + backends/hal/halcdrom.h + backends/hal/haldevice.h + backends/hal/haldeviceinterface.h + backends/hal/halgenericinterface.h + backends/hal/halmanager.h + backends/hal/halopticaldisc.h + backends/hal/halportablemediaplayer.h + backends/hal/halstorageaccess.h + backends/hal/halstorage.h + backends/hal/halvolume.h + ) + + # FIXME: this should work on more Unix systems + if (CMAKE_SYSTEM_NAME MATCHES Linux) + message(STATUS "Building Solid UDisks backend." ) + set(solidlite_LIB_SRCS ${solidlite_LIB_SRCS} + backends/udisks/udisksmanager.cpp + backends/udisks/udisksdevice.cpp + backends/udisks/udisksblock.cpp + backends/udisks/udisksstoragevolume.cpp + backends/udisks/udisksdeviceinterface.cpp + backends/udisks/udisksopticaldisc.cpp + backends/udisks/udisksopticaldrive.cpp + backends/udisks/udisksstoragedrive.cpp + backends/udisks/udisksstorageaccess.cpp + backends/udisks/udisksgenericinterface.cpp + ) + set(solidlite_LIB_MOC_HDRS ${solidlite_LIB_MOC_HDRS} + backends/udisks/udisksblock.h + backends/udisks/udisksdevice.h + backends/udisks/udisksdeviceinterface.h + backends/udisks/udisksgenericinterface.h + backends/udisks/udisksmanager.h + backends/udisks/udisksopticaldisc.h + backends/udisks/udisksopticaldrive.h + backends/udisks/udisksstorageaccess.h + backends/udisks/udisksstoragedrive.h + backends/udisks/udisksstoragevolume.h + ) + endif (CMAKE_SYSTEM_NAME MATCHES Linux) + +if(APPLE) + find_package(IOKit REQUIRED) + + message(STATUS "-- Building Solid IOKit backend." ) + set(solidlite_LIB_SRCS ${solidlite_LIB_SRCS} + backends/iokit/iokitmanager.cpp + backends/iokit/iokitdevice.cpp + backends/iokit/cfhelper.cpp + backends/iokit/iokitdeviceinterface.cpp + backends/iokit/iokitgenericinterface.cpp + ) + set(solidlite_LIB_MOC_HDRS ${solidlite_LIB_MOC_HDRS} + backends/iokit/iokitdevice.h + backends/iokit/iokitdeviceinterface.h + backends/iokit/iokitgenericinterface.h + backends/iokit/iokitmanager.h + ) +endif(APPLE) + +if(WIN32) + include(CheckIncludeFileCXX) + check_include_file_cxx(wbemidl.h HAVE_WBEM) + FIND_LIBRARY(WBEM_LIBRARIES NAMES wbemuuid wbemuuidd) + if(HAVE_WBEM AND WBEM_LIBRARIES) + set(HAVE_WBEM True) + message(STATUS "Found wbemuuid library: ${WBEM_LIBRARIES}") + else(HAVE_WBEM AND WBEM_LIBRARIES) + set(HAVE_WBEM False) + endif(HAVE_WBEM AND WBEM_LIBRARIES) + if(HAVE_WBEM AND NOT WINCE) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_WBEM") + message(STATUS "-- Building Solid WMI backend." ) + + set(solidlite_LIB_SRCS ${solidlite_LIB_SRCS} + backends/wmi/wmiblock.cpp + backends/wmi/wmicdrom.cpp + backends/wmi/wmideviceinterface.cpp + backends/wmi/wmigenericinterface.cpp + backends/wmi/wmidevice.cpp + backends/wmi/wmimanager.cpp + backends/wmi/wmiopticaldisc.cpp + backends/wmi/wmiportablemediaplayer.cpp + backends/wmi/wmiquery.cpp + backends/wmi/wmistorageaccess.cpp + backends/wmi/wmistorage.cpp + backends/wmi/wmivolume.cpp + + ) + set(solidlite_LIB_MOC_HDRS ${solidlite_LIB_MOC_HDRS} + backends/wmi/wmiblock.h + backends/wmi/wmicdrom.h + backends/wmi/wmidevice.h + backends/wmi/wmideviceinterface.h + backends/wmi/wmigenericinterface.h + backends/wmi/wmimanager.h + backends/wmi/wmiopticaldisc.h + backends/wmi/wmiportablemediaplayer.h + backends/wmi/wmistorageaccess.h + backends/wmi/wmistorage.h + backends/wmi/wmivolume.h + ) + endif(HAVE_WBEM AND NOT WINCE) +endif(WIN32) + +set(solidlite_OPTIONAL_LIBS) + +if(WIN32) + set(solidlite_OPTIONAL_LIBS ${solidlite_OPTIONAL_LIBS} ${KDEWIN_LIBRARY}) + if(HAVE_WBEM) + set(solidlite_OPTIONAL_LIBS ${solidlite_OPTIONAL_LIBS} ${WBEM_LIBRARIES}) + endif(HAVE_WBEM) +endif(WIN32) + +if(APPLE) + set(solidlite_OPTIONAL_LIBS ${IOKIT_LIBRARY}) +endif(APPLE) + +QT4_WRAP_CPP(solidlite_LIB_MOC_SRCS ${solidlite_LIB_MOC_HDRS} ) +add_library(solidlite ${solidlite_LIB_SRCS} ${solidlite_LIB_MOC_SRCS}) +# set_target_properties(solidlite PROPERTIES AUTOMOC TRUE) + +if ( UDEV_FOUND ) + set(solidlite_OPTIONAL_LIBS ${solidlite_OPTIONAL_LIBS} ${UDEV_LIBS}) +endif ( UDEV_FOUND ) + +target_link_libraries(solidlite ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${solidlite_OPTIONAL_LIBS} ) +target_link_libraries(solidlite LINK_INTERFACE_LIBRARIES ${QT_CORE_LIBRARY} ) + +if (WINCE) + target_link_libraries(solidlite ${WCECOMPAT_LIBRARIES}) +endif(WINCE) + +# set_target_properties(solidlite PROPERTIES +# VERSION ${GENERIC_LIB_VERSION} +# SOVERSION ${GENERIC_LIB_SOVERSION} +# ) + +#set(lexer_FILE predicate_lexer) +#set(parser_FILE predicate_parser) + +#find_package(Flex) +#macro_log_feature(FLEX_FOUND +# "Flex" +# "Allows the Solid predicate parser to be updated" +# "http://flex.sourceforge.net" +# FALSE +# "" +# "Required by the UpdateSolidPredicateParser target (mainly useful for developers)") + +#find_program(BISON_EXECUTABLE bison) +#macro_log_feature(BISON_EXECUTABLE +# "Bison" +# "Allows the Solid predicate parser to be updated" +# "http://www.gnu.org/software/bison" +# FALSE +# "" +# "Required by the UpdateSolidPredicateParser target (mainly useful for developers)") +#mark_as_advanced(BISON_EXECUTABLE) # don't show it in the simple view in cmake-gui/ccmake + +# if (FLEX_EXECUTABLE AND BISON_EXECUTABLE) +# +# add_custom_target(UpdateSolidPredicateParser +# COMMAND ${FLEX_EXECUTABLE} -P Solid -o${lexer_FILE}.c ${lexer_FILE}.l +# COMMAND ${BISON_EXECUTABLE} -p Solid -d -b ${parser_FILE} ${parser_FILE}.y +# COMMAND ${CMAKE_COMMAND} -E copy ${parser_FILE}.tab.c ${CMAKE_CURRENT_SOURCE_DIR}/${parser_FILE}.c +# COMMAND ${CMAKE_COMMAND} -E copy ${parser_FILE}.tab.h ${CMAKE_CURRENT_SOURCE_DIR}/${parser_FILE}.h +# COMMAND ${CMAKE_COMMAND} -E remove ${parser_FILE}.tab.c ${parser_FILE}.tab.h +# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +# +# else (FLEX_EXECUTABLE AND BISON_EXECUTABLE) +# add_custom_target(UpdateSolidPredicateParser +# COMMAND echo "flex and/or bison not found, so target UpdateSolidPredicateParser inactive") +# endif (FLEX_EXECUTABLE AND BISON_EXECUTABLE) + diff --git a/solid-lite/README b/solid-lite/README new file mode 100644 index 000000000..26a872b53 --- /dev/null +++ b/solid-lite/README @@ -0,0 +1,3 @@ +This is a (cut down) copy of Solid for KDE4.9.1 + +Only disk/medisplayer detection is remaining - as this is all Cantata needs. diff --git a/solid-lite/backends/hal/halblock.cpp b/solid-lite/backends/hal/halblock.cpp new file mode 100644 index 000000000..f5f5f09f8 --- /dev/null +++ b/solid-lite/backends/hal/halblock.cpp @@ -0,0 +1,53 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halblock.h" + +#include "haldevice.h" + +using namespace Solid::Backends::Hal; + +Block::Block(HalDevice *device) + : DeviceInterface(device) +{ + +} + +Block::~Block() +{ + +} + +int Block::deviceMajor() const +{ + return m_device->prop("block.major").toInt(); +} + +int Block::deviceMinor() const +{ + return m_device->prop("block.minor").toInt(); +} + +QString Block::device() const +{ + return m_device->prop("block.device").toString(); +} + +//#include "backends/hal/halblock.moc" diff --git a/solid-lite/backends/hal/halblock.h b/solid-lite/backends/hal/halblock.h new file mode 100644 index 000000000..edf4a9415 --- /dev/null +++ b/solid-lite/backends/hal/halblock.h @@ -0,0 +1,50 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_BLOCK_H +#define SOLID_BACKENDS_HAL_BLOCK_H + +#include +#include "haldeviceinterface.h" + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class Block : public DeviceInterface, virtual public Solid::Ifaces::Block +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::Block) + +public: + Block(HalDevice *device); + virtual ~Block(); + + virtual int deviceMajor() const; + virtual int deviceMinor() const; + virtual QString device() const; +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_BLOCK_H diff --git a/solid-lite/backends/hal/halcdrom.cpp b/solid-lite/backends/hal/halcdrom.cpp new file mode 100644 index 000000000..1216641db --- /dev/null +++ b/solid-lite/backends/hal/halcdrom.cpp @@ -0,0 +1,218 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halcdrom.h" + +#include +#include +#include +#include +#include + +#include "halfstabhandling.h" + +using namespace Solid::Backends::Hal; + +Cdrom::Cdrom(HalDevice *device) + : Storage(device), m_ejectInProgress(false) +{ + connect(device, SIGNAL(conditionRaised(QString,QString)), + this, SLOT(slotCondition(QString,QString))); + m_device->registerAction("eject", this, + SLOT(slotEjectRequested()), + SLOT(slotEjectDone(int,QString))); +} + +Cdrom::~Cdrom() +{ + +} + + +Solid::OpticalDrive::MediumTypes Cdrom::supportedMedia() const +{ + Solid::OpticalDrive::MediumTypes supported; + + QMap map; + map[Solid::OpticalDrive::Cdr] = "storage.cdrom.cdr"; + map[Solid::OpticalDrive::Cdrw] = "storage.cdrom.cdrw"; + map[Solid::OpticalDrive::Dvd] = "storage.cdrom.dvd"; + map[Solid::OpticalDrive::Dvdr] = "storage.cdrom.dvdr"; + map[Solid::OpticalDrive::Dvdrw] ="storage.cdrom.dvdrw"; + map[Solid::OpticalDrive::Dvdram] ="storage.cdrom.dvdram"; + map[Solid::OpticalDrive::Dvdplusr] ="storage.cdrom.dvdplusr"; + map[Solid::OpticalDrive::Dvdplusrw] ="storage.cdrom.dvdplusrw"; + map[Solid::OpticalDrive::Dvdplusdl] ="storage.cdrom.dvdplusrdl"; + map[Solid::OpticalDrive::Dvdplusdlrw] ="storage.cdrom.dvdplusrwdl"; + map[Solid::OpticalDrive::Bd] ="storage.cdrom.bd"; + map[Solid::OpticalDrive::Bdr] ="storage.cdrom.bdr"; + map[Solid::OpticalDrive::Bdre] ="storage.cdrom.bdre"; + map[Solid::OpticalDrive::HdDvd] ="storage.cdrom.hddvd"; + map[Solid::OpticalDrive::HdDvdr] ="storage.cdrom.hddvdr"; + map[Solid::OpticalDrive::HdDvdrw] ="storage.cdrom.hddvdrw"; + + foreach (const Solid::OpticalDrive::MediumType type, map.keys()) + { + if (m_device->prop(map[type]).toBool()) + { + supported|= type; + } + } + + return supported; +} + +int Cdrom::readSpeed() const +{ + return m_device->prop("storage.cdrom.read_speed").toInt(); +} + +int Cdrom::writeSpeed() const +{ + return m_device->prop("storage.cdrom.write_speed").toInt(); +} + +QList Cdrom::writeSpeeds() const +{ + QList speeds; + QStringList speed_strlist = m_device->prop("storage.cdrom.write_speeds").toStringList(); + + foreach (const QString &speed_str, speed_strlist) + { + speeds << speed_str.toInt(); + } + + return speeds; +} + +void Cdrom::slotCondition(const QString &name, const QString &/*reason */) +{ + if (name == "EjectPressed") + { + emit ejectPressed(m_device->udi()); + } +} + +bool Cdrom::eject() +{ + if (m_ejectInProgress) { + return false; + } + m_ejectInProgress = true; + m_device->broadcastActionRequested("eject"); + + if (FstabHandling::isInFstab(m_device->prop("block.device").toString())) { + return callSystemEject(); + } else { + return callHalDriveEject(); + } +} + +void Cdrom::slotEjectRequested() +{ + m_ejectInProgress = true; + emit ejectRequested(m_device->udi()); +} + +bool Cdrom::callHalDriveEject() +{ + QString udi = m_device->udi(); + QString interface = "org.freedesktop.Hal.Device.Storage"; + + // HACK: Eject doesn't work on cdrom drives when there's a mounted disc, + // let's try to workaround this by calling a child volume... + if (m_device->prop("storage.removable.media_available").toBool()) { + QDBusInterface manager("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + QDBusConnection::systemBus()); + + QDBusReply reply = manager.call("FindDeviceStringMatch", "info.parent", udi); + + if (reply.isValid()) + { + const QStringList udis = reply; + if (!udis.isEmpty()) { + udi = udis[0]; + interface = "org.freedesktop.Hal.Device.Volume"; + } + } + } + + QDBusConnection c = QDBusConnection::systemBus(); + QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Hal", udi, + interface, "Eject"); + + msg << QStringList(); + + + return c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError))); +} + +bool Solid::Backends::Hal::Cdrom::callSystemEject() +{ + const QString device = m_device->prop("block.device").toString(); + m_process = FstabHandling::callSystemCommand("eject", device, + this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); + + return m_process!=0; +} + +void Cdrom::slotDBusReply(const QDBusMessage &/*reply*/) +{ + m_ejectInProgress = false; + m_device->broadcastActionDone("eject"); +} + +void Cdrom::slotDBusError(const QDBusError &error) +{ + m_ejectInProgress = false; + + // TODO: Better error reporting here + m_device->broadcastActionDone("eject", Solid::UnauthorizedOperation, + QString(error.name()+": "+error.message())); +} + +void Solid::Backends::Hal::Cdrom::slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + Q_UNUSED(exitStatus); + if (m_ejectInProgress) { + m_ejectInProgress = false; + + if (exitCode==0) { + m_device->broadcastActionDone("eject"); + } else { + m_device->broadcastActionDone("eject", Solid::UnauthorizedOperation, + m_process->readAllStandardError()); + } + } + + delete m_process; +} + +void Cdrom::slotEjectDone(int error, const QString &errorString) +{ + m_ejectInProgress = false; + emit ejectDone(static_cast(error), errorString, m_device->udi()); +} + +//#include "backends/hal/halcdrom.moc" diff --git a/solid-lite/backends/hal/halcdrom.h b/solid-lite/backends/hal/halcdrom.h new file mode 100644 index 000000000..7f0d3e771 --- /dev/null +++ b/solid-lite/backends/hal/halcdrom.h @@ -0,0 +1,77 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_CDROM_H +#define SOLID_BACKENDS_HAL_CDROM_H + +#include +#include "halstorage.h" + +#include +#include +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class Cdrom : public Storage, virtual public Solid::Ifaces::OpticalDrive +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::OpticalDrive) + +public: + Cdrom(HalDevice *device); + virtual ~Cdrom(); + + virtual Solid::OpticalDrive::MediumTypes supportedMedia() const; + virtual int readSpeed() const; + virtual int writeSpeed() const; + virtual QList writeSpeeds() const; + virtual bool eject(); + +Q_SIGNALS: + void ejectPressed(const QString &udi); + void ejectDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void ejectRequested(const QString &udi); + +private Q_SLOTS: + void slotCondition(const QString &name, const QString &reason); + void slotDBusReply(const QDBusMessage &reply); + void slotDBusError(const QDBusError &error); + void slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + void slotEjectRequested(); + void slotEjectDone(int error, const QString &errorString); + +private: + bool callHalDriveEject(); + bool callSystemEject(); + + bool m_ejectInProgress; + QProcess *m_process; +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_CDROM_H diff --git a/solid-lite/backends/hal/haldevice.cpp b/solid-lite/backends/hal/haldevice.cpp new file mode 100644 index 000000000..d66a28201 --- /dev/null +++ b/solid-lite/backends/hal/haldevice.cpp @@ -0,0 +1,851 @@ +/* + Copyright 2005-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "haldevice.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "haldeviceinterface.h" +#include "halgenericinterface.h" +//#include "halprocessor.h" +#include "halblock.h" +#include "halstorageaccess.h" +#include "halstorage.h" +#include "halcdrom.h" +//#include "halvolume.h" +#include "halopticaldisc.h" +//#include "halcamera.h" +#include "halportablemediaplayer.h" +//#include "halnetworkinterface.h" +//#include "halacadapter.h" +//#include "halbattery.h" +//#include "halbutton.h" +//#include "halaudiointerface.h" +//#include "haldvbinterface.h" +//#include "halvideo.h" +//#include "halserialinterface.h" +//#include "halsmartcardreader.h" + +using namespace Solid::Backends::Hal; + +// Adapted from KLocale as Solid needs to be Qt-only +static QString formatByteSize(double size) +{ + // Per IEC 60027-2 + + // Binary prefixes + //Tebi-byte TiB 2^40 1,099,511,627,776 bytes + //Gibi-byte GiB 2^30 1,073,741,824 bytes + //Mebi-byte MiB 2^20 1,048,576 bytes + //Kibi-byte KiB 2^10 1,024 bytes + + QString s; + // Gibi-byte + if ( size >= 1073741824.0 ) + { + size /= 1073741824.0; + if ( size > 1024 ) // Tebi-byte + s = QObject::tr("%1 TiB").arg(QLocale().toString(size / 1024.0, 'f', 1)); + else + s = QObject::tr("%1 GiB").arg(QLocale().toString(size, 'f', 1)); + } + // Mebi-byte + else if ( size >= 1048576.0 ) + { + size /= 1048576.0; + s = QObject::tr("%1 MiB").arg(QLocale().toString(size, 'f', 1)); + } + // Kibi-byte + else if ( size >= 1024.0 ) + { + size /= 1024.0; + s = QObject::tr("%1 KiB").arg(QLocale().toString(size, 'f', 1)); + } + // Just byte + else if ( size > 0 ) + { + s = QObject::tr("%1 B").arg(QLocale().toString(size, 'f', 1)); + } + // Nothing + else + { + s = QObject::tr("0 B"); + } + return s; +} + +class Solid::Backends::Hal::HalDevicePrivate +{ +public: + HalDevicePrivate(const QString &udi) + : device("org.freedesktop.Hal", + udi, + "org.freedesktop.Hal.Device", + QDBusConnection::systemBus()), + cacheSynced(false), parent(0) { } + void checkCache(const QString &key = QString()); + + QDBusInterface device; + QMap cache; + QMap capListCache; + QSet invalidKeys; + + bool cacheSynced; + HalDevice *parent; +}; + +Q_DECLARE_METATYPE(ChangeDescription) +Q_DECLARE_METATYPE(QList) + +const QDBusArgument &operator<<(QDBusArgument &arg, const ChangeDescription &change) +{ + arg.beginStructure(); + arg << change.key << change.added << change.removed; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, ChangeDescription &change) +{ + arg.beginStructure(); + arg >> change.key >> change.added >> change.removed; + arg.endStructure(); + return arg; +} + +HalDevice::HalDevice(const QString &udi) + : Device(), d(new HalDevicePrivate(udi)) +{ + qDBusRegisterMetaType(); + qDBusRegisterMetaType< QList >(); + + d->device.connection().connect("org.freedesktop.Hal", + udi, "org.freedesktop.Hal.Device", + "PropertyModified", + this, SLOT(slotPropertyModified(int,QList))); + d->device.connection().connect("org.freedesktop.Hal", + udi, "org.freedesktop.Hal.Device", + "Condition", + this, SLOT(slotCondition(QString,QString))); +} + +HalDevice::~HalDevice() +{ + delete d->parent; + delete d; +} + +QString HalDevice::udi() const +{ + return prop("info.udi").toString(); +} + +QString HalDevice::parentUdi() const +{ + return prop("info.parent").toString(); +} + +QString HalDevice::vendor() const +{ + const QString category = prop("info.category").toString(); + + if (category == QLatin1String("battery")) { + return prop("battery.vendor").toString(); + } else { + return prop("info.vendor").toString(); + } +} + +QString HalDevice::product() const +{ + return prop("info.product").toString(); +} + +QString HalDevice::icon() const +{ + QString category = prop("info.category").toString(); + + if(parentUdi().isEmpty()) { + + QString formfactor = prop("system.formfactor").toString(); + if (formfactor=="laptop") { + return "computer-laptop"; + } else { + return "computer"; + } + + } else if (category=="storage" || category=="storage.cdrom") { + + if (prop("storage.drive_type").toString()=="floppy") { + return "media-floppy"; + } else if (prop("storage.drive_type").toString()=="cdrom") { + return "drive-optical"; + } else if (prop("storage.drive_type").toString()=="sd_mmc") { + return "media-flash-sd-mmc"; + } else if (prop("storage.hotpluggable").toBool()) { + if (prop("storage.bus").toString()=="usb") { + if (prop("storage.no_partitions_hint").toBool() + || prop("storage.removable.media_size").toLongLong()<4000000000LL) { + return "drive-removable-media-usb-pendrive"; + } else { + return "drive-removable-media-usb"; + } + } + + return "drive-removable-media"; + } + + return "drive-harddisk"; + + } else if (category=="volume" || category=="volume.disc") { + + QStringList capabilities = prop("info.capabilities").toStringList(); + + if (capabilities.contains("volume.disc")) { + bool has_video = prop("volume.disc.is_vcd").toBool() + || prop("volume.disc.is_svcd").toBool() + || prop("volume.disc.is_videodvd").toBool(); + bool has_audio = prop("volume.disc.has_audio").toBool(); + bool recordable = prop("volume.disc.is_blank").toBool() + || prop("volume.disc.is_appendable").toBool() + || prop("volume.disc.is_rewritable").toBool(); + + if (has_video) { + return "media-optical-video"; + } else if (has_audio) { + return "media-optical-audio"; + } else if (recordable) { + return "media-optical-recordable"; + } else { + return "media-optical"; + } + + } else { + if (!d->parent) { + d->parent = new HalDevice(parentUdi()); + } + QString iconName = d->parent->icon(); + + if (!iconName.isEmpty()) { + return iconName; + } + + return "drive-harddisk"; + } + + } /*else if (category=="camera") { + return "camera-photo"; + + } else if (category=="input") { + QStringList capabilities = prop("info.capabilities").toStringList(); + + if (capabilities.contains("input.mouse")) { + return "input-mouse"; + } else if (capabilities.contains("input.keyboard")) { + return "input-keyboard"; + } else if (capabilities.contains("input.joystick")) { + return "input-gaming"; + } else if (capabilities.contains("input.tablet")) { + return "input-tablet"; + } + + } */ else if (category=="portable_audio_player") { + QStringList protocols = prop("portable_audio_player.access_method.protocols").toStringList(); + + if (protocols.contains("ipod")) { + return "multimedia-player-apple-ipod"; + } else { + return "multimedia-player"; + } + } /* else if (category=="battery") { + return "battery"; + } else if (category=="processor") { + return "cpu"; // FIXME: Doesn't follow icon spec + } else if (category=="video4linux") { + return "camera-web"; + } else if (category == "alsa" || category == "oss") { + // Sorry about this const_cast, but it's the best way to not copy the code from + // AudioInterface. + const Hal::AudioInterface audioIface(const_cast(this)); + switch (audioIface.soundcardType()) { + case Solid::AudioInterface::InternalSoundcard: + return QLatin1String("audio-card"); + case Solid::AudioInterface::UsbSoundcard: + return QLatin1String("audio-card-usb"); + case Solid::AudioInterface::FirewireSoundcard: + return QLatin1String("audio-card-firewire"); + case Solid::AudioInterface::Headset: + if (udi().contains("usb", Qt::CaseInsensitive) || + audioIface.name().contains("usb", Qt::CaseInsensitive)) { + return QLatin1String("audio-headset-usb"); + } else { + return QLatin1String("audio-headset"); + } + case Solid::AudioInterface::Modem: + return QLatin1String("modem"); + } + } else if (category == "serial") { + // TODO - a serial device can be a modem, or just + // a COM port - need a new icon? + return QLatin1String("modem"); + } else if (category == "smart_card_reader") { + return QLatin1String("smart-card-reader"); + } */ + + return QString(); +} + +QStringList HalDevice::emblems() const +{ + QStringList res; + + if (queryDeviceInterface(Solid::DeviceInterface::StorageAccess)) { + bool isEncrypted = prop("volume.fsusage").toString()=="crypto"; + + const Hal::StorageAccess accessIface(const_cast(this)); + if (accessIface.isAccessible()) { + if (isEncrypted) { + res << "emblem-encrypted-unlocked"; + } else { + res << "emblem-mounted"; + } + } else { + if (isEncrypted) { + res << "emblem-encrypted-locked"; + } else { + res << "emblem-unmounted"; + } + } + } + + return res; +} + +QString HalDevice::description() const +{ + QString category = prop("info.category").toString(); + + if (category=="storage" || category=="storage.cdrom") { + return storageDescription(); + } else if (category=="volume" || category=="volume.disc") { + return volumeDescription(); + } /*else if (category=="net.80211") { + return QObject::tr("WLAN Interface"); + } else if (category=="net.80203") { + return QObject::tr("Networking Interface"); + } */ else { + return product(); + } +} + +QVariant HalDevice::prop(const QString &key) const +{ + d->checkCache(key); + return d->cache.value(key); +} + +void HalDevicePrivate::checkCache(const QString &key) +{ + if (cacheSynced) { + if (key.isEmpty()) { + if (invalidKeys.isEmpty()) { + return; + } + } else if (!invalidKeys.contains(key)) { + return; + } + } + + QDBusReply reply = device.call("GetAllProperties"); + + if (reply.isValid()) { + cache = reply; + } else { + qWarning() << Q_FUNC_INFO << " error: " << reply.error().name() + << ", " << reply.error().message() << endl; + cache = QVariantMap(); + } + + invalidKeys.clear(); + cacheSynced = true; + //qDebug( )<< q << udi() << "failure"; +} + +QMap HalDevice::allProperties() const +{ + d->checkCache(); + return d->cache; +} + +bool HalDevice::propertyExists(const QString &key) const +{ + d->checkCache(key); + return d->cache.value(key).isValid(); +} + +bool HalDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const +{ + // Special cases not matching with HAL capabilities + if (type==Solid::DeviceInterface::GenericInterface) { + return true; + } else if (type==Solid::DeviceInterface::StorageAccess) { + return prop("org.freedesktop.Hal.Device.Volume.method_names").toStringList().contains("Mount") + || prop("info.interfaces").toStringList().contains("org.freedesktop.Hal.Device.Volume.Crypto"); + } + /*else if (type==Solid::DeviceInterface::Video) { + if (!prop("video4linux.device").toString().contains("video" ) ) + return false; + } */else if (d->capListCache.contains(type)) { + return d->capListCache.value(type); + } + + QStringList cap_list = DeviceInterface::toStringList(type); + + foreach (const QString &cap, cap_list) { + QDBusReply reply = d->device.call("QueryCapability", cap); + + if (!reply.isValid()) { + qWarning() << Q_FUNC_INFO << " error: " << reply.error().name() << endl; + return false; + } + + if (reply) { + d->capListCache.insert(type, true); + return true; + } + } + + d->capListCache.insert(type, false); + return false; +} + +QObject *HalDevice::createDeviceInterface(const Solid::DeviceInterface::Type &type) +{ + if (!queryDeviceInterface(type)) { + return 0; + } + + DeviceInterface *iface = 0; + + switch (type) + { + case Solid::DeviceInterface::GenericInterface: + iface = new GenericInterface(this); + break; + //case Solid::DeviceInterface::Processor: + // iface = new Processor(this); + // break; + case Solid::DeviceInterface::Block: + iface = new Block(this); + break; + case Solid::DeviceInterface::StorageAccess: + iface = new StorageAccess(this); + break; + case Solid::DeviceInterface::StorageDrive: + iface = new Storage(this); + break; + case Solid::DeviceInterface::OpticalDrive: + iface = new Cdrom(this); + break; + case Solid::DeviceInterface::StorageVolume: + iface = new Volume(this); + break; + case Solid::DeviceInterface::OpticalDisc: + iface = new OpticalDisc(this); + break; + //case Solid::DeviceInterface::Camera: + // iface = new Camera(this); + // break; + case Solid::DeviceInterface::PortableMediaPlayer: + iface = new PortableMediaPlayer(this); + break; + /*case Solid::DeviceInterface::NetworkInterface: + iface = new NetworkInterface(this); + break; + case Solid::DeviceInterface::AcAdapter: + iface = new AcAdapter(this); + break; + case Solid::DeviceInterface::Battery: + iface = new Battery(this); + break; + case Solid::DeviceInterface::Button: + iface = new Button(this); + break; + case Solid::DeviceInterface::AudioInterface: + iface = new AudioInterface(this); + break; + case Solid::DeviceInterface::DvbInterface: + iface = new DvbInterface(this); + break; + case Solid::DeviceInterface::Video: + iface = new Video(this); + break; + case Solid::DeviceInterface::SerialInterface: + iface = new SerialInterface(this); + break; + case Solid::DeviceInterface::SmartCardReader: + iface = new SmartCardReader(this); + break; + case Solid::DeviceInterface::InternetGateway: + break; + case Solid::DeviceInterface::NetworkShare: + break; + */ + case Solid::DeviceInterface::Unknown: + case Solid::DeviceInterface::Last: + break; + } + + return iface; +} + +void HalDevice::slotPropertyModified(int /*count */, const QList &changes) +{ + QMap result; + + foreach (const ChangeDescription &change, changes) { + QString key = change.key; + bool added = change.added; + bool removed = change.removed; + + Solid::GenericInterface::PropertyChange type = Solid::GenericInterface::PropertyModified; + + if (added) { + type = Solid::GenericInterface::PropertyAdded; + } else if (removed) { + type = Solid::GenericInterface::PropertyRemoved; + } + + result[key] = type; + d->cache.remove(key); + + if (d->cache.isEmpty()) { + d->cacheSynced = false; + d->invalidKeys.clear(); + } else { + d->invalidKeys.insert(key); + } + } + + //qDebug() << this << "unsyncing the cache"; + emit propertyChanged(result); +} + +void HalDevice::slotCondition(const QString &condition, const QString &reason) +{ + emit conditionRaised(condition, reason); +} + +QString HalDevice::storageDescription() const +{ + QString description; + const Storage storageDrive(const_cast(this)); + Solid::StorageDrive::DriveType drive_type = storageDrive.driveType(); + bool drive_is_hotpluggable = storageDrive.isHotpluggable(); + + if (drive_type == Solid::StorageDrive::CdromDrive) { + const Cdrom opticalDrive(const_cast(this)); + Solid::OpticalDrive::MediumTypes mediumTypes = opticalDrive.supportedMedia(); + QString first; + QString second; + + first = QObject::tr("CD-ROM", "First item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Cdr) + first = QObject::tr("CD-R", "First item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Cdrw) + first = QObject::tr("CD-RW", "First item of %1%2 Drive sentence"); + + if (mediumTypes & Solid::OpticalDrive::Dvd) + second = QObject::tr("/DVD-ROM", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdplusr) + second = QObject::tr("/DVD+R", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdplusrw) + second = QObject::tr("/DVD+RW", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdr) + second = QObject::tr("/DVD-R", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdrw) + second = QObject::tr("/DVD-RW", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdram) + second = QObject::tr("/DVD-RAM", "Second item of %1%2 Drive sentence"); + if ((mediumTypes & Solid::OpticalDrive::Dvdr) && (mediumTypes & Solid::OpticalDrive::Dvdplusr)) { + if(mediumTypes & Solid::OpticalDrive::Dvdplusdl) + second = QObject::tr("/DVD±R DL", "Second item of %1%2 Drive sentence"); + else + second = QObject::tr("/DVD±R", "Second item of %1%2 Drive sentence"); + } + if ((mediumTypes & Solid::OpticalDrive::Dvdrw) && (mediumTypes & Solid::OpticalDrive::Dvdplusrw)) { + if((mediumTypes & Solid::OpticalDrive::Dvdplusdl) || (mediumTypes & Solid::OpticalDrive::Dvdplusdlrw)) + second = QObject::tr("/DVD±RW DL", "Second item of %1%2 Drive sentence"); + else + second = QObject::tr("/DVD±RW", "Second item of %1%2 Drive sentence"); + } + if (mediumTypes & Solid::OpticalDrive::Bd) + second = QObject::tr("/BD-ROM", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Bdr) + second = QObject::tr("/BD-R", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Bdre) + second = QObject::tr("/BD-RE", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::HdDvd) + second = QObject::tr("/HD DVD-ROM", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::HdDvdr) + second = QObject::tr("/HD DVD-R", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::HdDvdrw) + second = QObject::tr("/HD DVD-RW", "Second item of %1%2 Drive sentence"); + + if (drive_is_hotpluggable) { + description = QObject::tr("External %1%2 Drive", "%1 is CD-ROM/CD-R/etc; %2 is '/DVD-ROM'/'/DVD-R'/etc (with leading slash)").arg(first).arg(second); + } else { + description = QObject::tr("%1%2 Drive", "%1 is CD-ROM/CD-R/etc; %2 is '/DVD-ROM'/'/DVD-R'/etc (with leading slash)").arg(first).arg(second); + } + + return description; + } + + if (drive_type == Solid::StorageDrive::Floppy) { + if (drive_is_hotpluggable) + description = QObject::tr("External Floppy Drive"); + else + description = QObject::tr("Floppy Drive"); + + return description; + } + + bool drive_is_removable = storageDrive.isRemovable(); + + if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable) { + QString size_str = formatByteSize(prop("storage.size").toInt()); + if (!size_str.isEmpty()) { + if (drive_is_hotpluggable) { + description = QObject::tr("%1 External Hard Drive", "%1 is the size").arg(size_str); + } else { + description = QObject::tr("%1 Hard Drive", "%1 is the size").arg(size_str); + } + } else { + if (drive_is_hotpluggable) + description = QObject::tr("External Hard Drive"); + else + description = QObject::tr("Hard Drive"); + } + + return description; + } + + QString vendormodel_str; + QString model = prop("storage.model").toString(); + QString vendor = prop("storage.vendor").toString(); + + if (vendor.isEmpty()) { + if (!model.isEmpty()) + vendormodel_str = model; + } else { + if (model.isEmpty()) + vendormodel_str = vendor; + else + vendormodel_str = QObject::tr("%1 %2", "%1 is the vendor, %2 is the model of the device").arg(vendor).arg(model); + } + + if (vendormodel_str.isEmpty()) + description = QObject::tr("Drive"); + else + description = vendormodel_str; + + return description; +} + +QString HalDevice::volumeDescription() const +{ + QString description; + QString volume_label = prop("volume.label").toString(); + + if (!volume_label.isEmpty()) { + return volume_label; + } + + if (!d->parent) { + d->parent = new HalDevice(parentUdi()); + } + const Storage storageDrive(const_cast(d->parent)); + Solid::StorageDrive::DriveType drive_type = storageDrive.driveType(); + + /* Handle media in optical drives */ + if (drive_type == Solid::StorageDrive::CdromDrive) { + const OpticalDisc disc(const_cast(this)); + switch (disc.discType()) { + case Solid::OpticalDisc::UnknownDiscType: + case Solid::OpticalDisc::CdRom: + description = QObject::tr("CD-ROM"); + break; + + case Solid::OpticalDisc::CdRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank CD-R"); + else + description = QObject::tr("CD-R"); + break; + + case Solid::OpticalDisc::CdRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank CD-RW"); + else + description = QObject::tr("CD-RW"); + break; + + case Solid::OpticalDisc::DvdRom: + description = QObject::tr("DVD-ROM"); + break; + + case Solid::OpticalDisc::DvdRam: + if (disc.isBlank()) + description = QObject::tr("Blank DVD-RAM"); + else + description = QObject::tr("DVD-RAM"); + break; + + case Solid::OpticalDisc::DvdRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank DVD-R"); + else + description = QObject::tr("DVD-R"); + break; + + case Solid::OpticalDisc::DvdPlusRecordableDuallayer: + if (disc.isBlank()) + description = QObject::tr("Blank DVD+R Dual-Layer"); + else + description = QObject::tr("DVD+R Dual-Layer"); + break; + + case Solid::OpticalDisc::DvdRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank DVD-RW"); + else + description = QObject::tr("DVD-RW"); + break; + + case Solid::OpticalDisc::DvdPlusRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank DVD+R"); + else + description = QObject::tr("DVD+R"); + break; + + case Solid::OpticalDisc::DvdPlusRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank DVD+RW"); + else + description = QObject::tr("DVD+RW"); + break; + + case Solid::OpticalDisc::DvdPlusRewritableDuallayer: + if (disc.isBlank()) + description = QObject::tr("Blank DVD+RW Dual-Layer"); + else + description = QObject::tr("DVD+RW Dual-Layer"); + break; + + case Solid::OpticalDisc::BluRayRom: + description = QObject::tr("BD-ROM"); + break; + + case Solid::OpticalDisc::BluRayRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank BD-R"); + else + description = QObject::tr("BD-R"); + break; + + case Solid::OpticalDisc::BluRayRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank BD-RE"); + else + description = QObject::tr("BD-RE"); + break; + + case Solid::OpticalDisc::HdDvdRom: + description = QObject::tr("HD DVD-ROM"); + break; + + case Solid::OpticalDisc::HdDvdRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank HD DVD-R"); + else + description = QObject::tr("HD DVD-R"); + break; + + case Solid::OpticalDisc::HdDvdRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank HD DVD-RW"); + else + description = QObject::tr("HD DVD-RW"); + break; + } + + /* Special case for pure audio disc */ + if (disc.availableContent() == Solid::OpticalDisc::Audio) { + description = QObject::tr("Audio CD"); + } + + return description; + } + + bool drive_is_removable = storageDrive.isRemovable(); + bool drive_is_hotpluggable = storageDrive.isHotpluggable(); + bool drive_is_encrypted_container = prop("volume.fsusage").toString()=="crypto"; + + QString size_str = formatByteSize(prop("volume.size").toULongLong()); + if (drive_is_encrypted_container) { + if (!size_str.isEmpty()) { + description = QObject::tr("%1 Encrypted Container", "%1 is the size").arg(size_str); + } else { + description = QObject::tr("Encrypted Container"); + } + } else if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable) { + if (!size_str.isEmpty()) { + if (drive_is_hotpluggable) { + description = QObject::tr("%1 External Hard Drive", "%1 is the size").arg(size_str); + } else { + description = QObject::tr("%1 Hard Drive", "%1 is the size").arg(size_str); + } + } else { + if (drive_is_hotpluggable) + description = QObject::tr("External Hard Drive"); + else + description = QObject::tr("Hard Drive"); + } + } else { + if (drive_is_removable) { + description = QObject::tr("%1 Removable Media", "%1 is the size").arg(size_str); + } else { + description = QObject::tr("%1 Media", "%1 is the size").arg(size_str); + } + } + + return description; +} + +//#include "backends/hal/haldevice.moc" diff --git a/solid-lite/backends/hal/haldevice.h b/solid-lite/backends/hal/haldevice.h new file mode 100644 index 000000000..136258261 --- /dev/null +++ b/solid-lite/backends/hal/haldevice.h @@ -0,0 +1,87 @@ +/* + Copyright 2005,2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_HALDEVICE_H +#define SOLID_BACKENDS_HAL_HALDEVICE_H + +#include + +class QDBusVariant; + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class HalManager; +class HalDevicePrivate; + +struct ChangeDescription +{ + QString key; + bool added; + bool removed; +}; + +class HalDevice : public Solid::Ifaces::Device +{ + Q_OBJECT + +public: + HalDevice(const QString &udi); + virtual ~HalDevice(); + + virtual QString udi() const; + virtual QString parentUdi() const; + + virtual QString vendor() const; + virtual QString product() const; + virtual QString icon() const; + virtual QStringList emblems() const; + virtual QString description() const; + + virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type &type) const; + virtual QObject *createDeviceInterface(const Solid::DeviceInterface::Type &type); + +public: + QVariant prop(const QString &key) const; + QMap allProperties() const; + bool propertyExists(const QString &key) const; + +Q_SIGNALS: + void propertyChanged(const QMap &changes); + void conditionRaised(const QString &condition, const QString &reason); + +private Q_SLOTS: + void slotPropertyModified(int count, const QList &changes); + void slotCondition(const QString &condition, const QString &reason); + +private: + QString storageDescription() const; + QString volumeDescription() const; + + HalDevicePrivate *d; +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_HALDEVICE_H diff --git a/solid-lite/backends/hal/haldeviceinterface.cpp b/solid-lite/backends/hal/haldeviceinterface.cpp new file mode 100644 index 000000000..d479a14ea --- /dev/null +++ b/solid-lite/backends/hal/haldeviceinterface.cpp @@ -0,0 +1,34 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "haldeviceinterface.h" + +using namespace Solid::Backends::Hal; + +DeviceInterface::DeviceInterface(HalDevice *device) + : QObject(device), m_device(device) +{ +} + +DeviceInterface::~DeviceInterface() +{ +} + +//#include "backends/hal/haldeviceinterface.moc" diff --git a/solid-lite/backends/hal/haldeviceinterface.h b/solid-lite/backends/hal/haldeviceinterface.h new file mode 100644 index 000000000..1853c5a92 --- /dev/null +++ b/solid-lite/backends/hal/haldeviceinterface.h @@ -0,0 +1,172 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_DEVICEINTERFACE_H +#define SOLID_BACKENDS_HAL_DEVICEINTERFACE_H + +#include +#include "haldevice.h" + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class DeviceInterface : public QObject, virtual public Solid::Ifaces::DeviceInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::DeviceInterface) +public: + DeviceInterface(HalDevice *device); + virtual ~DeviceInterface(); + +protected: + HalDevice *m_device; + +public: + inline static QStringList toStringList(Solid::DeviceInterface::Type type) + { + QStringList list; + + switch(type) + { + case Solid::DeviceInterface::GenericInterface: + // Doesn't exist with HAL + break; + //case Solid::DeviceInterface::Processor: + // list << "processor"; + // break; + case Solid::DeviceInterface::Block: + list << "block"; + break; + case Solid::DeviceInterface::StorageAccess: + // Doesn't exist with HAL, but let's assume volume always cover this type + list << "volume"; + break; + case Solid::DeviceInterface::StorageDrive: + list << "storage"; + break; + case Solid::DeviceInterface::OpticalDrive: + list << "storage.cdrom"; + break; + case Solid::DeviceInterface::StorageVolume: + list << "volume"; + break; + case Solid::DeviceInterface::OpticalDisc: + list << "volume.disc"; + break; + //case Solid::DeviceInterface::Camera: + // list << "camera"; + // break; + case Solid::DeviceInterface::PortableMediaPlayer: + list << "portable_audio_player"; + break; + /*case Solid::DeviceInterface::NetworkInterface: + list << "net"; + break; + case Solid::DeviceInterface::AcAdapter: + list << "ac_adapter"; + break; + case Solid::DeviceInterface::Battery: + list << "battery"; + break; + case Solid::DeviceInterface::Button: + list << "button"; + break; + case Solid::DeviceInterface::AudioInterface: + list << "alsa" << "oss"; + break; + case Solid::DeviceInterface::DvbInterface: + list << "dvb"; + break; + case Solid::DeviceInterface::Video: + list << "video4linux"; + break; + case Solid::DeviceInterface::SerialInterface: + list << "serial"; + break; + case Solid::DeviceInterface::SmartCardReader: + list << "smart_card_reader"; + case Solid::DeviceInterface::InternetGateway: + list << "internet_gateway"; + case Solid::DeviceInterface::NetworkShare: + list << "networkshare"; + break; + */ + case Solid::DeviceInterface::Unknown: + break; + case Solid::DeviceInterface::Last: + break; + } + + return list; + } + + inline static Solid::DeviceInterface::Type fromString(const QString &capability) + { + /*if (capability == "processor") + return Solid::DeviceInterface::Processor; + else */if (capability == "block") + return Solid::DeviceInterface::Block; + else if (capability == "storage") + return Solid::DeviceInterface::StorageDrive; + else if (capability == "storage.cdrom") + return Solid::DeviceInterface::OpticalDrive; + else if (capability == "volume") + return Solid::DeviceInterface::StorageVolume; + else if (capability == "volume.disc") + return Solid::DeviceInterface::OpticalDisc; + /*else if (capability == "camera") + return Solid::DeviceInterface::Camera; */ + else if (capability == "portable_audio_player") + return Solid::DeviceInterface::PortableMediaPlayer; + /*else if (capability == "net") + return Solid::DeviceInterface::NetworkInterface; + else if (capability == "ac_adapter") + return Solid::DeviceInterface::AcAdapter; + else if (capability == "battery") + return Solid::DeviceInterface::Battery; + else if (capability == "button") + return Solid::DeviceInterface::Button; + else if (capability == "alsa" || capability == "oss") + return Solid::DeviceInterface::AudioInterface; + else if (capability == "dvb") + return Solid::DeviceInterface::DvbInterface; + else if (capability == "video4linux") + return Solid::DeviceInterface::Video; + else if (capability == "serial") + return Solid::DeviceInterface::SerialInterface; + else if (capability == "smart_card_reader") + return Solid::DeviceInterface::SmartCardReader; + else if (capability == "networkshare") + return Solid::DeviceInterface::NetworkShare;*/ + else + return Solid::DeviceInterface::Unknown; + } +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_DEVICEINTERFACE_H diff --git a/solid-lite/backends/hal/halfstabhandling.cpp b/solid-lite/backends/hal/halfstabhandling.cpp new file mode 100644 index 000000000..1774e11e9 --- /dev/null +++ b/solid-lite/backends/hal/halfstabhandling.cpp @@ -0,0 +1,194 @@ +/* + Copyright 2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halfstabhandling.h" + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_MNTENT_H +#include +#elif defined(HAVE_SYS_MNTENT_H) +#include +#endif + +#ifdef Q_OS_SOLARIS +#define FSTAB "/etc/vfstab" +#else +#define FSTAB "/etc/fstab" +#endif + +typedef QMultiHash QStringMultiHash; +SOLID_GLOBAL_STATIC(QStringMultiHash, globalMountPointsCache) + +QString _k_resolveSymLink(const QString &filename) +{ + QString resolved = filename; + QString tmp = QFile::symLinkTarget(filename); + + while (!tmp.isEmpty()) { + resolved = tmp; + tmp = QFile::symLinkTarget(resolved); + } + + return resolved; +} + +bool _k_isNetworkFileSystem(const QString &fstype, const QString &devName) +{ + if (fstype == "nfs" + || fstype == "nfs4" + || fstype == "smbfs" + || fstype == "cifs" + || devName.startsWith(QLatin1String("//"))) { + return true; + } + return false; +} + + +void _k_updateMountPointsCache() +{ + static bool firstCall = true; + static QTime elapsedTime; + + if (firstCall) { + firstCall = false; + elapsedTime.start(); + } else if (elapsedTime.elapsed()>10000) { + elapsedTime.restart(); + } else { + return; + } + + globalMountPointsCache->clear(); + +#ifdef HAVE_SETMNTENT + + struct mntent *fstab; + if ((fstab = setmntent(FSTAB, "r")) == 0) { + return; + } + + struct mntent *fe; + while ((fe = getmntent(fstab)) != 0) { + if (!_k_isNetworkFileSystem(fe->mnt_type, fe->mnt_fsname)) { + const QString device = _k_resolveSymLink(QFile::decodeName(fe->mnt_fsname)); + const QString mountpoint = _k_resolveSymLink(QFile::decodeName(fe->mnt_dir)); + + globalMountPointsCache->insert(device, mountpoint); + } + } + + endmntent(fstab); + +#else + + QFile fstab(FSTAB); + if (!fstab.open(QIODevice::ReadOnly)) { + return; + } + + QTextStream stream(&fstab); + QString line; + + while (!stream.atEnd()) { + line = stream.readLine().simplified(); + if (line.isEmpty() || line.startsWith('#')) { + continue; + } + + // not empty or commented out by '#' + const QStringList items = line.split(' '); + +#ifdef Q_OS_SOLARIS + if (items.count() < 5) { + continue; + } +#else + if (items.count() < 4) { + continue; + } +#endif + //prevent accessing a blocking directory + if (!_k_isNetworkFileSystem(items.at(2), items.at(0))) { + const QString device = _k_resolveSymLink(items.at(0)); + const QString mountpoint = _k_resolveSymLink(items.at(1)); + + globalMountPointsCache->insert(device, mountpoint); + } + } + + fstab.close(); +#endif +} + +bool Solid::Backends::Hal::FstabHandling::isInFstab(const QString &device) +{ + _k_updateMountPointsCache(); + const QString deviceToFind = _k_resolveSymLink(device); + + return globalMountPointsCache->contains(deviceToFind); +} + +QStringList Solid::Backends::Hal::FstabHandling::possibleMountPoints(const QString &device) +{ + _k_updateMountPointsCache(); + const QString deviceToFind = _k_resolveSymLink(device); + + return globalMountPointsCache->values(deviceToFind); +} + +QProcess *Solid::Backends::Hal::FstabHandling::callSystemCommand(const QString &commandName, + const QStringList &args, + QObject *obj, const char *slot) +{ + QStringList env = QProcess::systemEnvironment(); + env.replaceInStrings(QRegExp("^PATH=(.*)", Qt::CaseInsensitive), "PATH=/sbin:/bin:/usr/sbin/:/usr/bin"); + + QProcess *process = new QProcess(obj); + + QObject::connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), + obj, slot); + + process->setEnvironment(env); + process->start(commandName, args); + + if (process->waitForStarted()) { + return process; + } else { + delete process; + return 0; + } +} + +QProcess *Solid::Backends::Hal::FstabHandling::callSystemCommand(const QString &commandName, + const QString &device, + QObject *obj, const char *slot) +{ + return callSystemCommand(commandName, QStringList() << device, obj, slot); +} + diff --git a/solid-lite/backends/hal/halfstabhandling.h b/solid-lite/backends/hal/halfstabhandling.h new file mode 100644 index 000000000..bd20729aa --- /dev/null +++ b/solid-lite/backends/hal/halfstabhandling.h @@ -0,0 +1,53 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_FSTABHANDLING_H +#define SOLID_BACKENDS_HAL_FSTABHANDLING_H + +#include + +class QProcess; +class QObject; + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class FstabHandling +{ +public: + static bool isInFstab(const QString &device); + static QStringList possibleMountPoints(const QString &device); + static QProcess *callSystemCommand(const QString &commandName, + const QStringList &args, + QObject *obj, const char *slot); + static QProcess *callSystemCommand(const QString &commandName, + const QString &device, + QObject *obj, const char *slot); +}; +} +} +} + +#endif + + diff --git a/solid-lite/backends/hal/halgenericinterface.cpp b/solid-lite/backends/hal/halgenericinterface.cpp new file mode 100644 index 000000000..2ea73e67d --- /dev/null +++ b/solid-lite/backends/hal/halgenericinterface.cpp @@ -0,0 +1,56 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halgenericinterface.h" + +#include "haldevice.h" + +using namespace Solid::Backends::Hal; + +GenericInterface::GenericInterface(HalDevice *device) + : DeviceInterface(device) +{ + connect(device, SIGNAL(propertyChanged(QMap)), + this, SIGNAL(propertyChanged(QMap))); + connect(device, SIGNAL(conditionRaised(QString,QString)), + this, SIGNAL(conditionRaised(QString,QString))); +} + +GenericInterface::~GenericInterface() +{ + +} + +QVariant GenericInterface::property(const QString &key) const +{ + return m_device->prop(key); +} + +QMap GenericInterface::allProperties() const +{ + return m_device->allProperties(); +} + +bool GenericInterface::propertyExists(const QString &key) const +{ + return m_device->propertyExists(key); +} + +//#include "backends/hal/halgenericinterface.moc" diff --git a/solid-lite/backends/hal/halgenericinterface.h b/solid-lite/backends/hal/halgenericinterface.h new file mode 100644 index 000000000..e7a8c847a --- /dev/null +++ b/solid-lite/backends/hal/halgenericinterface.h @@ -0,0 +1,57 @@ +/* + Copyright 2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_GENERICINTERFACE_H +#define SOLID_BACKENDS_HAL_GENERICINTERFACE_H + +#include +#include +#include "haldeviceinterface.h" + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class HalDevice; + +class GenericInterface : public DeviceInterface, virtual public Solid::Ifaces::GenericInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::GenericInterface) + +public: + GenericInterface(HalDevice *device); + virtual ~GenericInterface(); + + virtual QVariant property(const QString &key) const; + virtual QMap allProperties() const; + virtual bool propertyExists(const QString &key) const; + +Q_SIGNALS: + void propertyChanged(const QMap &changes); + void conditionRaised(const QString &condition, const QString &reason); +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_GENERICINTERFACE_H diff --git a/solid-lite/backends/hal/halmanager.cpp b/solid-lite/backends/hal/halmanager.cpp new file mode 100644 index 000000000..1bd32fef5 --- /dev/null +++ b/solid-lite/backends/hal/halmanager.cpp @@ -0,0 +1,194 @@ +/* + Copyright 2005,2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halmanager.h" +#include "haldevice.h" +#include "haldeviceinterface.h" + +#include +#include +#include +#include + +using namespace Solid::Backends::Hal; + +class Solid::Backends::Hal::HalManagerPrivate +{ +public: + HalManagerPrivate() : manager("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + QDBusConnection::systemBus()), + cacheSynced(false) { } + + QDBusInterface manager; + QList devicesCache; + bool cacheSynced; + QSet supportedInterfaces; +}; + + +HalManager::HalManager(QObject *parent) + : DeviceManager(parent), d(new HalManagerPrivate()) +{ + d->manager.connection().connect("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "DeviceAdded", + this, SLOT(slotDeviceAdded(QString))); + + d->manager.connection().connect("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "DeviceRemoved", + this, SLOT(slotDeviceRemoved(QString))); + + d->supportedInterfaces << Solid::DeviceInterface::GenericInterface + //<< Solid::DeviceInterface::Processor + << Solid::DeviceInterface::Block + << Solid::DeviceInterface::StorageAccess + << Solid::DeviceInterface::StorageDrive + << Solid::DeviceInterface::OpticalDrive + << Solid::DeviceInterface::StorageVolume + << Solid::DeviceInterface::OpticalDisc + //<< Solid::DeviceInterface::Camera + << Solid::DeviceInterface::PortableMediaPlayer + /*<< Solid::DeviceInterface::NetworkInterface + << Solid::DeviceInterface::AcAdapter + << Solid::DeviceInterface::Battery + << Solid::DeviceInterface::Button + << Solid::DeviceInterface::AudioInterface + << Solid::DeviceInterface::DvbInterface + << Solid::DeviceInterface::Video + << Solid::DeviceInterface::SerialInterface + << Solid::DeviceInterface::SmartCardReader*/; +} + +HalManager::~HalManager() +{ + delete d; +} + +QString HalManager::udiPrefix() const +{ + return "/org/freedesktop/Hal"; +} + +QSet HalManager::supportedInterfaces() const +{ + return d->supportedInterfaces; +} + +QStringList HalManager::allDevices() +{ + if (d->cacheSynced) + { + return d->devicesCache; + } + + QDBusReply reply = d->manager.call("GetAllDevices"); + + if (!reply.isValid()) + { + qWarning() << Q_FUNC_INFO << " error: " << reply.error().name() << endl; + return QStringList(); + } + + d->devicesCache = reply; + d->cacheSynced = true; + + return reply; +} + +bool HalManager::deviceExists(const QString &udi) +{ + if (d->devicesCache.contains(udi)) + { + return true; + } + else if (d->cacheSynced) + { + return false; + } + + QDBusReply reply = d->manager.call("DeviceExists", udi); + + if (!reply.isValid()) + { + qWarning() << Q_FUNC_INFO << " error: " << reply.error().name() << endl; + return false; + } + + if (reply) + { + d->devicesCache.append(udi); + } + + return reply; +} + +QStringList HalManager::devicesFromQuery(const QString &parentUdi, + Solid::DeviceInterface::Type type) +{ + if ((parentUdi.isEmpty()) && (type == Solid::DeviceInterface::Unknown)) { + return allDevices(); + } + + QStringList result; + + foreach (const QString &udi, allDevices()) { + HalDevice device(udi); + + if ((!parentUdi.isEmpty()) && (parentUdi != device.parentUdi())) { + continue; + } + + if ((type != Solid::DeviceInterface::Unknown) && (!device.queryDeviceInterface(type))) { + continue; + } + + result << udi; + } + + return result; +} + +QObject *HalManager::createDevice(const QString &udi) +{ + if (deviceExists(udi)) { + return new HalDevice(udi); + } else { + return 0; + } +} + +void HalManager::slotDeviceAdded(const QString &udi) +{ + d->devicesCache.append(udi); + emit deviceAdded(udi); +} + +void HalManager::slotDeviceRemoved(const QString &udi) +{ + d->devicesCache.removeAll(udi); + emit deviceRemoved(udi); +} + +//#include "backends/hal/halmanager.moc" diff --git a/solid-lite/backends/hal/halmanager.h b/solid-lite/backends/hal/halmanager.h new file mode 100644 index 000000000..f10a7aad5 --- /dev/null +++ b/solid-lite/backends/hal/halmanager.h @@ -0,0 +1,68 @@ +/* + Copyright 2005,2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_HALMANAGER_H +#define SOLID_BACKENDS_HAL_HALMANAGER_H + +#include +#include + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class HalManagerPrivate; + +class HalManager : public Solid::Ifaces::DeviceManager +{ + Q_OBJECT + +public: + HalManager(QObject *parent); + virtual ~HalManager(); + + virtual QString udiPrefix() const ; + virtual QSet supportedInterfaces() const; + + bool deviceExists(const QString &udi); + virtual QStringList allDevices(); + + virtual QStringList devicesFromQuery(const QString &parentUdi, + Solid::DeviceInterface::Type type); + + virtual QObject *createDevice(const QString &udi); + +private Q_SLOTS: + void slotDeviceAdded(const QString &udi); + void slotDeviceRemoved(const QString &udi); + +private: + HalManagerPrivate *d; +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_HALMANAGER_H diff --git a/solid-lite/backends/hal/halopticaldisc.cpp b/solid-lite/backends/hal/halopticaldisc.cpp new file mode 100644 index 000000000..b6c378e6d --- /dev/null +++ b/solid-lite/backends/hal/halopticaldisc.cpp @@ -0,0 +1,158 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halopticaldisc.h" + +using namespace Solid::Backends::Hal; + +OpticalDisc::OpticalDisc(HalDevice *device) + : Volume(device) +{ + +} + +OpticalDisc::~OpticalDisc() +{ + +} + + +Solid::OpticalDisc::ContentTypes OpticalDisc::availableContent() const +{ + Solid::OpticalDisc::ContentTypes content; + + QMap map; + map[Solid::OpticalDisc::Audio] = "volume.disc.has_audio"; + map[Solid::OpticalDisc::Data] = "volume.disc.has_data"; + map[Solid::OpticalDisc::VideoCd] = "volume.disc.is_vcd"; + map[Solid::OpticalDisc::SuperVideoCd] = "volume.disc.is_svcd"; + map[Solid::OpticalDisc::VideoDvd] ="volume.disc.is_videodvd"; + map[Solid::OpticalDisc::VideoBluRay] ="volume.disc.is_blurayvideo"; + + foreach (const Solid::OpticalDisc::ContentType type, map.keys()) + { + if (m_device->prop(map[type]).toBool()) + { + content|= type; + } + } + + return content; +} + +Solid::OpticalDisc::DiscType OpticalDisc::discType() const +{ + QString type = m_device->prop("volume.disc.type").toString(); + + if (type == "cd_rom") + { + return Solid::OpticalDisc::CdRom; + } + else if (type == "cd_r") + { + return Solid::OpticalDisc::CdRecordable; + } + else if (type == "cd_rw") + { + return Solid::OpticalDisc::CdRewritable; + } + else if (type == "dvd_rom") + { + return Solid::OpticalDisc::DvdRom; + } + else if (type == "dvd_ram") + { + return Solid::OpticalDisc::DvdRam; + } + else if (type == "dvd_r") + { + return Solid::OpticalDisc::DvdRecordable; + } + else if (type == "dvd_rw") + { + return Solid::OpticalDisc::DvdRewritable; + } + else if (type == "dvd_plus_r") + { + return Solid::OpticalDisc::DvdPlusRecordable; + } + else if (type == "dvd_plus_rw") + { + return Solid::OpticalDisc::DvdPlusRewritable; + } + else if (type == "dvd_plus_r_dl") + { + return Solid::OpticalDisc::DvdPlusRecordableDuallayer; + } + else if (type == "dvd_plus_rw_dl") + { + return Solid::OpticalDisc::DvdPlusRewritableDuallayer; + } + else if (type == "bd_rom") + { + return Solid::OpticalDisc::BluRayRom; + } + else if (type == "bd_r") + { + return Solid::OpticalDisc::BluRayRecordable; + } + else if (type == "bd_re") + { + return Solid::OpticalDisc::BluRayRewritable; + } + else if (type == "hddvd_rom") + { + return Solid::OpticalDisc::HdDvdRom; + } + else if (type == "hddvd_r") + { + return Solid::OpticalDisc::HdDvdRecordable; + } + else if (type == "hddvd_rw") + { + return Solid::OpticalDisc::HdDvdRewritable; + } + else + { + return Solid::OpticalDisc::UnknownDiscType; + } +} + +bool OpticalDisc::isAppendable() const +{ + return m_device->prop("volume.disc.is_appendable").toBool(); +} + +bool OpticalDisc::isBlank() const +{ + return m_device->prop("volume.disc.is_blank").toBool(); +} + +bool OpticalDisc::isRewritable() const +{ + return m_device->prop("volume.disc.is_rewritable").toBool(); +} + +qulonglong OpticalDisc::capacity() const +{ + return m_device->prop("volume.disc.capacity").toULongLong(); +} + +//#include "backends/hal/halopticaldisc.moc" diff --git a/solid-lite/backends/hal/halopticaldisc.h b/solid-lite/backends/hal/halopticaldisc.h new file mode 100644 index 000000000..da9d90716 --- /dev/null +++ b/solid-lite/backends/hal/halopticaldisc.h @@ -0,0 +1,53 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_OPTICALDISC_H +#define SOLID_BACKENDS_HAL_OPTICALDISC_H + +#include +#include "halvolume.h" + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class OpticalDisc : public Volume, virtual public Solid::Ifaces::OpticalDisc +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::OpticalDisc) + +public: + OpticalDisc(HalDevice *device); + virtual ~OpticalDisc(); + + virtual Solid::OpticalDisc::ContentTypes availableContent() const; + virtual Solid::OpticalDisc::DiscType discType() const; + virtual bool isAppendable() const; + virtual bool isBlank() const; + virtual bool isRewritable() const; + virtual qulonglong capacity() const; +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_OPTICALDISC_H diff --git a/solid-lite/backends/hal/halportablemediaplayer.cpp b/solid-lite/backends/hal/halportablemediaplayer.cpp new file mode 100644 index 000000000..3ed51e0bc --- /dev/null +++ b/solid-lite/backends/hal/halportablemediaplayer.cpp @@ -0,0 +1,68 @@ +/* + Copyright 2006 Davide Bettio + Copyright 2007 Jeff Mitchell + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halportablemediaplayer.h" + +using namespace Solid::Backends::Hal; + +PortableMediaPlayer::PortableMediaPlayer(HalDevice *device) + : DeviceInterface(device) +{ + +} + +PortableMediaPlayer::~PortableMediaPlayer() +{ + +} + +QStringList PortableMediaPlayer::supportedProtocols() const +{ + return m_device->prop("portable_audio_player.access_method.protocols").toStringList(); +} + +QStringList PortableMediaPlayer::supportedDrivers(QString protocol) const +{ + QStringList drivers = m_device->prop("portable_audio_player.access_method.drivers").toStringList(); + if(protocol.isNull()) + return drivers; + QStringList returnedDrivers; + QString temp; + for(int i = 0; i < drivers.size(); i++) + { + temp = drivers.at(i); + if(m_device->prop("portable_audio_player." + temp + ".protocol") == protocol) + returnedDrivers << temp; + } + return returnedDrivers; +} + +QVariant PortableMediaPlayer::driverHandle(const QString &driver) const +{ + if (driver=="mtp") { + return m_device->prop("usb.serial"); + } + // TODO: Fill in the blank for other drivers + + return QVariant(); +} + +//#include "backends/hal/halportablemediaplayer.moc" diff --git a/solid-lite/backends/hal/halportablemediaplayer.h b/solid-lite/backends/hal/halportablemediaplayer.h new file mode 100644 index 000000000..2614276a1 --- /dev/null +++ b/solid-lite/backends/hal/halportablemediaplayer.h @@ -0,0 +1,55 @@ +/* + Copyright 2006 Davide Bettio + Copyright 2007 Jeff Mitchell + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_PORTABLEMEDIAPLAYER_H +#define SOLID_BACKENDS_HAL_PORTABLEMEDIAPLAYER_H + +#include +#include "haldeviceinterface.h" + +#include + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class HalDevice; + +class PortableMediaPlayer : public DeviceInterface, virtual public Solid::Ifaces::PortableMediaPlayer +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::PortableMediaPlayer) + +public: + PortableMediaPlayer(HalDevice *device); + virtual ~PortableMediaPlayer(); + + virtual QStringList supportedProtocols() const; + virtual QStringList supportedDrivers(QString protocol = QString()) const; + virtual QVariant driverHandle(const QString &driver) const; +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_PORTABLEMEDIAPLAYER_H diff --git a/solid-lite/backends/hal/halstorage.cpp b/solid-lite/backends/hal/halstorage.cpp new file mode 100644 index 000000000..5e6fdc4d6 --- /dev/null +++ b/solid-lite/backends/hal/halstorage.cpp @@ -0,0 +1,123 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halstorage.h" + +using namespace Solid::Backends::Hal; + +Storage::Storage(HalDevice *device) + : Block(device) +{ + +} + +Storage::~Storage() +{ + +} + +Solid::StorageDrive::Bus Storage::bus() const +{ + QString bus = m_device->prop("storage.bus").toString(); + + if (bus=="ide") + { + return Solid::StorageDrive::Ide; + } + else if (bus=="usb") + { + return Solid::StorageDrive::Usb; + } + else if (bus=="ieee1394") + { + return Solid::StorageDrive::Ieee1394; + } + else if (bus=="scsi") + { + return Solid::StorageDrive::Scsi; + } + else if (bus=="sata") + { + return Solid::StorageDrive::Sata; + } + else + { + return Solid::StorageDrive::Platform; + } +} + +Solid::StorageDrive::DriveType Storage::driveType() const +{ + QString type = m_device->prop("storage.drive_type").toString(); + + if (type=="disk") + { + return Solid::StorageDrive::HardDisk; + } + else if (type=="cdrom") + { + return Solid::StorageDrive::CdromDrive; + } + else if (type=="floppy") + { + return Solid::StorageDrive::Floppy; + } + else if (type=="tape") + { + return Solid::StorageDrive::Tape; + } + else if (type=="compact_flash") + { + return Solid::StorageDrive::CompactFlash; + } + else if (type=="memory_stick") + { + return Solid::StorageDrive::MemoryStick; + } + else if (type=="smart_media") + { + return Solid::StorageDrive::SmartMedia; + } + else if (type=="sd_mmc") + { + return Solid::StorageDrive::SdMmc; + } + else + { + return Solid::StorageDrive::HardDisk; + } +} + +bool Storage::isRemovable() const +{ + return m_device->prop("storage.removable").toBool(); +} + +bool Storage::isHotpluggable() const +{ + return m_device->prop("storage.hotpluggable").toBool(); +} + +qulonglong Storage::size() const +{ + return m_device->prop("storage.size").toULongLong(); +} + +//#include "backends/hal/halstorage.moc" diff --git a/solid-lite/backends/hal/halstorage.h b/solid-lite/backends/hal/halstorage.h new file mode 100644 index 000000000..c525f57da --- /dev/null +++ b/solid-lite/backends/hal/halstorage.h @@ -0,0 +1,53 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_STORAGE_H +#define SOLID_BACKENDS_HAL_STORAGE_H + +#include +#include "halblock.h" + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class Storage : public Block, virtual public Solid::Ifaces::StorageDrive +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::StorageDrive) + +public: + Storage(HalDevice *device); + virtual ~Storage(); + + virtual Solid::StorageDrive::Bus bus() const; + virtual Solid::StorageDrive::DriveType driveType() const; + + virtual bool isRemovable() const; + virtual bool isHotpluggable() const; + virtual qulonglong size() const; +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_STORAGE_H diff --git a/solid-lite/backends/hal/halstorageaccess.cpp b/solid-lite/backends/hal/halstorageaccess.cpp new file mode 100644 index 000000000..2c22318d5 --- /dev/null +++ b/solid-lite/backends/hal/halstorageaccess.cpp @@ -0,0 +1,516 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halstorageaccess.h" + +#include "halfstabhandling.h" +#include "../../genericinterface.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef Q_OS_FREEBSD +#include +#endif + +using namespace Solid::Backends::Hal; + +StorageAccess::StorageAccess(HalDevice *device) + : DeviceInterface(device), m_setupInProgress(false), m_teardownInProgress(false), m_ejectInProgress(false), + m_passphraseRequested(false) +{ + connect(device, SIGNAL(propertyChanged(QMap)), + this, SLOT(slotPropertyChanged(QMap))); + // Delay connecting to DBus signals to avoid the related time penalty + // in hot paths such as predicate matching + QTimer::singleShot(0, this, SLOT(connectDBusSignals())); +} + +StorageAccess::~StorageAccess() +{ + +} + +void StorageAccess::connectDBusSignals() +{ + m_device->registerAction("setup", this, + SLOT(slotSetupRequested()), + SLOT(slotSetupDone(int,QString))); + + m_device->registerAction("teardown", this, + SLOT(slotTeardownRequested()), + SLOT(slotTeardownDone(int,QString))); + + m_device->registerAction("eject", this, + SLOT(slotEjectRequested()), + SLOT(slotEjectDone(int,QString))); +} + +void StorageAccess::slotSetupDone(int error, const QString &errorString) +{ + m_setupInProgress = false; + emit setupDone(static_cast(error), errorString, m_device->udi()); +} + +void StorageAccess::slotTeardownDone(int error, const QString &errorString) +{ + m_teardownInProgress = false; + emit teardownDone(static_cast(error), errorString, m_device->udi()); +} + +void StorageAccess::slotEjectDone(int error, const QString &errorString) +{ + m_ejectInProgress = false; + emit ejectDone(static_cast(error), errorString, m_device->udi()); +} + +bool StorageAccess::isAccessible() const +{ + if (m_device->prop("info.interfaces").toStringList().contains("org.freedesktop.Hal.Device.Volume.Crypto")) { + + // Might be a bit slow, but I see no cleaner way to do this with HAL... + QDBusInterface manager("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + QDBusConnection::systemBus()); + + QDBusReply reply = manager.call("FindDeviceStringMatch", + "volume.crypto_luks.clear.backing_volume", + m_device->udi()); + + QStringList list = reply; + + return reply.isValid() && !list.isEmpty(); + + } else { + return m_device->prop("volume.is_mounted").toBool(); + } +} + +QString StorageAccess::filePath() const +{ + QString result = m_device->prop("volume.mount_point").toString(); + + if (result.isEmpty()) { + QStringList mountpoints + = FstabHandling::possibleMountPoints(m_device->prop("block.device").toString()); + if (mountpoints.size()==1) { + result = mountpoints.first(); + } + } + + return result; +} + +bool StorageAccess::isIgnored() const +{ + HalDevice lock("/org/freedesktop/Hal/devices/computer"); + bool isLocked = lock.prop("info.named_locks.Global.org.freedesktop.Hal.Device.Storage.locked").toBool(); + + if (m_device->prop("volume.ignore").toBool() || isLocked ){ + return true; + } + + const QString mount_point = StorageAccess(m_device).filePath(); + const bool mounted = m_device->prop("volume.is_mounted").toBool(); + if (!mounted) { + return false; + } else if (mount_point.startsWith(QLatin1String("/media/")) || mount_point.startsWith(QLatin1String("/mnt/"))) { + return false; + } + + /* Now be a bit more aggressive on what we want to ignore, + * the user generally need to check only what's removable or in /media + * the volumes mounted to make the system (/, /boot, /var, etc.) + * are useless to him. + */ + Solid::Device drive(m_device->prop("block.storage_device").toString()); + + const bool removable = drive.as()->property("storage.removable").toBool(); + const bool hotpluggable = drive.as()->property("storage.hotpluggable").toBool(); + + return !removable && !hotpluggable; +} + +bool StorageAccess::setup() +{ + if (m_teardownInProgress || m_setupInProgress || isAccessible()) { + return false; + } + m_setupInProgress = true; + m_device->broadcastActionRequested("setup"); + + if (m_device->prop("info.interfaces").toStringList().contains("org.freedesktop.Hal.Device.Volume.Crypto")) { + return requestPassphrase(); + } else if (FstabHandling::isInFstab(m_device->prop("block.device").toString())) { + return callSystemMount(); + } else { + return callHalVolumeMount(); + } +} + +bool StorageAccess::teardown() +{ + if (m_teardownInProgress || m_setupInProgress || !isAccessible()) { + return false; + } + m_teardownInProgress = true; + m_device->broadcastActionRequested("teardown"); + + if (m_device->prop("info.interfaces").toStringList().contains("org.freedesktop.Hal.Device.Volume.Crypto")) { + return callCryptoTeardown(); + } else if (FstabHandling::isInFstab(m_device->prop("block.device").toString())) { + return callSystemUnmount(); + } else { + return callHalVolumeUnmount(); + } +} + +void StorageAccess::slotPropertyChanged(const QMap &changes) +{ + if (changes.contains("volume.is_mounted")) + { + emit accessibilityChanged(isAccessible(), m_device->udi()); + } +} + +void StorageAccess::slotDBusReply(const QDBusMessage &/*reply*/) +{ + if (m_setupInProgress) { + m_setupInProgress = false; + m_device->broadcastActionDone("setup"); + } else if (m_teardownInProgress) { + m_teardownInProgress = false; + m_device->broadcastActionDone("teardown"); + + HalDevice drive(m_device->prop("block.storage_device").toString()); + if (drive.prop("storage.drive_type").toString()!="cdrom" + && drive.prop("storage.requires_eject").toBool()) { + + QString devnode = m_device->prop("block.device").toString(); + +#if defined(Q_OS_OPENBSD) + QString program = "cdio"; + QStringList args; + args << "-f" << devnode << "eject"; +#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) + devnode.remove("/dev/").replace("([0-9]).", "\\1"); + QString program = "cdcontrol"; + QStringList args; + args << "-f" << devnode << "eject"; +#else + QString program = "eject"; + QStringList args; + args << devnode; +#endif + + m_ejectInProgress = true; + m_device->broadcastActionRequested("eject"); + m_process = FstabHandling::callSystemCommand("eject", args, + this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); + } + } else if (m_ejectInProgress) { + m_ejectInProgress = false; + m_device->broadcastActionDone("eject"); + } +} + +void StorageAccess::slotDBusError(const QDBusError &error) +{ + // TODO: Better error reporting here + if (m_setupInProgress) { + m_setupInProgress = false; + m_device->broadcastActionDone("setup", Solid::UnauthorizedOperation, + QString(error.name()+": "+error.message())); + } else if (m_teardownInProgress) { + m_teardownInProgress = false; + m_device->broadcastActionDone("teardown", Solid::UnauthorizedOperation, + QString(error.name()+": "+error.message())); + } else if (m_ejectInProgress) { + m_ejectInProgress = false; + m_device->broadcastActionDone("eject", Solid::UnauthorizedOperation, + QString(error.name()+": "+error.message())); + } +} + +void Solid::Backends::Hal::StorageAccess::slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + Q_UNUSED(exitStatus); + if (m_setupInProgress) { + m_setupInProgress = false; + + if (exitCode==0) { + m_device->broadcastActionDone("setup"); + } else { + m_device->broadcastActionDone("setup", Solid::UnauthorizedOperation, + m_process->readAllStandardError()); + } + } else if (m_teardownInProgress) { + m_teardownInProgress = false; + if (exitCode==0) { + m_device->broadcastActionDone("teardown"); + } else { + m_device->broadcastActionDone("teardown", Solid::UnauthorizedOperation, + m_process->readAllStandardError()); + } + } else if (m_ejectInProgress) { + if (exitCode==0) { + m_ejectInProgress = false; + m_device->broadcastActionDone("eject"); + } else { + callHalVolumeEject(); + } + } + + delete m_process; +} + +void StorageAccess::slotSetupRequested() +{ + m_setupInProgress = true; + emit setupRequested(m_device->udi()); +} + +void StorageAccess::slotTeardownRequested() +{ + m_teardownInProgress = true; + emit teardownRequested(m_device->udi()); +} + +void StorageAccess::slotEjectRequested() +{ + m_ejectInProgress = true; +} + +QString generateReturnObjectPath() +{ + static int number = 1; + + return "/org/kde/solid/HalStorageAccess_"+QString::number(number++); +} + +bool StorageAccess::requestPassphrase() +{ + QString udi = m_device->udi(); + QString returnService = QDBusConnection::sessionBus().baseService(); + m_lastReturnObject = generateReturnObjectPath(); + + QDBusConnection::sessionBus().registerObject(m_lastReturnObject, this, + QDBusConnection::ExportScriptableSlots); + + + QWidget *activeWindow = QApplication::activeWindow(); + uint wId = 0; + if (activeWindow!=0) { + wId = (uint)activeWindow->winId(); + } + + QString appId = QCoreApplication::applicationName(); + + QDBusInterface soliduiserver("org.kde.kded", "/modules/soliduiserver", "org.kde.SolidUiServer"); + QDBusReply reply = soliduiserver.call("showPassphraseDialog", udi, + returnService, m_lastReturnObject, + wId, appId); + m_passphraseRequested = reply.isValid(); + if (!m_passphraseRequested) { + qWarning() << "Failed to call the SolidUiServer, D-Bus said:" << reply.error(); + } + return m_passphraseRequested; +} + +void StorageAccess::passphraseReply(const QString &passphrase) +{ + if (m_passphraseRequested) { + QDBusConnection::sessionBus().unregisterObject(m_lastReturnObject); + m_passphraseRequested = false; + if (!passphrase.isEmpty()) { + callCryptoSetup(passphrase); + } else { + m_setupInProgress = false; + m_device->broadcastActionDone("setup"); + } + } +} + +bool StorageAccess::callHalVolumeMount() +{ + QDBusConnection c = QDBusConnection::systemBus(); + QString udi = m_device->udi(); + QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume", + "Mount"); + + // HAL 0.5.12 supports using alternative drivers for the same filesystem. + // This is mainly used to integrate the ntfs-3g driver. + // Unfortunately, the primary driver gets used unless we + // specify some other driver (fstype) to the Mount method. + // TODO: Allow the user to choose the driver. + + QString fstype = m_device->prop("volume.fstype").toString(); + QStringList halOptions = m_device->prop("volume.mount.valid_options").toStringList(); + + QString alternativePreferred = m_device->prop("volume.fstype.alternative.preferred").toString(); + if (!alternativePreferred.isEmpty()) { + QStringList alternativeFstypes = m_device->prop("volume.fstype.alternative").toStringList(); + if (alternativeFstypes.contains(alternativePreferred)) { + fstype = alternativePreferred; + halOptions = m_device->prop("volume.mount."+fstype+".valid_options").toStringList(); + } + } + + QStringList options; + +#ifdef Q_OS_FREEBSD + QString uid="-u="; +#else + QString uid="uid="; +#endif + if (halOptions.contains(uid)) { + options << uid+QString::number(::getuid()); + } + +#ifdef Q_OS_FREEBSD + char *cType; + if ( fstype=="vfat" && halOptions.contains("-L=")) { + if ( (cType = getenv("LC_ALL")) || (cType = getenv("LC_CTYPE")) || (cType = getenv("LANG")) ) + options << "-L="+QString(cType); + } + else if ( (fstype.startsWith(QLatin1String("ntfs")) || fstype=="iso9660" || fstype=="udf") && halOptions.contains("-C=") ) { + if ((cType = getenv("LC_ALL")) || (cType = getenv("LC_CTYPE")) || (cType = getenv("LANG")) ) + options << "-C="+QString(nl_langinfo(CODESET)); + } +#else + if (fstype=="vfat" || fstype=="ntfs" || fstype=="iso9660" || fstype=="udf" ) { + if (halOptions.contains("utf8")) + options<<"utf8"; + else if (halOptions.contains("iocharset=")) + options<<"iocharset=utf8"; + if (halOptions.contains("shortname=")) + options<<"shortname=mixed"; + if (halOptions.contains("flush")) + options<<"flush"; + } + // pass our locale to the ntfs-3g driver so it can translate local characters + else if ( halOptions.contains("locale=") ) { + // have to obtain LC_CTYPE as returned by the `locale` command + // check in the same order as `locale` does + char *cType; + if ( (cType = getenv("LC_ALL")) || (cType = getenv("LC_CTYPE")) || (cType = getenv("LANG")) ) { + options << "locale="+QString(cType); + } + } +#endif + + msg << "" << fstype << options; + + return c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError))); +} + +bool StorageAccess::callHalVolumeUnmount() +{ + QDBusConnection c = QDBusConnection::systemBus(); + QString udi = m_device->udi(); + QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume", + "Unmount"); + + msg << QStringList(); + + return c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError))); +} + +bool StorageAccess::callHalVolumeEject() +{ + QString udi = m_device->udi(); + QString interface = "org.freedesktop.Hal.Device.Volume"; + + QDBusConnection c = QDBusConnection::systemBus(); + QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Hal", udi, + interface, "Eject"); + + msg << QStringList(); + + return c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError))); +} + +bool Solid::Backends::Hal::StorageAccess::callSystemMount() +{ + const QString device = m_device->prop("block.device").toString(); + m_process = FstabHandling::callSystemCommand("mount", device, + this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); + + return m_process!=0; +} + +bool Solid::Backends::Hal::StorageAccess::callSystemUnmount() +{ + const QString device = m_device->prop("block.device").toString(); + m_process = FstabHandling::callSystemCommand("umount", device, + this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); + + return m_process!=0; +} + +void StorageAccess::callCryptoSetup(const QString &passphrase) +{ + QDBusConnection c = QDBusConnection::systemBus(); + QString udi = m_device->udi(); + QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume.Crypto", + "Setup"); + + msg << passphrase; + + c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError))); +} + +bool StorageAccess::callCryptoTeardown() +{ + QDBusConnection c = QDBusConnection::systemBus(); + QString udi = m_device->udi(); + QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume.Crypto", + "Teardown"); + + return c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError))); +} + +//#include "backends/hal/halstorageaccess.moc" diff --git a/solid-lite/backends/hal/halstorageaccess.h b/solid-lite/backends/hal/halstorageaccess.h new file mode 100644 index 000000000..6a2e00aed --- /dev/null +++ b/solid-lite/backends/hal/halstorageaccess.h @@ -0,0 +1,101 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_STORAGEACCESS_H +#define SOLID_BACKENDS_HAL_STORAGEACCESS_H + +#include +#include "haldeviceinterface.h" + +#include +#include +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class StorageAccess : public DeviceInterface, virtual public Solid::Ifaces::StorageAccess +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::StorageAccess) + +public: + StorageAccess(HalDevice *device); + virtual ~StorageAccess(); + + virtual bool isAccessible() const; + virtual QString filePath() const; + virtual bool isIgnored() const; + virtual bool setup(); + virtual bool teardown(); + +Q_SIGNALS: + void accessibilityChanged(bool accessible, const QString &udi); + void setupDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void teardownDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void ejectDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void setupRequested(const QString &udi); + void teardownRequested(const QString &udi); + +private Q_SLOTS: + void connectDBusSignals(); + void slotPropertyChanged(const QMap &changes); + void slotDBusReply(const QDBusMessage &reply); + void slotDBusError(const QDBusError &error); + void slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + void slotSetupRequested(); + void slotTeardownRequested(); + void slotEjectRequested(); + void slotSetupDone(int error, const QString &errorString); + void slotTeardownDone(int error, const QString &errorString); + void slotEjectDone(int error, const QString &errorString); + +public Q_SLOTS: + Q_SCRIPTABLE Q_NOREPLY void passphraseReply(const QString &passphrase); + +private: + bool callHalVolumeMount(); + bool callHalVolumeUnmount(); + bool callHalVolumeEject(); + + bool callSystemMount(); + bool callSystemUnmount(); + + bool requestPassphrase(); + void callCryptoSetup(const QString &passphrase); + bool callCryptoTeardown(); + +private: + bool m_setupInProgress; + bool m_teardownInProgress; + bool m_ejectInProgress; + bool m_passphraseRequested; + QString m_lastReturnObject; + QProcess *m_process; +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_STORAGEACCESS_H diff --git a/solid-lite/backends/hal/halvolume.cpp b/solid-lite/backends/hal/halvolume.cpp new file mode 100644 index 000000000..f4d24a54f --- /dev/null +++ b/solid-lite/backends/hal/halvolume.cpp @@ -0,0 +1,123 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "halvolume.h" +#include "halstorageaccess.h" +#include "../../genericinterface.h" + +using namespace Solid::Backends::Hal; + +Volume::Volume(HalDevice *device) + : Block(device) +{ +} + +Volume::~Volume() +{ + +} + + +bool Volume::isIgnored() const +{ + static HalDevice lock("/org/freedesktop/Hal/devices/computer"); + bool isLocked = lock.prop("info.named_locks.Global.org.freedesktop.Hal.Device.Storage.locked").toBool(); + + if (m_device->prop("volume.ignore").toBool() || isLocked ){ + return true; + } + + const QString mount_point = StorageAccess(m_device).filePath(); + const bool mounted = m_device->prop("volume.is_mounted").toBool(); + if (!mounted) { + return false; + } else if (mount_point.startsWith(QLatin1String("/media/")) || mount_point.startsWith(QLatin1String("/mnt/"))) { + return false; + } + + /* Now be a bit more aggressive on what we want to ignore, + * the user generally need to check only what's removable or in /media + * the volumes mounted to make the system (/, /boot, /var, etc.) + * are useless to him. + */ + Solid::Device drive(m_device->prop("block.storage_device").toString()); + + const bool removable = drive.as()->property("storage.removable").toBool(); + const bool hotpluggable = drive.as()->property("storage.hotpluggable").toBool(); + + return !removable && !hotpluggable; +} + +Solid::StorageVolume::UsageType Volume::usage() const +{ + QString usage = m_device->prop("volume.fsusage").toString(); + + if (usage == "filesystem") + { + return Solid::StorageVolume::FileSystem; + } + else if (usage == "partitiontable") + { + return Solid::StorageVolume::PartitionTable; + } + else if (usage == "raid") + { + return Solid::StorageVolume::Raid; + } + else if (usage == "crypto") + { + return Solid::StorageVolume::Encrypted; + } + else if (usage == "unused") + { + return Solid::StorageVolume::Unused; + } + else + { + return Solid::StorageVolume::Other; + } +} + +QString Volume::fsType() const +{ + return m_device->prop("volume.fstype").toString(); +} + +QString Volume::label() const +{ + return m_device->prop("volume.label").toString(); +} + +QString Volume::uuid() const +{ + return m_device->prop("volume.uuid").toString(); +} + +qulonglong Volume::size() const +{ + return m_device->prop("volume.size").toULongLong(); +} + +QString Solid::Backends::Hal::Volume::encryptedContainerUdi() const +{ + return m_device->prop("volume.crypto_luks.clear.backing_volume").toString(); +} + +//#include "backends/hal/halvolume.moc" diff --git a/solid-lite/backends/hal/halvolume.h b/solid-lite/backends/hal/halvolume.h new file mode 100644 index 000000000..0061e8dfb --- /dev/null +++ b/solid-lite/backends/hal/halvolume.h @@ -0,0 +1,54 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_HAL_VOLUME_H +#define SOLID_BACKENDS_HAL_VOLUME_H + +#include +#include "halblock.h" + +namespace Solid +{ +namespace Backends +{ +namespace Hal +{ +class Volume : public Block, virtual public Solid::Ifaces::StorageVolume +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::StorageVolume) + +public: + Volume(HalDevice *device); + virtual ~Volume(); + + virtual bool isIgnored() const; + virtual Solid::StorageVolume::UsageType usage() const; + virtual QString fsType() const; + virtual QString label() const; + virtual QString uuid() const; + virtual qulonglong size() const; + virtual QString encryptedContainerUdi() const; +}; +} +} +} + +#endif // SOLID_BACKENDS_HAL_VOLUME_H diff --git a/solid-lite/backends/iokit/cfhelper.cpp b/solid-lite/backends/iokit/cfhelper.cpp new file mode 100644 index 000000000..c3c40ee60 --- /dev/null +++ b/solid-lite/backends/iokit/cfhelper.cpp @@ -0,0 +1,171 @@ +/* + Copyright 2009 Harald Fernengel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +#include + +/* helper classes to convert from CF types to Qt */ + +static QString q_toString(const CFStringRef &str) +{ + CFIndex length = CFStringGetLength(str); + QVarLengthArray buffer(length); + + CFRange range = { 0, length }; + CFStringGetCharacters(str, range, buffer.data()); + return QString(reinterpret_cast(buffer.data()), length); +} + +template +static inline T convertCFNumber(const CFNumberRef &num, CFNumberType type) +{ + T n; + CFNumberGetValue(num, type, &n); + return n; +} + +static QVariant q_toVariant(const CFTypeRef &obj) +{ + const CFTypeID typeId = CFGetTypeID(obj); + + if (typeId == CFStringGetTypeID()) + return QVariant(q_toString(static_cast(obj))); + + if (typeId == CFNumberGetTypeID()) { + const CFNumberRef num = static_cast(obj); + const CFNumberType type = CFNumberGetType(num); + switch (type) { + case kCFNumberSInt8Type: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberSInt16Type: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberSInt32Type: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberSInt64Type: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberCharType: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberShortType: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberIntType: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberLongType: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberLongLongType: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberFloatType: + return qVariantFromValue(convertCFNumber(num, type)); + case kCFNumberDoubleType: + return qVariantFromValue(convertCFNumber(num, type)); + default: + if (CFNumberIsFloatType(num)) + return qVariantFromValue(convertCFNumber(num, kCFNumberDoubleType)); + return qVariantFromValue(convertCFNumber(num, kCFNumberLongLongType)); + } + } + + if (typeId == CFDateGetTypeID()) { + QDateTime dt; + dt.setTime_t(uint(kCFAbsoluteTimeIntervalSince1970)); + return dt.addSecs(int(CFDateGetAbsoluteTime(static_cast(obj)))); + } + + if (typeId == CFDataGetTypeID()) { + const CFDataRef cfdata = static_cast(obj); + return QByteArray(reinterpret_cast(CFDataGetBytePtr(cfdata)), + CFDataGetLength(cfdata)); + } + + if (typeId == CFBooleanGetTypeID()) + return QVariant(bool(CFBooleanGetValue(static_cast(obj)))); + + if (typeId == CFArrayGetTypeID()) { + const CFArrayRef cfarray = static_cast(obj); + QList list; + CFIndex size = CFArrayGetCount(cfarray); + bool metNonString = false; + for (CFIndex i = 0; i < size; ++i) { + QVariant value = q_toVariant(CFArrayGetValueAtIndex(cfarray, i)); + if (value.type() != QVariant::String) + metNonString = true; + list << value; + } + if (metNonString) + return list; + else + return QVariant(list).toStringList(); + } + + if (typeId == CFDictionaryGetTypeID()) { + const CFDictionaryRef cfdict = static_cast(obj); + const CFTypeID arrayTypeId = CFArrayGetTypeID(); + int size = int(CFDictionaryGetCount(cfdict)); + QVarLengthArray keys(size); + QVarLengthArray values(size); + CFDictionaryGetKeysAndValues(cfdict, keys.data(), values.data()); + + QMultiMap map; + for (int i = 0; i < size; ++i) { + QString key = q_toString(static_cast(keys[i])); + + if (CFGetTypeID(values[i]) == arrayTypeId) { + const CFArrayRef cfarray = static_cast(values[i]); + CFIndex arraySize = CFArrayGetCount(cfarray); + for (CFIndex j = arraySize - 1; j >= 0; --j) + map.insert(key, q_toVariant(CFArrayGetValueAtIndex(cfarray, j))); + } else { + map.insert(key, q_toVariant(values[i])); + } + } + return map; + } + + return QVariant(); +} + +QMap q_toVariantMap (const CFMutableDictionaryRef &dict) +{ + Q_ASSERT(dict); + + QMap result; + + const int count = CFDictionaryGetCount(dict); + QVarLengthArray keys(count); + QVarLengthArray values(count); + + CFDictionaryGetKeysAndValues(dict, + const_cast(keys.data()), + const_cast(values.data())); + + for (int i = 0; i < count; ++i) { + const QString key = q_toString((CFStringRef)keys[i]); + const QVariant value = q_toVariant((CFTypeRef)values[i]); + result[key] = value; + } + + return result; +} + diff --git a/solid-lite/backends/iokit/iokitdevice.cpp b/solid-lite/backends/iokit/iokitdevice.cpp new file mode 100644 index 000000000..1dee412ed --- /dev/null +++ b/solid-lite/backends/iokit/iokitdevice.cpp @@ -0,0 +1,249 @@ +/* + Copyright 2009 Harald Fernengel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + + +#include "iokitdevice.h" +#include "iokitgenericinterface.h" +//#include "iokitprocessor.h" +//#include "iokitbattery.h" +//#include "iokitnetworkinterface.h" +//#include "iokitserialinterface.h" + +#include + +#include +#include +//#include + +#include + +// from cfhelper.cpp +extern QMap q_toVariantMap(const CFMutableDictionaryRef &dict); + +namespace Solid { namespace Backends { namespace IOKit { + +// returns a solid type from an entry and its properties +static Solid::DeviceInterface::Type typeFromEntry(const io_registry_entry_t &entry, + const QMap &properties) +{ + /* + if (IOObjectConformsTo(entry, kIOEthernetInterfaceClass)) + return Solid::DeviceInterface::NetworkInterface; + if (IOObjectConformsTo(entry, "AppleACPICPU")) + return Solid::DeviceInterface::Processor; + if (IOObjectConformsTo(entry, "IOSerialBSDClient")) + return Solid::DeviceInterface::SerialInterface; + if (IOObjectConformsTo(entry, "AppleSmartBattery")) + return Solid::DeviceInterface::Battery; + */ + return Solid::DeviceInterface::Unknown; +} + +// gets all properties from an entry into a QMap +static QMap getProperties(const io_registry_entry_t &entry) +{ + CFMutableDictionaryRef propertyDict = 0; + + if (IORegistryEntryCreateCFProperties(entry, &propertyDict, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) { + return QMap(); + } + + QMap result = q_toVariantMap(propertyDict); + + CFRelease(propertyDict); + + return result; +} + +// gets the parent's Udi from an entry +static QString getParentDeviceUdi(const io_registry_entry_t &entry) +{ + io_registry_entry_t parent = 0; + kern_return_t ret = IORegistryEntryGetParentEntry(entry, kIOServicePlane, &parent); + if (ret != KERN_SUCCESS) { + // don't release parent here - docs say only on success + return QString(); + } + + QString result; + io_string_t pathName; + ret = IORegistryEntryGetPath(parent, kIOServicePlane, pathName); + if (ret == KERN_SUCCESS) + result = QString::fromUtf8(pathName); + + // now we can release the parent + IOObjectRelease(parent); + + return result; +} + + +class IOKitDevicePrivate +{ +public: + inline IOKitDevicePrivate() + : type(Solid::DeviceInterface::Unknown) + {} + + void init(const QString &udiString, const io_registry_entry_t & entry); + + QString udi; + QString parentUdi; + QMap properties; + Solid::DeviceInterface::Type type; +}; + +void IOKitDevicePrivate::init(const QString &udiString, const io_registry_entry_t &entry) +{ + Q_ASSERT(entry != MACH_PORT_NULL); + + udi = udiString; + + properties = getProperties(entry); + + io_name_t className; + IOObjectGetClass(entry, className); + properties["className"] = QString::fromUtf8(className); + + parentUdi = getParentDeviceUdi(entry); + type = typeFromEntry(entry, properties); + + IOObjectRelease(entry); +} + +IOKitDevice::IOKitDevice(const QString &udi, const io_registry_entry_t &entry) + : d(new IOKitDevicePrivate) +{ + d->init(udi, entry); +} + +IOKitDevice::IOKitDevice(const QString &udi) + : d(new IOKitDevicePrivate) +{ + io_registry_entry_t entry = IORegistryEntryFromPath( + kIOMasterPortDefault, + udi.toLocal8Bit().constData()); + + if (entry == MACH_PORT_NULL) { + qDebug() << Q_FUNC_INFO << "Tried to create Device from invalid UDI" << udi; + return; + } + + d->init(udi, entry); +} + +IOKitDevice::~IOKitDevice() +{ + delete d; +} + +QString IOKitDevice::udi() const +{ + return d->udi; +} + +QString IOKitDevice::parentUdi() const +{ + return d->parentUdi; +} + +QString IOKitDevice::vendor() const +{ + return QString(); // TODO +} + +QString IOKitDevice::product() const +{ + return QString(); // TODO +} + +QString IOKitDevice::icon() const +{ + return QString(); // TODO +} + +QStringList IOKitDevice::emblems() const +{ + return QStringList(); // TODO +} + +QString IOKitDevice::description() const +{ + return product(); // TODO +} + +QVariant IOKitDevice::property(const QString &key) const +{ + return d->properties.value(key); +} + +QMap IOKitDevice::allProperties() const +{ + return d->properties; +} + +bool IOKitDevice::propertyExists(const QString &key) const +{ + return d->properties.contains(key); +} + +bool IOKitDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const +{ + return (type == Solid::DeviceInterface::GenericInterface + || type == d->type); +} + +QObject *IOKitDevice::createDeviceInterface(const Solid::DeviceInterface::Type &type) +{ + QObject *iface = 0; + + switch (type) + { + case Solid::DeviceInterface::GenericInterface: + iface = new GenericInterface(this); + break; + /* + case Solid::DeviceInterface::Processor: + if (d->type == Solid::DeviceInterface::Processor) + iface = new Processor(this); + break; + case Solid::DeviceInterface::NetworkInterface: + if (d->type == Solid::DeviceInterface::NetworkInterface) + iface = new NetworkInterface(this); + break; + case Solid::DeviceInterface::SerialInterface: + if (d->type == Solid::DeviceInterface::SerialInterface) + iface = new SerialInterface(this); + break; + case Solid::DeviceInterface::Battery: + if (d->type == Solid::DeviceInterface::Battery) + iface = new Battery(this); + break; + */ + // the rest is TODO + } + + + return iface; +} + + +} } } // namespaces + diff --git a/solid-lite/backends/iokit/iokitdevice.h b/solid-lite/backends/iokit/iokitdevice.h new file mode 100644 index 000000000..9e60d539b --- /dev/null +++ b/solid-lite/backends/iokit/iokitdevice.h @@ -0,0 +1,75 @@ +/* + Copyright 2009 Harald Fernengel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_IOKIT_IOKITDEVICE_H +#define SOLID_BACKENDS_IOKIT_IOKITDEVICE_H + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace IOKit +{ +class IOKitDevicePrivate; +class IOKitManager; + +class IOKitDevice : public Solid::Ifaces::Device +{ + Q_OBJECT + +public: + IOKitDevice(const QString &udi); + virtual ~IOKitDevice(); + + virtual QString udi() const; + virtual QString parentUdi() const; + + virtual QString vendor() const; + virtual QString product() const; + virtual QString icon() const; + virtual QStringList emblems() const; + virtual QString description() const; + + virtual QVariant property(const QString &key) const; + + virtual QMap allProperties() const; + + virtual bool propertyExists(const QString &key) const; + + virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type &type) const; + virtual QObject *createDeviceInterface(const Solid::DeviceInterface::Type &type); + +Q_SIGNALS: + void propertyChanged(const QMap &changes); + void conditionRaised(const QString &condition, const QString &reason); + +private: + friend class IOKitManager; + IOKitDevice(const QString &udi, const io_registry_entry_t &entry); + IOKitDevicePrivate * const d; +}; +} +} +} + +#endif // SOLID_BACKENDS_IOKIT_IOKITDEVICE_H diff --git a/solid-lite/backends/iokit/iokitdeviceinterface.cpp b/solid-lite/backends/iokit/iokitdeviceinterface.cpp new file mode 100644 index 000000000..be27139d4 --- /dev/null +++ b/solid-lite/backends/iokit/iokitdeviceinterface.cpp @@ -0,0 +1,34 @@ +/* + Copyright 2009 Harald Fernengel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "iokitdeviceinterface.h" + +using namespace Solid::Backends::IOKit; + +DeviceInterface::DeviceInterface(IOKitDevice *device) + : QObject(device), m_device(device) +{ +} + +DeviceInterface::~DeviceInterface() +{ +} + +//#include "backends/iokit/iokitdeviceinterface.moc" diff --git a/solid-lite/backends/iokit/iokitdeviceinterface.h b/solid-lite/backends/iokit/iokitdeviceinterface.h new file mode 100644 index 000000000..d5cff9d95 --- /dev/null +++ b/solid-lite/backends/iokit/iokitdeviceinterface.h @@ -0,0 +1,51 @@ +/* + Copyright 2009 Harald Fernengel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_IOKIT_DEVICEINTERFACE_H +#define SOLID_BACKENDS_IOKIT_DEVICEINTERFACE_H + +#include +#include "iokitdevice.h" + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace IOKit +{ +class DeviceInterface : public QObject, virtual public Solid::Ifaces::DeviceInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::DeviceInterface) +public: + DeviceInterface(IOKitDevice *device); + virtual ~DeviceInterface(); + +protected: + IOKitDevice *m_device; +}; +} +} +} + +#endif // SOLID_BACKENDS_IOKIT_DEVICEINTERFACE_H diff --git a/solid-lite/backends/iokit/iokitgenericinterface.cpp b/solid-lite/backends/iokit/iokitgenericinterface.cpp new file mode 100644 index 000000000..344ccf653 --- /dev/null +++ b/solid-lite/backends/iokit/iokitgenericinterface.cpp @@ -0,0 +1,52 @@ +/* + Copyright 2009 Harald Fernengel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "iokitgenericinterface.h" + +#include "iokitdevice.h" + +using namespace Solid::Backends::IOKit; + +GenericInterface::GenericInterface(IOKitDevice *device) + : DeviceInterface(device) +{ +} + +GenericInterface::~GenericInterface() +{ + +} + +QVariant GenericInterface::property(const QString &key) const +{ + return m_device->property(key); +} + +QMap GenericInterface::allProperties() const +{ + return m_device->allProperties(); +} + +bool GenericInterface::propertyExists(const QString &key) const +{ + return m_device->propertyExists(key); +} + +//#include "backends/iokit/iokitgenericinterface.moc" diff --git a/solid-lite/backends/iokit/iokitgenericinterface.h b/solid-lite/backends/iokit/iokitgenericinterface.h new file mode 100644 index 000000000..11cfc8fea --- /dev/null +++ b/solid-lite/backends/iokit/iokitgenericinterface.h @@ -0,0 +1,57 @@ +/* + Copyright 2009 Harald Fernengel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_IOKIT_GENERICINTERFACE_H +#define SOLID_BACKENDS_IOKIT_GENERICINTERFACE_H + +#include +#include +#include "iokitdeviceinterface.h" + +namespace Solid +{ +namespace Backends +{ +namespace IOKit +{ +class IOKitDevice; + +class GenericInterface : public DeviceInterface, virtual public Solid::Ifaces::GenericInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::GenericInterface) + +public: + GenericInterface(IOKitDevice *device); + virtual ~GenericInterface(); + + virtual QVariant property(const QString &key) const; + virtual QMap allProperties() const; + virtual bool propertyExists(const QString &key) const; + +Q_SIGNALS: + void propertyChanged(const QMap &changes); + void conditionRaised(const QString &condition, const QString &reason); +}; +} +} +} + +#endif // SOLID_BACKENDS_IOKIT_GENERICINTERFACE_H diff --git a/solid-lite/backends/iokit/iokitmanager.cpp b/solid-lite/backends/iokit/iokitmanager.cpp new file mode 100644 index 000000000..fcd748ef1 --- /dev/null +++ b/solid-lite/backends/iokit/iokitmanager.cpp @@ -0,0 +1,245 @@ +/* + Copyright 2009 Harald Fernengel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "iokitmanager.h" +#include "iokitdevice.h" + +#include + +#include +#include +#include + +#include + +namespace Solid { namespace Backends { namespace IOKit { + +class IOKitManagerPrivate +{ +public: + inline IOKitManagerPrivate() + : port(0), source(0) + {} + + IONotificationPortRef port; + CFRunLoopSourceRef source; + + static const char *typeToName(Solid::DeviceInterface::Type type); + static QStringList devicesFromRegistry(io_iterator_t it); + + QSet supportedInterfaces; +}; + +// gets all registry pathes from an iterator +QStringList IOKitManagerPrivate::devicesFromRegistry(io_iterator_t it) +{ + QStringList result; + io_object_t obj; + io_string_t pathName; + while ((obj = IOIteratorNext(it))) { + kern_return_t ret = IORegistryEntryGetPath(obj, kIOServicePlane, pathName); + if (ret != KERN_SUCCESS) { + qWarning() << Q_FUNC_INFO << "IORegistryEntryGetPath failed"; + continue; + } + result += QString::fromUtf8(pathName); + ret = IOObjectRelease(obj); + if (ret != KERN_SUCCESS) { + // very unlikely to happen - keep it a qDebug just in case. + // compiler will nuke this code in release builds. + qDebug() << Q_FUNC_INFO << "Unable to release object reference"; + } + } + IOObjectRelease(it); + + return result; +} + +const char *IOKitManagerPrivate::typeToName(Solid::DeviceInterface::Type type) +{ + switch (type) { + case Solid::DeviceInterface::Unknown: + return 0; + case Solid::DeviceInterface::NetworkInterface: + return kIOEthernetInterfaceClass; + case Solid::DeviceInterface::Processor: + return "AppleACPICPU"; + case Solid::DeviceInterface::SerialInterface: + return "IOSerialBSDClient"; + case Solid::DeviceInterface::Battery: + return "AppleSmartBattery"; + + //Solid::DeviceInterface::GenericInterface: + //Solid::DeviceInterface::Block: + //Solid::DeviceInterface::StorageAccess: + //Solid::DeviceInterface::StorageDrive: + //Solid::DeviceInterface::OpticalDrive: + //Solid::DeviceInterface::StorageVolume: + //Solid::DeviceInterface::OpticalDisc: + //Solid::DeviceInterface::Camera: + //Solid::DeviceInterface::PortableMediaPlayer: + //Solid::DeviceInterface::NetworkInterface: + //Solid::DeviceInterface::AcAdapter: + //Solid::DeviceInterface::Button: + //Solid::DeviceInterface::AudioInterface: + //Solid::DeviceInterface::DvbInterface: + //Solid::DeviceInterface::Video: + } + + return 0; +} + +IOKitManager::IOKitManager(QObject *parent) + : Solid::Ifaces::DeviceManager(parent), d(new IOKitManagerPrivate) +{ + d->port = IONotificationPortCreate(kIOMasterPortDefault); + if (!d->port) { + qWarning() << Q_FUNC_INFO << "Unable to create notification port"; + return; + } + + d->source = IONotificationPortGetRunLoopSource(d->port); + if (!d->source) { + qWarning() << Q_FUNC_INFO << "Unable to create notification source"; + return; + } + + CFRunLoopAddSource(CFRunLoopGetCurrent(), d->source, kCFRunLoopDefaultMode); + + d->supportedInterfaces << Solid::DeviceInterface::GenericInterface + << Solid::DeviceInterface::Processor + << Solid::DeviceInterface::Block + << Solid::DeviceInterface::StorageAccess + << Solid::DeviceInterface::StorageDrive + << Solid::DeviceInterface::OpticalDrive + << Solid::DeviceInterface::StorageVolume + << Solid::DeviceInterface::OpticalDisc + << Solid::DeviceInterface::Camera + << Solid::DeviceInterface::PortableMediaPlayer + << Solid::DeviceInterface::NetworkInterface + << Solid::DeviceInterface::AcAdapter + << Solid::DeviceInterface::Battery + << Solid::DeviceInterface::Button + << Solid::DeviceInterface::AudioInterface + << Solid::DeviceInterface::DvbInterface + << Solid::DeviceInterface::Video + << Solid::DeviceInterface::SerialInterface + << Solid::DeviceInterface::SmartCardReader; +} + +IOKitManager::~IOKitManager() +{ + if (d->source) + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), d->source, kCFRunLoopDefaultMode); + if (d->port) + IONotificationPortDestroy(d->port); + + delete d; +} + +QString IOKitManager::udiPrefix() const +{ + return QString(); //FIXME: We should probably use a prefix there... has to be tested on Mac +} + +QSet IOKitManager::supportedInterfaces() const +{ + return d->supportedInterfaces; +} + +QStringList IOKitManager::allDevices() +{ + // use an IORegistry Iterator to iterate over all devices in the service plane + + io_iterator_t it; + kern_return_t ret = IORegistryCreateIterator( + kIOMasterPortDefault, + kIOServicePlane, + kIORegistryIterateRecursively, + &it); + if (ret != KERN_SUCCESS) { + qWarning() << Q_FUNC_INFO << "unable to create iterator"; + return QStringList(); + } + + return IOKitManagerPrivate::devicesFromRegistry(it); +} + +QStringList IOKitManager::devicesFromQuery(const QString &parentUdi, + Solid::DeviceInterface::Type type) +{ + QStringList result; + + if (type == Solid::DeviceInterface::Unknown) { + // match all device interfaces + result = allDevices(); + } else { + const char *deviceClassName = IOKitManagerPrivate::typeToName(type); + if (!deviceClassName) + return QStringList(); + + CFMutableDictionaryRef matchingDict = IOServiceMatching(deviceClassName); + + if (!matchingDict) + return QStringList(); + + io_iterator_t it = 0; + + // note - IOServiceGetMatchingServices dereferences the dict + kern_return_t ret = IOServiceGetMatchingServices( + kIOMasterPortDefault, + matchingDict, + &it); + + result = IOKitManagerPrivate::devicesFromRegistry(it); + } + + // if the parentUdi is an empty string, return all matches + if (parentUdi.isEmpty()) + return result; + + // return only matches that start with the parent's UDI + QStringList filtered; + foreach (const QString &udi, result) { + if (udi.startsWith(parentUdi)) + filtered += udi; + } + + return filtered; +} + +QObject *IOKitManager::createDevice(const QString &udi) +{ + io_registry_entry_t entry = IORegistryEntryFromPath( + kIOMasterPortDefault, + udi.toLocal8Bit().constData()); + + // we have to do IOObjectConformsTo - comparing the class names is not good enough + //if (IOObjectConformsTo(entry, kIOEthernetInterfaceClass)) { + //} + + if (entry == MACH_PORT_NULL) + return 0; + + return new IOKitDevice(udi, entry); +} + +}}} // namespaces + diff --git a/solid-lite/backends/iokit/iokitmanager.h b/solid-lite/backends/iokit/iokitmanager.h new file mode 100644 index 000000000..d11b47090 --- /dev/null +++ b/solid-lite/backends/iokit/iokitmanager.h @@ -0,0 +1,62 @@ +/* + Copyright 2009 Harald Fernengel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_IOKIT_IOKITMANAGER_H +#define SOLID_BACKENDS_IOKIT_IOKITMANAGER_H + +#include +#include + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace IOKit +{ +class IOKitManagerPrivate; + +class IOKitManager : public Solid::Ifaces::DeviceManager +{ + Q_OBJECT + +public: + IOKitManager(QObject *parent); + virtual ~IOKitManager(); + + virtual QString udiPrefix() const ; + virtual QSet supportedInterfaces() const; + + virtual QStringList allDevices(); + virtual QStringList devicesFromQuery(const QString &parentUdi, + Solid::DeviceInterface::Type type); + virtual QObject *createDevice(const QString &udi); + +private: + IOKitManagerPrivate *d; +}; +} +} +} + +#endif // SOLID_BACKENDS_IOKIT_IOKITMANAGER_H + diff --git a/solid-lite/backends/shared/rootdevice.cpp b/solid-lite/backends/shared/rootdevice.cpp new file mode 100644 index 000000000..713664fa2 --- /dev/null +++ b/solid-lite/backends/shared/rootdevice.cpp @@ -0,0 +1,106 @@ +/* + Copyright 2010 Mario Bensi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "rootdevice.h" +#include + +using namespace Solid::Backends::Shared; + +RootDevice::RootDevice(const QString &udi, const QString &parentUdi) : + Solid::Ifaces::Device(), + m_udi(udi), + m_parentUdi(parentUdi), + m_vendor("KDE") +{ +} + +RootDevice::~RootDevice() +{ +} + +QString RootDevice::udi() const +{ + return m_udi; +} + +QString RootDevice::parentUdi() const +{ + return m_parentUdi; +} + +QString RootDevice::vendor() const +{ + return m_vendor; +} + +void RootDevice::setVendor(const QString &vendor) +{ + m_vendor = vendor; +} + +QString RootDevice::product() const +{ + return m_product; +} + +void RootDevice::setProduct(const QString &product) +{ + m_product = product; +} + +QString RootDevice::icon() const +{ + return m_icon; +} + +void RootDevice::setIcon(const QString &icon) +{ + m_icon = icon; +} + +QStringList RootDevice::emblems() const +{ + return m_emblems; +} + +void RootDevice::setEmblems(const QStringList &emblems) +{ + m_emblems = emblems; +} + +QString RootDevice::description() const +{ + return m_description; +} + +void RootDevice::setDescription(const QString &description) +{ + m_description = description; +} + +bool RootDevice::queryDeviceInterface(const Solid::DeviceInterface::Type&) const +{ + return false; +} + +QObject* RootDevice::createDeviceInterface(const Solid::DeviceInterface::Type&) +{ + return 0; +} diff --git a/solid-lite/backends/shared/rootdevice.h b/solid-lite/backends/shared/rootdevice.h new file mode 100644 index 000000000..9d8935c17 --- /dev/null +++ b/solid-lite/backends/shared/rootdevice.h @@ -0,0 +1,78 @@ +/* + Copyright 2010 Mario Bensi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_SHARED_ROOT_DEVICE_H +#define SOLID_BACKENDS_SHARED_ROOT_DEVICE_H + +#include + +#include + +namespace Solid +{ +namespace Backends +{ +namespace Shared +{ + +class RootDevice : public Solid::Ifaces::Device +{ + Q_OBJECT + +public: + explicit RootDevice(const QString &udi, const QString &parentUdi = QString()); + + virtual ~RootDevice(); + + virtual QString udi() const; + virtual QString parentUdi() const; + + virtual QString vendor() const; + void setVendor(const QString &vendor); + + virtual QString product() const; + void setProduct(const QString &product); + + virtual QString icon() const; + void setIcon(const QString &icon); + + virtual QStringList emblems() const; + void setEmblems(const QStringList &emblems); + + virtual QString description() const; + void setDescription(const QString &description); + + virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type &type) const; + + virtual QObject *createDeviceInterface(const Solid::DeviceInterface::Type &type); +private: + QString m_udi; + QString m_parentUdi; + QString m_vendor; + QString m_product; + QString m_icon; + QStringList m_emblems; + QString m_description; +}; + +} +} +} +#endif diff --git a/solid-lite/backends/shared/udevqt.h b/solid-lite/backends/shared/udevqt.h new file mode 100644 index 000000000..40b7bbe93 --- /dev/null +++ b/solid-lite/backends/shared/udevqt.h @@ -0,0 +1,155 @@ +/* + Copyright 2009 Benjamin K. Stuhl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDEVQT_H +#define UDEVQT_H + +#include +#include +#include +#include +#include + +#include +#include + +namespace UdevQt +{ + +class DevicePrivate; +class Device +{ + public: + Device(); + Device(const Device &other); + ~Device(); + Device &operator= (const Device &other); + + bool isValid() const; + QString subsystem() const; + QString devType() const; + QString name() const; + QString sysfsPath() const; + int sysfsNumber() const; + QString driver() const; + QString primaryDeviceFile() const; + QStringList alternateDeviceSymlinks() const; + QStringList deviceProperties() const; + Device parent() const; + + // ### should this really be a QVariant? as far as udev knows, everything is a string... + // see also Client::devicesByProperty + QVariant deviceProperty(const QString &name) const; + QString decodedDeviceProperty(const QString &name) const; + QVariant sysfsProperty(const QString &name) const; + Device ancestorOfType(const QString &subsys, const QString &devtype) const; + + private: + Device(DevicePrivate *devPrivate); + friend class Client; + friend class ClientPrivate; + + DevicePrivate *d; +}; + +typedef QList DeviceList; + +class ClientPrivate; +class Client : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QStringList watchedSubsystems READ watchedSubsystems WRITE setWatchedSubsystems) + + public: + Client(QObject *parent = 0); + Client(const QStringList &subsystemList, QObject *parent = 0); + ~Client(); + + QStringList watchedSubsystems() const; + void setWatchedSubsystems(const QStringList &subsystemList); + + DeviceList allDevices(); + DeviceList devicesByProperty(const QString &property, const QVariant &value); + DeviceList devicesBySubsystem(const QString &subsystem); + Device deviceByDeviceFile(const QString &deviceFile); + Device deviceBySysfsPath(const QString &sysfsPath); + Device deviceBySubsystemAndName(const QString &subsystem, const QString &name); + + signals: + void deviceAdded(const UdevQt::Device &dev); + void deviceRemoved(const UdevQt::Device &dev); + void deviceChanged(const UdevQt::Device &dev); + void deviceOnlined(const UdevQt::Device &dev); + void deviceOfflined(const UdevQt::Device &dev); + + private: + friend class ClientPrivate; + Q_PRIVATE_SLOT(d, void _uq_monitorReadyRead(int fd)) + ClientPrivate *d; +}; + +class DevicePrivate +{ + public: + DevicePrivate(struct udev_device *udev_, bool ref = true); + ~DevicePrivate(); + DevicePrivate &operator=(const DevicePrivate& other); + + QString decodePropertyValue(const QByteArray &encoded) const; + + struct udev_device *udev; +}; + + +class ClientPrivate +{ + public: + enum ListenToWhat { ListenToList, ListenToNone }; + + ClientPrivate(Client *q_); + ~ClientPrivate(); + + void init(const QStringList &subsystemList, ListenToWhat what); + void setWatchedSubsystems(const QStringList &subsystemList); + void _uq_monitorReadyRead(int fd); + DeviceList deviceListFromEnumerate(struct udev_enumerate *en); + + struct udev *udev; + struct udev_monitor *monitor; + Client *q; + QSocketNotifier *monitorNotifier; + QStringList watchedSubsystems; +}; + +inline QStringList listFromListEntry(struct udev_list_entry *list) +{ + QStringList ret; + struct udev_list_entry *entry; + + udev_list_entry_foreach(entry, list) { + ret << QString::fromLatin1(udev_list_entry_get_name(entry)); + } + return ret; +} + +} + +#endif diff --git a/solid-lite/backends/shared/udevqt_p.h b/solid-lite/backends/shared/udevqt_p.h new file mode 100644 index 000000000..189a5ff88 --- /dev/null +++ b/solid-lite/backends/shared/udevqt_p.h @@ -0,0 +1,82 @@ +/* + Copyright 2009 Benjamin K. Stuhl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDEVQT_P_H +#define UDEVQT_P_H + +extern "C" +{ +#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE +#include +} + +class QByteArray; +class QSocketNotifier; + +namespace UdevQt +{ + +class DevicePrivate +{ + public: + DevicePrivate(struct udev_device *udev_, bool ref = true); + ~DevicePrivate(); + DevicePrivate &operator=(const DevicePrivate& other); + + QString decodePropertyValue(const QByteArray &encoded) const; + + struct udev_device *udev; +}; + + +class ClientPrivate +{ + public: + enum ListenToWhat { ListenToList, ListenToNone }; + + ClientPrivate(Client *q_); + ~ClientPrivate(); + + void init(const QStringList &subsystemList, ListenToWhat what); + void setWatchedSubsystems(const QStringList &subsystemList); + void _uq_monitorReadyRead(int fd); + DeviceList deviceListFromEnumerate(struct udev_enumerate *en); + + struct udev *udev; + struct udev_monitor *monitor; + Client *q; + QSocketNotifier *monitorNotifier; + QStringList watchedSubsystems; +}; + +inline QStringList listFromListEntry(struct udev_list_entry *list) +{ + QStringList ret; + struct udev_list_entry *entry; + + udev_list_entry_foreach(entry, list) { + ret << QString::fromLatin1(udev_list_entry_get_name(entry)); + } + return ret; +} + +} + +#endif diff --git a/solid-lite/backends/shared/udevqtclient.cpp b/solid-lite/backends/shared/udevqtclient.cpp new file mode 100644 index 000000000..81d4100cf --- /dev/null +++ b/solid-lite/backends/shared/udevqtclient.cpp @@ -0,0 +1,256 @@ +/* + Copyright 2009 Benjamin K. Stuhl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevqt.h" +// #include "udevqt_p.h" + +#include +#include + +namespace UdevQt { + +ClientPrivate::ClientPrivate(Client *q_) + : udev(0), monitor(0), q(q_), monitorNotifier(0) +{ +} + +ClientPrivate::~ClientPrivate() +{ + udev_unref(udev); + delete monitorNotifier; + + if (monitor) + udev_monitor_unref(monitor); +} + +void ClientPrivate::init(const QStringList &subsystemList, ListenToWhat what) +{ + udev = udev_new(); + + if (what != ListenToNone) { + setWatchedSubsystems(subsystemList); + } +} + +void ClientPrivate::setWatchedSubsystems(const QStringList &subsystemList) +{ + // create a listener + struct udev_monitor *newM = udev_monitor_new_from_netlink(udev, "udev"); + + if (!newM) { + qWarning("UdevQt: unable to create udev monitor connection"); + return; + } + + // apply our filters; an empty list means listen to everything + foreach (const QString& subsysDevtype, subsystemList) { + int ix = subsysDevtype.indexOf("/"); + + if (ix > 0) { + QByteArray subsystem = subsysDevtype.left(ix).toLatin1(); + QByteArray devType = subsysDevtype.mid(ix + 1).toLatin1(); + udev_monitor_filter_add_match_subsystem_devtype(newM, subsystem.constData(), devType.constData()); + } else { + udev_monitor_filter_add_match_subsystem_devtype(newM, subsysDevtype.toLatin1().constData(), NULL); + } + } + + // start the new monitor receiving + udev_monitor_enable_receiving(newM); + QSocketNotifier *sn = new QSocketNotifier(udev_monitor_get_fd(newM), QSocketNotifier::Read); + QObject::connect(sn, SIGNAL(activated(int)), q, SLOT(_uq_monitorReadyRead(int))); + + // kill any previous monitor + delete monitorNotifier; + if (monitor) + udev_monitor_unref(monitor); + + // and save our new one + monitor = newM; + monitorNotifier = sn; + watchedSubsystems = subsystemList; +} + +void ClientPrivate::_uq_monitorReadyRead(int fd) +{ + Q_UNUSED(fd); + monitorNotifier->setEnabled(false); + struct udev_device *dev = udev_monitor_receive_device(monitor); + monitorNotifier->setEnabled(true); + + if (!dev) + return; + + Device device(new DevicePrivate(dev, false)); + + QByteArray action(udev_device_get_action(dev)); + if (action == "add") { + emit q->deviceAdded(device); + } else if (action == "remove") { + emit q->deviceRemoved(device); + } else if (action == "change") { + emit q->deviceChanged(device); + } else if (action == "online") { + emit q->deviceOnlined(device); + } else if (action == "offline") { + emit q->deviceOfflined(device); + } else { + qWarning("UdevQt: unhandled device action \"%s\"", action.constData()); + } +} + +DeviceList ClientPrivate::deviceListFromEnumerate(struct udev_enumerate *en) +{ + DeviceList ret; + struct udev_list_entry *list, *entry; + + udev_enumerate_scan_devices(en); + list = udev_enumerate_get_list_entry(en); + udev_list_entry_foreach(entry, list) { + struct udev_device *ud = udev_device_new_from_syspath(udev_enumerate_get_udev(en), + udev_list_entry_get_name(entry)); + + if (!ud) + continue; + + ret << Device(new DevicePrivate(ud, false)); + } + + udev_enumerate_unref(en); + + return ret; +} + + +Client::Client(QObject *parent) + : QObject(parent) + , d(new ClientPrivate(this)) +{ + d->init(QStringList(), ClientPrivate::ListenToNone); +} + +Client::Client(const QStringList& subsystemList, QObject *parent) + : QObject(parent) + , d(new ClientPrivate(this)) +{ + d->init(subsystemList, ClientPrivate::ListenToList); +} + +Client::~Client() +{ + delete d; +} + +QStringList Client::watchedSubsystems() const +{ + // we're watching a specific list + if (!d->watchedSubsystems.isEmpty()) + return d->watchedSubsystems; + + // we're not watching anything + if (!d->monitor) + return QStringList(); + + // we're watching everything: figure out what "everything" currently is + // we don't cache it, since it may be subject to change, depending on hotplug + struct udev_enumerate *en = udev_enumerate_new(d->udev); + udev_enumerate_scan_subsystems(en); + QStringList s = listFromListEntry(udev_enumerate_get_list_entry(en)); + udev_enumerate_unref(en); + return s; +} + +void Client::setWatchedSubsystems(const QStringList &subsystemList) +{ + d->setWatchedSubsystems(subsystemList); +} + +DeviceList Client::devicesByProperty(const QString &property, const QVariant &value) +{ + struct udev_enumerate *en = udev_enumerate_new(d->udev); + + if (value.isValid()) { + udev_enumerate_add_match_property(en, property.toLatin1().constData(), value.toString().toLatin1().constData()); + } else { + udev_enumerate_add_match_property(en, property.toLatin1().constData(), NULL); + } + + return d->deviceListFromEnumerate(en); +} + +DeviceList Client::allDevices() +{ + struct udev_enumerate *en = udev_enumerate_new(d->udev); + return d->deviceListFromEnumerate(en); +} + +DeviceList Client::devicesBySubsystem(const QString &subsystem) +{ + struct udev_enumerate *en = udev_enumerate_new(d->udev); + + udev_enumerate_add_match_subsystem(en, subsystem.toLatin1().constData()); + return d->deviceListFromEnumerate(en); +} + +Device Client::deviceByDeviceFile(const QString &deviceFile) +{ + struct stat sb; + + if (stat(deviceFile.toLatin1().constData(), &sb) != 0) + return Device(); + + struct udev_device *ud = 0; + + if (S_ISBLK(sb.st_mode)) + ud = udev_device_new_from_devnum(d->udev, 'b', sb.st_rdev); + else if (S_ISCHR(sb.st_mode)) + ud = udev_device_new_from_devnum(d->udev, 'c', sb.st_rdev); + + if (!ud) + return Device(); + + return Device(new DevicePrivate(ud, false)); +} + +Device Client::deviceBySysfsPath(const QString &sysfsPath) +{ + struct udev_device *ud = udev_device_new_from_syspath(d->udev, sysfsPath.toLatin1().constData()); + + if (!ud) + return Device(); + + return Device(new DevicePrivate(ud, false)); +} + +Device Client::deviceBySubsystemAndName(const QString &subsystem, const QString &name) +{ + struct udev_device *ud = udev_device_new_from_subsystem_sysname(d->udev, + subsystem.toLatin1().constData(), + name.toLatin1().constData()); + + if (!ud) + return Device(); + + return Device(new DevicePrivate(ud, false)); +} + +} + +//#include "udevqt.moc" diff --git a/solid-lite/backends/shared/udevqtdevice.cpp b/solid-lite/backends/shared/udevqtdevice.cpp new file mode 100644 index 000000000..8873e82cb --- /dev/null +++ b/solid-lite/backends/shared/udevqtdevice.cpp @@ -0,0 +1,262 @@ +/* + Copyright 2009 Benjamin K. Stuhl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevqt.h" +// #include "udevqt_p.h" + +#include + +namespace UdevQt { + +DevicePrivate::DevicePrivate(struct udev_device *udev_, bool ref) + : udev(udev_) +{ + if (ref) + udev_device_ref(udev); +} + +DevicePrivate::~DevicePrivate() +{ + udev_device_unref(udev); +} + +DevicePrivate &DevicePrivate::operator=(const DevicePrivate &other) +{ + udev_device_unref(udev); + udev = udev_device_ref(other.udev); + return *this; +} + +QString DevicePrivate::decodePropertyValue(const QByteArray &encoded) const +{ + QByteArray decoded; + const int len = encoded.length(); + + for (int i = 0; i < len; i++) { + quint8 ch = encoded.at(i); + + if (ch == '\\') { + if (i + 1 < len && encoded.at(i + 1) == '\\') { + decoded.append('\\'); + i++; + continue; + } else if (i + 3 < len && encoded.at(i + 1) == 'x') { + QByteArray hex = encoded.mid(i + 2, 2); + bool ok; + int code = hex.toInt(&ok, 16); + if (ok) + decoded.append(char(code)); + i += 3; + continue; + } + } else { + decoded.append(ch); + } + } + return QString::fromUtf8(decoded); +} + +Device::Device() + : d(0) +{ +} + +Device::Device(const Device &other) +{ + if (other.d) { + d = new DevicePrivate(other.d->udev); + } else { + d = 0; + } +} + +Device::Device(DevicePrivate *devPrivate) + : d(devPrivate) +{ +} + +Device::~Device() +{ + delete d; +} + +Device &Device::operator=(const Device &other) +{ + if (this == &other) + return *this; + if (!other.d) { + delete d; + d = 0; + return *this; + } + if (!d) { + d = new DevicePrivate(other.d->udev); + } else { + *d = *other.d; + } + + return *this; +} + +bool Device::isValid() const +{ + return (d != 0); +} + +QString Device::subsystem() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_subsystem(d->udev)); +} + +QString Device::devType() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_devtype(d->udev)); +} + +QString Device::name() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_sysname(d->udev)); +} + +QString Device::sysfsPath() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_syspath(d->udev)); +} + +int Device::sysfsNumber() const +{ + if (!d) + return -1; + + QString value = QString::fromLatin1(udev_device_get_sysnum(d->udev)); + bool success = false; + int number = value.toInt(&success); + if (success) + return number; + return -1; +} + +QString Device::driver() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_driver(d->udev)); +} + +QString Device::primaryDeviceFile() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_devnode(d->udev)); +} + +QStringList Device::alternateDeviceSymlinks() const +{ + if (!d) + return QStringList(); + + return listFromListEntry(udev_device_get_devlinks_list_entry(d->udev)); +} + +QStringList Device::deviceProperties() const +{ + if (!d) + return QStringList(); + + return listFromListEntry(udev_device_get_properties_list_entry(d->udev)); +} + +Device Device::parent() const +{ + if (!d) + return Device(); + + struct udev_device *p = udev_device_get_parent(d->udev); + + if (!p) + return Device(); + + return Device(new DevicePrivate(p)); +} + +QVariant Device::deviceProperty(const QString &name) const +{ + if (!d) + return QVariant(); + + QByteArray propName = name.toLatin1(); + QString propValue = QString::fromLatin1(udev_device_get_property_value(d->udev, propName.constData())); + if (!propValue.isEmpty()) { + return QVariant::fromValue(propValue); + } + return QVariant(); +} + +QString Device::decodedDeviceProperty(const QString &name) const +{ + if (!d) + return QString(); + + QByteArray propName = name.toLatin1(); + return d->decodePropertyValue(udev_device_get_property_value(d->udev, propName.constData())); +} + +QVariant Device::sysfsProperty(const QString &name) const +{ + if (!d) + return QVariant(); + + QByteArray propName = name.toLatin1(); + QString propValue = QString::fromLatin1(udev_device_get_sysattr_value(d->udev, propName.constData())); + if (!propValue.isEmpty()) { + return QVariant::fromValue(propValue); + } + return QVariant(); +} + +Device Device::ancestorOfType(const QString &subsys, const QString &devtype) const +{ + if (!d) + return Device(); + + struct udev_device *p = udev_device_get_parent_with_subsystem_devtype(d->udev, + subsys.toLatin1().constData(), devtype.toLatin1().constData()); + + if (!p) + return Device(); + + return Device(new DevicePrivate(p)); +} + +} diff --git a/solid-lite/backends/udev/udev.h b/solid-lite/backends/udev/udev.h new file mode 100644 index 000000000..8ee4472cd --- /dev/null +++ b/solid-lite/backends/udev/udev.h @@ -0,0 +1,28 @@ +/* + Copyright 2010 Rafael Fernández López + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_UDEV_H +#define SOLID_BACKENDS_UDEV_H + +#include "../shared/udevqt.h" + +#define UDEV_UDI_PREFIX "/org/kde/solid/udev" + +#endif // SOLID_BACKENDS_UDEV_H diff --git a/solid-lite/backends/udev/udevblock.cpp b/solid-lite/backends/udev/udevblock.cpp new file mode 100644 index 000000000..bd25532c9 --- /dev/null +++ b/solid-lite/backends/udev/udevblock.cpp @@ -0,0 +1,49 @@ +/* + Copyright 2010 Pino Toscano + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevblock.h" + +using namespace Solid::Backends::UDev; + +Block::Block(UDevDevice *device) + : DeviceInterface(device) +{ +} + +Block::~Block() +{ +} + +int Block::deviceMajor() const +{ + return m_device->property("MAJOR").toInt(); +} + +int Block::deviceMinor() const +{ + return m_device->property("MINOR").toInt(); +} + +QString Block::device() const +{ + return m_device->property("DEVNAME").toString(); +} + +//#include "backends/udev/udevblock.moc" diff --git a/solid-lite/backends/udev/udevblock.h b/solid-lite/backends/udev/udevblock.h new file mode 100644 index 000000000..5a2c10e18 --- /dev/null +++ b/solid-lite/backends/udev/udevblock.h @@ -0,0 +1,51 @@ +/* + Copyright 2010 Pino Toscano + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_UDEV_UDEVBLOCK_H +#define SOLID_BACKENDS_UDEV_UDEVBLOCK_H + +#include + +#include "udevdeviceinterface.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDev +{ +class Block : public DeviceInterface, virtual public Solid::Ifaces::Block +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::Block) + +public: + Block(UDevDevice *device); + virtual ~Block(); + + virtual int deviceMajor() const; + virtual int deviceMinor() const; + virtual QString device() const; +}; +} +} +} + +#endif // SOLID_BACKENDS_UDEV_UDEVBLOCK_H diff --git a/solid-lite/backends/udev/udevdevice.cpp b/solid-lite/backends/udev/udevdevice.cpp new file mode 100644 index 000000000..71eb5375e --- /dev/null +++ b/solid-lite/backends/udev/udevdevice.cpp @@ -0,0 +1,336 @@ +/* + Copyright 2010 Rafael Fernández López + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevdevice.h" + +#include "udevgenericinterface.h" +//#include "udevprocessor.h" +//#include "udevcamera.h" +//#include "udevvideo.h" +#include "udevportablemediaplayer.h" +//#include "udevdvbinterface.h" +#include "udevblock.h" +//#include "udevaudiointerface.h" +//#include "udevserialinterface.h" +//#include "udevnetworkinterface.h" +//#include "cpuinfo.h" + +#include +#include + +#include +#include + +using namespace Solid::Backends::UDev; + +UDevDevice::UDevDevice(const UdevQt::Device device) + : Solid::Ifaces::Device() + , m_device(device) +{ +} + +UDevDevice::~UDevDevice() +{ +} + +QString UDevDevice::udi() const +{ + return devicePath(); +} + +QString UDevDevice::parentUdi() const +{ + return UDEV_UDI_PREFIX; +} + +QString UDevDevice::vendor() const +{ + QString vendor = m_device.sysfsProperty("manufacturer").toString(); + if (vendor.isEmpty()) { + /*if (queryDeviceInterface(Solid::DeviceInterface::Processor)) { + // sysfs doesn't have anything useful here + vendor = extractCpuInfoLine(deviceNumber(), "vendor_id\\s+:\\s+(\\S.+)"); + } else if (queryDeviceInterface(Solid::DeviceInterface::Video)) { + vendor = m_device.deviceProperty("ID_VENDOR").toString().replace('_', " "); + } else if (queryDeviceInterface(Solid::DeviceInterface::NetworkInterface)) { + vendor = m_device.deviceProperty("ID_VENDOR_FROM_DATABASE").toString(); + } else if (queryDeviceInterface(Solid::DeviceInterface::AudioInterface)) { + if (m_device.parent().isValid()) { + vendor = m_device.parent().deviceProperty("ID_VENDOR_FROM_DATABASE").toString(); + } + } + */ + if (vendor.isEmpty()) { + vendor = m_device.deviceProperty("ID_VENDOR").toString().replace('_', ' '); + } + } + return vendor; +} + +QString UDevDevice::product() const +{ + QString product = m_device.sysfsProperty("product").toString(); + if (product.isEmpty()) { + /*if (queryDeviceInterface(Solid::DeviceInterface::Processor)) { + // sysfs doesn't have anything useful here + product = extractCpuInfoLine(deviceNumber(), "model name\\s+:\\s+(\\S.+)"); + } else if(queryDeviceInterface(Solid::DeviceInterface::Video)) { + product = m_device.deviceProperty("ID_V4L_PRODUCT").toString(); + } else if(queryDeviceInterface(Solid::DeviceInterface::AudioInterface)) { + const AudioInterface audioIface(const_cast(this)); + product = audioIface.name(); + } else if(queryDeviceInterface(Solid::DeviceInterface::NetworkInterface)) { + QFile typeFile(deviceName() + "/type"); + if (typeFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + int mediaType = typeFile.readAll().trimmed().toInt(); + if (mediaType == ARPHRD_LOOPBACK) { + product = QLatin1String("Loopback device Interface"); + } else { + product = m_device.deviceProperty("ID_MODEL_FROM_DATABASE").toString(); + } + } + } else if(queryDeviceInterface(Solid::DeviceInterface::SerialInterface)) { + const SerialInterface serialIface(const_cast(this)); + if (serialIface.serialType() == Solid::SerialInterface::Platform) { + product.append(QLatin1String("Platform serial")); + } else if (serialIface.serialType() == Solid::SerialInterface::Usb) { + product.append(QLatin1String("USB Serial Port")); + } + } + */ + + if (product.isEmpty()) { + product = m_device.deviceProperty("ID_MODEL").toString().replace('_', ' '); + } + } + return product; +} + +QString UDevDevice::icon() const +{ + if (parentUdi().isEmpty()) { + return QLatin1String("computer"); + } + + /*if (queryDeviceInterface(Solid::DeviceInterface::Processor)) { + return QLatin1String("cpu"); + } else*/ if (queryDeviceInterface(Solid::DeviceInterface::PortableMediaPlayer)) { + // TODO: check out special cases like iPod + return QLatin1String("multimedia-player"); + } /*else if (queryDeviceInterface(Solid::DeviceInterface::Camera)) { + return QLatin1String("camera-photo"); + } else if (queryDeviceInterface(Solid::DeviceInterface::Video)) { + return QLatin1String("camera-web"); + } else if (queryDeviceInterface(Solid::DeviceInterface::AudioInterface)) { + const AudioInterface audioIface(const_cast(this)); + switch (audioIface.soundcardType()) { + case Solid::AudioInterface::InternalSoundcard: + return QLatin1String("audio-card"); + case Solid::AudioInterface::UsbSoundcard: + return QLatin1String("audio-card-usb"); + case Solid::AudioInterface::FirewireSoundcard: + return QLatin1String("audio-card-firewire"); + case Solid::AudioInterface::Headset: + if (udi().contains("usb", Qt::CaseInsensitive) || + audioIface.name().contains("usb", Qt::CaseInsensitive)) { + return QLatin1String("audio-headset-usb"); + } else { + return QLatin1String("audio-headset"); + } + case Solid::AudioInterface::Modem: + return QLatin1String("modem"); + } + } else if (queryDeviceInterface(Solid::DeviceInterface::SerialInterface)) { + // TODO - a serial device can be a modem, or just + // a COM port - need a new icon? + return QLatin1String("modem"); + } + */ + + return QString(); +} + +QStringList UDevDevice::emblems() const +{ + return QStringList(); +} + +QString UDevDevice::description() const +{ + if (parentUdi().isEmpty()) { + return QObject::tr("Computer"); + } + + /*if (queryDeviceInterface(Solid::DeviceInterface::Processor)) { + return QObject::tr("Processor"); + } else*/ if (queryDeviceInterface(Solid::DeviceInterface::PortableMediaPlayer)) { + // TODO: check out special cases like iPod + return QObject::tr("Portable Media Player"); + } /*else if (queryDeviceInterface(Solid::DeviceInterface::Camera)) { + return QObject::tr("Camera"); + } else if (queryDeviceInterface(Solid::DeviceInterface::Video)) { + return product(); + } else if (queryDeviceInterface(Solid::DeviceInterface::AudioInterface)) { + return product(); + } else if (queryDeviceInterface(Solid::DeviceInterface::NetworkInterface)) { + const NetworkInterface networkIface(const_cast(this)); + if (networkIface.isWireless()) { + return QObject::tr("WLAN Interface"); + } + return QObject::tr("Networking Interface"); + } */ + + return QString(); +} + +bool UDevDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const +{ + switch (type) { + case Solid::DeviceInterface::GenericInterface: + return true; + + /*case Solid::DeviceInterface::Processor: + return property("DRIVER").toString() == "processor"; + + case Solid::DeviceInterface::Camera: + return property("ID_GPHOTO2").toInt() == 1; + */ + case Solid::DeviceInterface::PortableMediaPlayer: + return !property("ID_MEDIA_PLAYER").toString().isEmpty(); + +/* + case Solid::DeviceInterface::DvbInterface: + return m_device.subsystem() == QLatin1String("dvb"); +*/ + case Solid::DeviceInterface::Block: + return !property("MAJOR").toString().isEmpty(); +/* + case Solid::DeviceInterface::Video: + return m_device.subsystem() == QLatin1String("video4linux"); + + case Solid::DeviceInterface::AudioInterface: + return m_device.subsystem() == QLatin1String("sound"); + + case Solid::DeviceInterface::NetworkInterface: + return m_device.subsystem() == QLatin1String("net"); + + case Solid::DeviceInterface::SerialInterface: + return m_device.subsystem() == QLatin1String("tty"); +*/ + default: + return false; + } +} + +QObject *UDevDevice::createDeviceInterface(const Solid::DeviceInterface::Type &type) +{ + if (!queryDeviceInterface(type)) { + return 0; + } + + switch (type) { + case Solid::DeviceInterface::GenericInterface: + return new GenericInterface(this); +/* + case Solid::DeviceInterface::Processor: + return new Processor(this); + + case Solid::DeviceInterface::Camera: + return new Camera(this); +*/ + case Solid::DeviceInterface::PortableMediaPlayer: + return new PortableMediaPlayer(this); +/* + case Solid::DeviceInterface::DvbInterface: + return new DvbInterface(this); +*/ + case Solid::DeviceInterface::Block: + return new Block(this); +/* + case Solid::DeviceInterface::Video: + return new Video(this); + + case Solid::DeviceInterface::AudioInterface: + return new AudioInterface(this); + + case Solid::DeviceInterface::NetworkInterface: + return new NetworkInterface(this); + + case Solid::DeviceInterface::SerialInterface: + return new SerialInterface(this); +*/ + default: + // qFatal("Shouldn't happen"); + return 0; + } +} + +QString UDevDevice::device() const +{ + return devicePath(); +} + +QVariant UDevDevice::property(const QString &key) const +{ + const QVariant res = m_device.deviceProperty(key); + if (res.isValid()) { + return res; + } + return m_device.sysfsProperty(key); +} + +QMap UDevDevice::allProperties() const +{ + QMap res; + foreach (const QString &prop, m_device.deviceProperties()) { + res[prop] = property(prop); + } + return res; +} + +bool UDevDevice::propertyExists(const QString &key) const +{ + return m_device.deviceProperties().contains(key); +} + +QString UDevDevice::systemAttribute(const char *attribute) const +{ + return m_device.sysfsProperty(attribute).toString(); +} + +QString UDevDevice::deviceName() const +{ + return m_device.sysfsPath(); +} + +int UDevDevice::deviceNumber() const +{ + return m_device.sysfsNumber(); +} + +QString UDevDevice::devicePath() const +{ + return QString(UDEV_UDI_PREFIX) + deviceName(); +} + +UdevQt::Device UDevDevice::udevDevice() +{ + return m_device; +} diff --git a/solid-lite/backends/udev/udevdevice.h b/solid-lite/backends/udev/udevdevice.h new file mode 100644 index 000000000..9f93fc5e1 --- /dev/null +++ b/solid-lite/backends/udev/udevdevice.h @@ -0,0 +1,81 @@ +/* + Copyright 2010 Rafael Fernández López + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_UDEV_UDEVDEVICE_H +#define SOLID_BACKENDS_UDEV_UDEVDEVICE_H + +#include "udev.h" + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace UDev +{ + +class UDevDevice : public Solid::Ifaces::Device +{ + Q_OBJECT + +public: + UDevDevice(const UdevQt::Device device); + virtual ~UDevDevice(); + + virtual QString udi() const; + + virtual QString parentUdi() const; + + virtual QString vendor() const; + + virtual QString product() const; + + virtual QString icon() const; + + virtual QStringList emblems() const; + + virtual QString description() const; + + virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type &type) const; + + virtual QObject *createDeviceInterface(const Solid::DeviceInterface::Type &type); + + QString device() const; + + QVariant property(const QString &key) const; + QMap allProperties() const; + bool propertyExists(const QString &key) const; + + QString systemAttribute(const char *attribute) const; + QString deviceName() const; + QString devicePath() const; + int deviceNumber() const; + + UdevQt::Device udevDevice(); +private: + UdevQt::Device m_device; +}; + +} +} +} +#endif // SOLID_BACKENDS_UDEV_UDEVDEVICE_H diff --git a/solid-lite/backends/udev/udevdeviceinterface.cpp b/solid-lite/backends/udev/udevdeviceinterface.cpp new file mode 100644 index 000000000..49ab3ba1c --- /dev/null +++ b/solid-lite/backends/udev/udevdeviceinterface.cpp @@ -0,0 +1,34 @@ +/* + Copyright 2010 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevdeviceinterface.h" + +using namespace Solid::Backends::UDev; + +DeviceInterface::DeviceInterface(UDevDevice *device) + : QObject(device), m_device(device) +{ +} + +DeviceInterface::~DeviceInterface() +{ +} + +//#include "backends/udev/udevdeviceinterface.moc" diff --git a/solid-lite/backends/udev/udevdeviceinterface.h b/solid-lite/backends/udev/udevdeviceinterface.h new file mode 100644 index 000000000..96245c119 --- /dev/null +++ b/solid-lite/backends/udev/udevdeviceinterface.h @@ -0,0 +1,51 @@ +/* + Copyright 2010 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_UDEV_DEVICEINTERFACE_H +#define SOLID_BACKENDS_UDEV_DEVICEINTERFACE_H + +#include +#include "udevdevice.h" + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace UDev +{ +class DeviceInterface : public QObject, virtual public Solid::Ifaces::DeviceInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::DeviceInterface) +public: + DeviceInterface(UDevDevice *device); + virtual ~DeviceInterface(); + +protected: + UDevDevice *m_device; +}; +} +} +} + +#endif diff --git a/solid-lite/backends/udev/udevgenericinterface.cpp b/solid-lite/backends/udev/udevgenericinterface.cpp new file mode 100644 index 000000000..9e7c7ccdf --- /dev/null +++ b/solid-lite/backends/udev/udevgenericinterface.cpp @@ -0,0 +1,58 @@ +/* + Copyright 2010 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevgenericinterface.h" + +#include "udevdevice.h" + +using namespace Solid::Backends::UDev; + +GenericInterface::GenericInterface(UDevDevice *device) + : DeviceInterface(device) +{ +#if 0 + connect(device, SIGNAL(propertyChanged(QMap)), + this, SIGNAL(propertyChanged(QMap))); + connect(device, SIGNAL(conditionRaised(QString,QString)), + this, SIGNAL(conditionRaised(QString,QString))); +#endif +} + +GenericInterface::~GenericInterface() +{ + +} + +QVariant GenericInterface::property(const QString &key) const +{ + return m_device->property(key); +} + +QMap GenericInterface::allProperties() const +{ + return m_device->allProperties(); +} + +bool GenericInterface::propertyExists(const QString &key) const +{ + return m_device->propertyExists(key); +} + +//#include "backends/udev/udevgenericinterface.moc" diff --git a/solid-lite/backends/udev/udevgenericinterface.h b/solid-lite/backends/udev/udevgenericinterface.h new file mode 100644 index 000000000..d1bee0bb1 --- /dev/null +++ b/solid-lite/backends/udev/udevgenericinterface.h @@ -0,0 +1,57 @@ +/* + Copyright 2010 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_UDEV_GENERICINTERFACE_H +#define SOLID_BACKENDS_UDEV_GENERICINTERFACE_H + +#include +#include +#include "udevdeviceinterface.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDev +{ +class UDevDevice; + +class GenericInterface : public DeviceInterface, virtual public Solid::Ifaces::GenericInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::GenericInterface) + +public: + GenericInterface(UDevDevice *device); + virtual ~GenericInterface(); + + virtual QVariant property(const QString &key) const; + virtual QMap allProperties() const; + virtual bool propertyExists(const QString &key) const; + +Q_SIGNALS: + void propertyChanged(const QMap &changes); + void conditionRaised(const QString &condition, const QString &reason); +}; +} +} +} + +#endif diff --git a/solid-lite/backends/udev/udevmanager.cpp b/solid-lite/backends/udev/udevmanager.cpp new file mode 100644 index 000000000..50ca10331 --- /dev/null +++ b/solid-lite/backends/udev/udevmanager.cpp @@ -0,0 +1,210 @@ +/* + Copyright 2010 Rafael Fernández López + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevmanager.h" + +#include "udev.h" +#include "udevdevice.h" +#include "../shared/rootdevice.h" + +#include +#include +#include + +#define DETAILED_OUTPUT 0 + +using namespace Solid::Backends::UDev; +using namespace Solid::Backends::Shared; + +class UDevManager::Private +{ +public: + Private(); + ~Private(); + + bool isOfInterest(const UdevQt::Device &device); + + UdevQt::Client *m_client; + QSet m_supportedInterfaces; +}; + +UDevManager::Private::Private() +{ + QStringList subsystems; + subsystems << "processor"; + subsystems << "sound"; + subsystems << "tty"; + subsystems << "dvb"; + subsystems << "video4linux"; + subsystems << "net"; + subsystems << "usb"; + m_client = new UdevQt::Client(subsystems); +} + +UDevManager::Private::~Private() +{ + delete m_client; +} + +bool UDevManager::Private::isOfInterest(const UdevQt::Device &device) +{ +#if DETAILED_OUTPUT + qDebug() << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"; + qDebug() << "Path:" << device.sysfsPath(); + qDebug() << "Properties:" << device.deviceProperties(); + Q_FOREACH (const QString &key, device.deviceProperties()) { + qDebug() << "\t" << key << ":" << device.deviceProperty(key).toString(); + } + qDebug() << "Driver:" << device.driver(); + qDebug() << "Subsystem:" << device.subsystem(); + qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; +#endif + if (device.driver() == QLatin1String("processor")) { + // Linux ACPI reports processor slots, rather than processors. + // Empty slots will not have a system device associated with them. + return QFile::exists(device.sysfsPath() + "/sysdev"); + } + if (device.subsystem() == QLatin1String("sound") && + device.deviceProperty("SOUND_FORM_FACTOR").toString() != "internal") { + return true; + } + + if (device.subsystem() == QLatin1String("tty")) { + QString path = device.deviceProperty("DEVPATH").toString(); + + int lastSlash = path.length() - path.lastIndexOf(QLatin1String("/")) -1; + QByteArray lastElement = path.right(lastSlash).toAscii(); + + if (lastElement.startsWith("tty") && !path.startsWith("/devices/virtual")) { + return true; + } + } + return device.subsystem() == QLatin1String("dvb") || + device.subsystem() == QLatin1String("video4linux") || + device.subsystem() == QLatin1String("net") || + device.deviceProperty("ID_MEDIA_PLAYER").toString().isEmpty() == false || // media-player-info recognized devices + device.deviceProperty("ID_GPHOTO2").toInt() == 1; // GPhoto2 cameras +} + +UDevManager::UDevManager(QObject *parent) + : Solid::Ifaces::DeviceManager(parent), + d(new Private) +{ + connect(d->m_client, SIGNAL(deviceAdded(UdevQt::Device)), this, SLOT(slotDeviceAdded(UdevQt::Device))); + connect(d->m_client, SIGNAL(deviceRemoved(UdevQt::Device)), this, SLOT(slotDeviceRemoved(UdevQt::Device))); + + d->m_supportedInterfaces << Solid::DeviceInterface::GenericInterface + /*<< Solid::DeviceInterface::Processor + << Solid::DeviceInterface::AudioInterface + << Solid::DeviceInterface::NetworkInterface + << Solid::DeviceInterface::SerialInterface + << Solid::DeviceInterface::Camera */ + << Solid::DeviceInterface::PortableMediaPlayer + //<< Solid::DeviceInterface::DvbInterface + << Solid::DeviceInterface::Block + /*<< Solid::DeviceInterface::Video*/; +} + +UDevManager::~UDevManager() +{ + delete d; +} + +QString UDevManager::udiPrefix() const +{ + return QString::fromLatin1(UDEV_UDI_PREFIX); +} + +QSet UDevManager::supportedInterfaces() const +{ + return d->m_supportedInterfaces; +} + +QStringList UDevManager::allDevices() +{ + QStringList res; + const UdevQt::DeviceList deviceList = d->m_client->allDevices(); + foreach (const UdevQt::Device &device, deviceList) { + if (d->isOfInterest(device)) { + res << udiPrefix() + device.sysfsPath(); + } + } + return res; +} + +QStringList UDevManager::devicesFromQuery(const QString &parentUdi, + Solid::DeviceInterface::Type type) +{ + QStringList allDev = allDevices(); + QStringList result; + + if (!parentUdi.isEmpty()) { + foreach (const QString &udi, allDev) { + UDevDevice device(d->m_client->deviceBySysfsPath(udi.right(udi.size() - udiPrefix().size()))); + if (device.queryDeviceInterface(type) && device.parentUdi() == parentUdi) { + result << udi; + } + } + + return result; + } else if (type != Solid::DeviceInterface::Unknown) { + foreach (const QString &udi, allDev) { + UDevDevice device(d->m_client->deviceBySysfsPath(udi.right(udi.size() - udiPrefix().size()))); + if (device.queryDeviceInterface(type)) { + result << udi; + } + } + + return result; + } else { + return allDev; + } +} + +QObject *UDevManager::createDevice(const QString &udi_) +{ + if (udi_ == udiPrefix()) { + RootDevice *const device = new RootDevice(UDEV_UDI_PREFIX); + device->setProduct(tr("Devices")); + device->setDescription(tr("Devices declared in your system")); + device->setIcon("computer"); + return device; + } + const QString udi = udi_.right(udi_.size() - udiPrefix().size()); + UdevQt::Device device = d->m_client->deviceBySysfsPath(udi); + if (d->isOfInterest(device) || QFile::exists(udi)) { + return new UDevDevice(device); + } + return 0; +} + +void UDevManager::slotDeviceAdded(const UdevQt::Device &device) +{ + if (d->isOfInterest(device)) { + emit deviceAdded(udiPrefix() + device.sysfsPath()); + } +} + +void UDevManager::slotDeviceRemoved(const UdevQt::Device &device) +{ + if (d->isOfInterest(device)) { + emit deviceRemoved(udiPrefix() + device.sysfsPath()); + } +} diff --git a/solid-lite/backends/udev/udevmanager.h b/solid-lite/backends/udev/udevmanager.h new file mode 100644 index 000000000..9f43ab684 --- /dev/null +++ b/solid-lite/backends/udev/udevmanager.h @@ -0,0 +1,64 @@ +/* + Copyright 2010 Rafael Fernández López + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_UDEV_UDEVMANAGER_H +#define SOLID_BACKENDS_UDEV_UDEVMANAGER_H + +#include + +#include "../shared/udevqt.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDev +{ +class UDevManager : public Solid::Ifaces::DeviceManager +{ + Q_OBJECT + +public: + UDevManager(QObject *parent); + virtual ~UDevManager(); + + virtual QString udiPrefix() const; + virtual QSet supportedInterfaces() const; + + virtual QStringList allDevices(); + + virtual QStringList devicesFromQuery(const QString &parentUdi, + Solid::DeviceInterface::Type type); + + virtual QObject *createDevice(const QString &udi); + +private Q_SLOTS: + void slotDeviceAdded(const UdevQt::Device &device); + void slotDeviceRemoved(const UdevQt::Device &device); + +private: + class Private; + Private *const d; +}; +} +} +} + +#endif // SOLID_BACKENDS_UDEV_UDEVMANAGER_H diff --git a/solid-lite/backends/udev/udevportablemediaplayer.cpp b/solid-lite/backends/udev/udevportablemediaplayer.cpp new file mode 100644 index 000000000..da28b8001 --- /dev/null +++ b/solid-lite/backends/udev/udevportablemediaplayer.cpp @@ -0,0 +1,152 @@ +/* + Copyright 2010 Rafael Fernández López + 2010 Lukas Tinkl + 2011 Matej Laitl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevportablemediaplayer.h" + +#include "solid-lite/xdgbasedirs_p.h" + +#include +#include +#include +#include + +using namespace Solid::Backends::UDev; + +/** + * Reads one value from media-player-info ini-like file. + * + * @param file file to open. May advance current seek position + * @param group group name to read from, e.g. "Device" for [Device] group + * @param key key name, e.g. "AccessProtocol" + * @return value as a string or an empty string + */ +static QString readMpiValue(QIODevice &file, const QString &group, const QString &key) +{ + QTextStream mpiStream(&file); + QString line; + QString currGroup; + + while (!mpiStream.atEnd()) { + line = mpiStream.readLine().trimmed(); // trimmed is needed for possible indentation + if (line.isEmpty() || line.startsWith(QChar(';'))) { + // skip empty and comment lines + } + else if (line.startsWith(QChar('[')) && line.endsWith(QChar(']'))) { + currGroup = line.mid(1, line.length() - 2); // strip [ and ] + } + else if (line.indexOf(QChar('=') != -1)) { + int index = line.indexOf(QChar('=')); + if (currGroup == group && line.left(index) == key) { + line = line.right(line.length() - index - 1); + if (line.startsWith(QChar('"')) && line.endsWith(QChar('"'))) { + line = line.mid(1, line.length() - 2); // strip enclosing double quotes + } + return line; + } + } + else { + qWarning() << "readMpiValue: cannot parse line:" << line; + } + } + return QString(); +} + +PortableMediaPlayer::PortableMediaPlayer(UDevDevice *device) + : DeviceInterface(device) +{ + +} + +PortableMediaPlayer::~PortableMediaPlayer() +{ + +} + +QStringList PortableMediaPlayer::supportedProtocols() const +{ + /* There are multiple packages that set ID_MEDIA_PLAYER: + * * gphoto2 sets it to numeric 1 (for _some_ cameras it supports) and it hopefully + * means MTP-compatible device. + * * libmtp >= 1.0.4 sets it to numeric 1 and this always denotes MTP-compatible player. + * * media-player-info sets it to a string that denotes a name of the .mpi file with + * additional info. + */ + if (m_device->property("ID_MEDIA_PLAYER").toInt() == 1) { + return QStringList() << "mtp"; + } + + QString mpiFileName = mediaPlayerInfoFilePath(); + if (mpiFileName.isEmpty()) { + return QStringList(); + } + // we unfornutately cannot use QSettings as it cannot read unquoted valued with semicolons in it + QFile mpiFile(mpiFileName); + if (!mpiFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning() << "Cannot open" << mpiFileName << "for reading." + << "Check your media-player-info installation."; + return QStringList(); + } + QString value = readMpiValue(mpiFile, QString("Device"), QString("AccessProtocol")); + return value.split(QChar(';'), QString::SkipEmptyParts); +} + +QStringList PortableMediaPlayer::supportedDrivers(QString protocol) const +{ + Q_UNUSED(protocol) + QStringList res; + + if (!supportedProtocols().isEmpty()) { + res << "usb"; + } + if (m_device->property("USBMUX_SUPPORTED").toBool() == true) { + res << "usbmux"; + } + return res; +} + +QVariant PortableMediaPlayer::driverHandle(const QString &driver) const +{ + if (driver == "mtp" || driver == "usbmux") + return m_device->property("ID_SERIAL_SHORT"); + + return QVariant(); +} + +QString PortableMediaPlayer::mediaPlayerInfoFilePath() const +{ + QString relativeFilename = m_device->property("ID_MEDIA_PLAYER").toString(); + if (relativeFilename.isEmpty()) { + qWarning() << "We attached PortableMediaPlayer interface to device" << m_device->udi() + << "but m_device->property(\"ID_MEDIA_PLAYER\") is empty???"; + return QString(); + } + relativeFilename.prepend("media-player-info/"); + relativeFilename.append(".mpi"); + QString filename = Solid::XdgBaseDirs::findResourceFile("data", relativeFilename); + if (filename.isEmpty()) { + qWarning() << "media player info file" << relativeFilename << "not found under user and" + << "system XDG data directories. Do you have media-player-info installed?"; + } + return filename; +} + +//#include "backends/udev/udevportablemediaplayer.moc" diff --git a/solid-lite/backends/udev/udevportablemediaplayer.h b/solid-lite/backends/udev/udevportablemediaplayer.h new file mode 100644 index 000000000..ff1aee8c8 --- /dev/null +++ b/solid-lite/backends/udev/udevportablemediaplayer.h @@ -0,0 +1,62 @@ +/* + Copyright 2010 Rafael Fernández López + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_UDEV_PORTABLEMEDIAPLAYER_H +#define SOLID_BACKENDS_UDEV_PORTABLEMEDIAPLAYER_H + +#include +#include "udevdeviceinterface.h" + +#include + +namespace Solid +{ +namespace Backends +{ +namespace UDev +{ +class UDevDevice; + +class PortableMediaPlayer : public DeviceInterface, virtual public Solid::Ifaces::PortableMediaPlayer +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::PortableMediaPlayer) + +public: + PortableMediaPlayer(UDevDevice *device); + virtual ~PortableMediaPlayer(); + + virtual QStringList supportedProtocols() const; + virtual QStringList supportedDrivers(QString protocol = QString()) const; + virtual QVariant driverHandle(const QString &driver) const; + +private: + /** + * Return full absolute path to media-player-info .mpi file, based on ID_MEDIA_PLAYER + * udev property. Does not check for existence. Returns empty string in case no reasonable + * file path could be determined. + */ + QString mediaPlayerInfoFilePath() const; +}; +} +} +} + +#endif // SOLID_BACKENDS_UDEV_PORTABLEMEDIAPLAYER_H diff --git a/solid-lite/backends/udisks/udisks.h b/solid-lite/backends/udisks/udisks.h new file mode 100644 index 000000000..23e195d95 --- /dev/null +++ b/solid-lite/backends/udisks/udisks.h @@ -0,0 +1,39 @@ +/* + Copyright 2009 Pino Toscano + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_UDISKS_H +#define SOLID_BACKENDS_UDISKS_H + +/* UDisks */ +#define UD_DBUS_SERVICE "org.freedesktop.UDisks" +#define UD_DBUS_PATH "/org/freedesktop/UDisks" +#define UD_DBUS_INTERFACE_DISKS "org.freedesktop.UDisks" +#define UD_DBUS_INTERFACE_DISKS_DEVICE "org.freedesktop.UDisks.Device" +#define UD_UDI_DISKS_PREFIX "/org/freedesktop/UDisks" + +/* errors */ +#define UD_ERROR_UNAUTHORIZED "org.freedesktop.PolicyKit.Error.NotAuthorized" +#define UD_ERROR_BUSY "org.freedesktop.UDisks.Error.Busy" +#define UD_ERROR_FAILED "org.freedesktop.UDisks.Error.Failed" +#define UD_ERROR_CANCELED "org.freedesktop.UDisks.Error.Cancelled" +#define UD_ERROR_INVALID_OPTION "org.freedesktop.UDisks.Error.InvalidOption" +#define UD_ERROR_MISSING_DRIVER "org.freedesktop.UDisks.Error.FilesystemDriverMissing" + +#endif // SOLID_BACKENDS_UDISKS_H diff --git a/solid-lite/backends/udisks/udisksblock.cpp b/solid-lite/backends/udisks/udisksblock.cpp new file mode 100644 index 000000000..597b12aba --- /dev/null +++ b/solid-lite/backends/udisks/udisksblock.cpp @@ -0,0 +1,50 @@ +/* + Copyright 2010 Michael Zanetti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udisksblock.h" + +using namespace Solid::Backends::UDisks; + +Block::Block(UDisksDevice *device) + : DeviceInterface(device) +{ + +} + +Block::~Block() +{ + +} + +QString Block::device() const +{ + return m_device->prop("DeviceFile").toString(); +} + +int Block::deviceMinor() const +{ + return m_device->prop("DeviceMinor").toInt(); +} + +int Block::deviceMajor() const +{ + return m_device->prop("DeviceMajor").toInt(); +} + diff --git a/solid-lite/backends/udisks/udisksblock.h b/solid-lite/backends/udisks/udisksblock.h new file mode 100644 index 000000000..ae6894753 --- /dev/null +++ b/solid-lite/backends/udisks/udisksblock.h @@ -0,0 +1,53 @@ +/* + Copyright 2010 Michael Zanetti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDISKSBLOCK_H +#define UDISKSBLOCK_H + +#include +#include "udisksdeviceinterface.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ + +class Block: public DeviceInterface, virtual public Solid::Ifaces::Block +{ + + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::Block) + +public: + Block(UDisksDevice *device); + virtual ~Block(); + + virtual QString device() const; + virtual int deviceMinor() const; + virtual int deviceMajor() const; +}; + +} +} +} + +#endif // UDISKSBLOCK_H diff --git a/solid-lite/backends/udisks/udisksdevice.cpp b/solid-lite/backends/udisks/udisksdevice.cpp new file mode 100644 index 000000000..bbe8a8849 --- /dev/null +++ b/solid-lite/backends/udisks/udisksdevice.cpp @@ -0,0 +1,777 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010-2011 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udisks.h" +#include "udisksdevice.h" +#include "udisksdeviceinterface.h" +#include "udisksstoragevolume.h" +#include "udisksopticaldisc.h" +#include "udisksopticaldrive.h" +#include "udisksstorageaccess.h" +#include "udisksgenericinterface.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include + +using namespace Solid::Backends::UDisks; + +// Adapted from KLocale as Solid needs to be Qt-only +static QString formatByteSize(double size) +{ + // Per IEC 60027-2 + + // Binary prefixes + //Tebi-byte TiB 2^40 1,099,511,627,776 bytes + //Gibi-byte GiB 2^30 1,073,741,824 bytes + //Mebi-byte MiB 2^20 1,048,576 bytes + //Kibi-byte KiB 2^10 1,024 bytes + + QString s; + // Gibi-byte + if ( size >= 1073741824.0 ) + { + size /= 1073741824.0; + if ( size > 1024 ) // Tebi-byte + s = QObject::tr("%1 TiB").arg(QLocale().toString(size / 1024.0, 'f', 1)); + else + s = QObject::tr("%1 GiB").arg(QLocale().toString(size, 'f', 1)); + } + // Mebi-byte + else if ( size >= 1048576.0 ) + { + size /= 1048576.0; + s = QObject::tr("%1 MiB").arg(QLocale().toString(size, 'f', 1)); + } + // Kibi-byte + else if ( size >= 1024.0 ) + { + size /= 1024.0; + s = QObject::tr("%1 KiB").arg(QLocale().toString(size, 'f', 1)); + } + // Just byte + else if ( size > 0 ) + { + s = QObject::tr("%1 B").arg(QLocale().toString(size, 'f', 1)); + } + // Nothing + else + { + s = QObject::tr("0 B"); + } + return s; +} + +UDisksDevice::UDisksDevice(const QString &udi) + : Solid::Ifaces::Device() + , m_udi(udi) +{ + QString realUdi = m_udi; + if (realUdi.endsWith(":media")) { + realUdi.chop(6); + } + m_device = new QDBusInterface(UD_DBUS_SERVICE, realUdi, + UD_DBUS_INTERFACE_DISKS_DEVICE, + QDBusConnection::systemBus()); + + if (m_device->isValid()) + connect(m_device, SIGNAL(Changed()), this, SLOT(slotChanged())); +} + +UDisksDevice::~UDisksDevice() +{ + delete m_device; +} + +QObject* UDisksDevice::createDeviceInterface(const Solid::DeviceInterface::Type& type) +{ + if (!queryDeviceInterface(type)) { + return 0; + } + + DeviceInterface *iface = 0; + switch (type) + { + case Solid::DeviceInterface::GenericInterface: + iface = new GenericInterface(this); + break; + case Solid::DeviceInterface::Block: + iface = new Block(this); + break; + case Solid::DeviceInterface::StorageAccess: + iface = new UDisksStorageAccess(this); + break; + case Solid::DeviceInterface::StorageDrive: + iface = new UDisksStorageDrive(this); + break; + case Solid::DeviceInterface::OpticalDrive: + iface = new UDisksOpticalDrive(this); + break; + case Solid::DeviceInterface::StorageVolume: + iface = new UDisksStorageVolume(this); + break; + case Solid::DeviceInterface::OpticalDisc: + iface = new OpticalDisc(this); + break; + default: + break; + } + return iface; +} + +bool UDisksDevice::queryDeviceInterface(const Solid::DeviceInterface::Type& type) const +{ + switch (type) { + case Solid::DeviceInterface::GenericInterface: + return true; + case Solid::DeviceInterface::Block: + return prop("DeviceMajor").toInt() != -1; + case Solid::DeviceInterface::StorageVolume: + if (prop("DeviceIsOpticalDisc").toBool()) { + return m_udi.endsWith(":media"); + } else { + return prop("DeviceIsPartition").toBool() + || prop("IdUsage").toString()=="filesystem" + || prop("IdUsage").toString()=="crypto"; + } + + case Solid::DeviceInterface::StorageAccess: + if (prop("DeviceIsOpticalDisc").toBool()) { + return prop("IdUsage").toString()=="filesystem" + && m_udi.endsWith(":media"); + + } else { + return prop("IdUsage").toString()=="filesystem" + || prop("IdUsage").toString()=="crypto"; + } + + case Solid::DeviceInterface::StorageDrive: + return !m_udi.endsWith(":media") && prop("DeviceIsDrive").toBool(); + case Solid::DeviceInterface::OpticalDrive: + return !m_udi.endsWith(":media") + && prop( "DeviceIsDrive" ).toBool() + && !prop( "DriveMediaCompatibility" ).toStringList().filter( "optical_" ).isEmpty(); + case Solid::DeviceInterface::OpticalDisc: + return m_udi.endsWith(":media") && prop("DeviceIsOpticalDisc").toBool(); + default: + return false; + } +} + +QStringList UDisksDevice::emblems() const +{ + QStringList res; + + if (queryDeviceInterface(Solid::DeviceInterface::StorageAccess)) + { + + bool isEncrypted = false; + if (queryDeviceInterface(Solid::DeviceInterface::StorageVolume)) + { + const UDisks::UDisksStorageVolume volIface(const_cast(this)); + isEncrypted = (volIface.usage() == Solid::StorageVolume::Encrypted); + } + + const UDisks::UDisksStorageAccess accessIface(const_cast(this)); + if (accessIface.isAccessible()) + { + if (isEncrypted) + res << "emblem-encrypted-unlocked"; + else + res << "emblem-mounted"; + } + else + { + if (isEncrypted) + res << "emblem-encrypted-locked"; + else + res << "emblem-unmounted"; + } + } + + return res; +} + +QString UDisksDevice::description() const +{ + if (queryDeviceInterface(Solid::DeviceInterface::StorageDrive)) + return storageDescription(); + else if (queryDeviceInterface(Solid::DeviceInterface::StorageVolume)) + return volumeDescription(); + else + return product(); +} + +QString UDisksDevice::storageDescription() const +{ + QString description; + const UDisks::UDisksStorageDrive storageDrive(const_cast(this)); + Solid::StorageDrive::DriveType drive_type = storageDrive.driveType(); + bool drive_is_hotpluggable = storageDrive.isHotpluggable(); + const UDisks::UDisksStorageVolume storageVolume(const_cast(this)); + + if (drive_type == Solid::StorageDrive::CdromDrive) + { + const UDisks::UDisksOpticalDrive opticalDrive(const_cast(this)); + Solid::OpticalDrive::MediumTypes mediumTypes = opticalDrive.supportedMedia(); + QString first; + QString second; + + first = QObject::tr("CD-ROM", "First item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Cdr) + first = QObject::tr("CD-R", "First item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Cdrw) + first = QObject::tr("CD-RW", "First item of %1%2 Drive sentence"); + + if (mediumTypes & Solid::OpticalDrive::Dvd) + second = QObject::tr("/DVD-ROM", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdplusr) + second = QObject::tr("/DVD+R", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdplusrw) + second = QObject::tr("/DVD+RW", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdr) + second = QObject::tr("/DVD-R", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdrw) + second = QObject::tr("/DVD-RW", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Dvdram) + second = QObject::tr("/DVD-RAM", "Second item of %1%2 Drive sentence"); + if ((mediumTypes & Solid::OpticalDrive::Dvdr) && (mediumTypes & Solid::OpticalDrive::Dvdplusr)) + { + if(mediumTypes & Solid::OpticalDrive::Dvdplusdl) + second = QObject::tr("/DVD±R DL", "Second item of %1%2 Drive sentence"); + else + second = QObject::tr("/DVD±R", "Second item of %1%2 Drive sentence"); + } + if ((mediumTypes & Solid::OpticalDrive::Dvdrw) && (mediumTypes & Solid::OpticalDrive::Dvdplusrw)) + { + if((mediumTypes & Solid::OpticalDrive::Dvdplusdl) || (mediumTypes & Solid::OpticalDrive::Dvdplusdlrw)) + second = QObject::tr("/DVD±RW DL", "Second item of %1%2 Drive sentence"); + else + second = QObject::tr("/DVD±RW", "Second item of %1%2 Drive sentence"); + } + if (mediumTypes & Solid::OpticalDrive::Bd) + second = QObject::tr("/BD-ROM", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Bdr) + second = QObject::tr("/BD-R", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::Bdre) + second = QObject::tr("/BD-RE", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::HdDvd) + second = QObject::tr("/HD DVD-ROM", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::HdDvdr) + second = QObject::tr("/HD DVD-R", "Second item of %1%2 Drive sentence"); + if (mediumTypes & Solid::OpticalDrive::HdDvdrw) + second = QObject::tr("/HD DVD-RW", "Second item of %1%2 Drive sentence"); + + if (drive_is_hotpluggable) + description = QObject::tr("External %1%2 Drive", "%1 is CD-ROM/CD-R/etc; %2 is '/DVD-ROM'/'/DVD-R'/etc (with leading slash)").arg(first).arg(second); + else + description = QObject::tr("%1%2 Drive", "%1 is CD-ROM/CD-R/etc; %2 is '/DVD-ROM'/'/DVD-R'/etc (with leading slash)").arg(first).arg(second); + + return description; + } + + if (drive_type == Solid::StorageDrive::Floppy) + { + if (drive_is_hotpluggable) + description = QObject::tr("External Floppy Drive"); + else + description = QObject::tr("Floppy Drive"); + + return description; + } + + bool drive_is_removable = storageDrive.isRemovable(); + + if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable) + { + QString size_str = formatByteSize(storageVolume.size()); + if (!size_str.isEmpty()) + { + if (drive_is_hotpluggable) + description = QObject::tr("%1 External Hard Drive", "%1 is the size").arg(size_str); + else + description = QObject::tr("%1 Hard Drive", "%1 is the size").arg(size_str); + } else { + if (drive_is_hotpluggable) + description = QObject::tr("External Hard Drive"); + else + description = QObject::tr("Hard Drive"); + } + + return description; + } + + QString vendormodel_str; + QString model = product(); + QString vendor_str = vendor(); + + if (vendor_str.isEmpty()) + { + if (!model.isEmpty()) + vendormodel_str = model; + } + else + { + if (model.isEmpty()) + vendormodel_str = vendor_str; + else + { + if (model.startsWith(vendor_str)) + { + // e.g. vendor is "Nokia" and model is "Nokia N950" we do not want "Nokia Nokia N950" as description + vendormodel_str = model; + } + else + { + vendormodel_str = QObject::tr("%1 %2", "%1 is the vendor, %2 is the model of the device").arg(vendor_str).arg(model); + } + } + } + + if (vendormodel_str.isEmpty()) + description = QObject::tr("Drive"); + else + description = vendormodel_str; + + return description; +} + +QString UDisksDevice::volumeDescription() const +{ + QString description; + const UDisks::UDisksStorageVolume storageVolume(const_cast(this)); + QString volume_label = prop("IdLabel").toString(); + if (volume_label.isEmpty()) + volume_label = prop("PartitionLabel").toString(); + if (!volume_label.isEmpty()) + return volume_label; + + const UDisks::UDisksStorageDrive storageDrive(const_cast(this)); + Solid::StorageDrive::DriveType drive_type = storageDrive.driveType(); + + // Handle media in optical drives + if (drive_type == Solid::StorageDrive::CdromDrive) + { + const UDisks::OpticalDisc disc(const_cast(this)); + switch (disc.discType()) + { + case Solid::OpticalDisc::UnknownDiscType: + case Solid::OpticalDisc::CdRom: + description = QObject::tr("CD-ROM"); + break; + + case Solid::OpticalDisc::CdRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank CD-R"); + else + description = QObject::tr("CD-R"); + break; + + case Solid::OpticalDisc::CdRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank CD-RW"); + else + description = QObject::tr("CD-RW"); + break; + + case Solid::OpticalDisc::DvdRom: + description = QObject::tr("DVD-ROM"); + break; + + case Solid::OpticalDisc::DvdRam: + if (disc.isBlank()) + description = QObject::tr("Blank DVD-RAM"); + else + description = QObject::tr("DVD-RAM"); + break; + + case Solid::OpticalDisc::DvdRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank DVD-R"); + else + description = QObject::tr("DVD-R"); + break; + + case Solid::OpticalDisc::DvdPlusRecordableDuallayer: + if (disc.isBlank()) + description = QObject::tr("Blank DVD+R Dual-Layer"); + else + description = QObject::tr("DVD+R Dual-Layer"); + break; + + case Solid::OpticalDisc::DvdRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank DVD-RW"); + else + description = QObject::tr("DVD-RW"); + break; + + case Solid::OpticalDisc::DvdPlusRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank DVD+R"); + else + description = QObject::tr("DVD+R"); + break; + + case Solid::OpticalDisc::DvdPlusRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank DVD+RW"); + else + description = QObject::tr("DVD+RW"); + break; + + case Solid::OpticalDisc::DvdPlusRewritableDuallayer: + if (disc.isBlank()) + description = QObject::tr("Blank DVD+RW Dual-Layer"); + else + description = QObject::tr("DVD+RW Dual-Layer"); + break; + + case Solid::OpticalDisc::BluRayRom: + description = QObject::tr("BD-ROM"); + break; + + case Solid::OpticalDisc::BluRayRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank BD-R"); + else + description = QObject::tr("BD-R"); + break; + + case Solid::OpticalDisc::BluRayRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank BD-RE"); + else + description = QObject::tr("BD-RE"); + break; + + case Solid::OpticalDisc::HdDvdRom: + description = QObject::tr("HD DVD-ROM"); + break; + + case Solid::OpticalDisc::HdDvdRecordable: + if (disc.isBlank()) + description = QObject::tr("Blank HD DVD-R"); + else + description = QObject::tr("HD DVD-R"); + break; + + case Solid::OpticalDisc::HdDvdRewritable: + if (disc.isBlank()) + description = QObject::tr("Blank HD DVD-RW"); + else + description = QObject::tr("HD DVD-RW"); + break; + } + + // Special case for pure audio disc + if (disc.availableContent() == Solid::OpticalDisc::Audio) + description = QObject::tr("Audio CD"); + + return description; + } + + bool drive_is_removable = storageDrive.isRemovable(); + bool drive_is_hotpluggable = storageDrive.isHotpluggable(); + bool drive_is_encrypted_container = (storageVolume.usage() == Solid::StorageVolume::Encrypted); + + QString size_str = formatByteSize(storageVolume.size()); + if (drive_is_encrypted_container) + { + if (!size_str.isEmpty()) + description = QObject::tr("%1 Encrypted Container", "%1 is the size").arg(size_str); + else + description = QObject::tr("Encrypted Container"); + } + else if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable) + { + if (!size_str.isEmpty()) + { + if (drive_is_hotpluggable) + description = QObject::tr("%1 External Hard Drive", "%1 is the size").arg(size_str); + else + description = QObject::tr("%1 Hard Drive", "%1 is the size").arg(size_str); + } + else + { + if (drive_is_hotpluggable) + description = QObject::tr("External Hard Drive"); + else + description = QObject::tr("Hard Drive"); + } + } + else + { + if (drive_is_removable) + description = QObject::tr("%1 Removable Media", "%1 is the size").arg(size_str); + else + description = QObject::tr("%1 Media", "%1 is the size").arg(size_str); + } + + return description; +} + +QString UDisksDevice::icon() const +{ + QString iconName = prop( "DevicePresentationIconName" ).toString(); + + if ( !iconName.isEmpty() ) + { + return iconName; + } + else + { + bool isPartition = prop( "DeviceIsPartition" ).toBool(); + if ( isPartition ) // this is a slave device, we need to return its parent's icon + { + UDisksDevice* parent = 0; + if ( !parentUdi().isEmpty() ) + parent = new UDisksDevice( parentUdi() ); + + if ( parent ) + { + iconName = parent->icon(); + delete parent; + } + + if ( !iconName.isEmpty() ) + return iconName; + } + + // handle mounted ISOs + bool isLoop = prop( "DeviceIsLinuxLoop" ).toBool(); + QString fstype = prop("IdType").toString(); + + if( isLoop && ( fstype == "iso9660" || fstype == "udf" ) ) + { + return "media-optical"; + } + + // handle media + const QString media = prop( "DriveMedia" ).toString(); + bool isOptical = prop( "DeviceIsOpticalDisc" ).toBool(); + + if ( !media.isEmpty() ) + { + if ( isOptical ) // optical stuff + { + bool isWritable = prop( "OpticalDiscIsBlank" ).toBool() || prop("OpticalDiscIsAppendable").toBool(); + + const UDisks::OpticalDisc disc(const_cast(this)); + Solid::OpticalDisc::ContentTypes availContent = disc.availableContent(); + + if (availContent & Solid::OpticalDisc::VideoDvd) // Video DVD + return "media-optical-dvd-video"; + else if ((availContent & Solid::OpticalDisc::VideoCd) || (availContent & Solid::OpticalDisc::SuperVideoCd)) // Video CD + return "media-optical-video"; + else if ((availContent & Solid::OpticalDisc::Data) && (availContent & Solid::OpticalDisc::Audio)) // Mixed CD + return "media-optical-mixed-cd"; + else if (availContent & Solid::OpticalDisc::Audio) // Audio CD + return "media-optical-audio"; + else if (availContent & Solid::OpticalDisc::Data) // Data CD + return "media-optical-data"; + else if ( isWritable ) + return "media-optical-recordable"; + else + { + if ( media.startsWith( "optical_dvd" ) || media.startsWith( "optical_hddvd" ) ) // DVD + return "media-optical-dvd"; + else if ( media.startsWith( "optical_bd" ) ) // BluRay + return "media-optical-blu-ray"; + } + + // fallback for every other optical disc + return "media-optical"; + } + + if ( media == "flash_ms" ) // Flash & Co. + return "media-flash-memory-stick"; + else if ( media == "flash_sd" || media == "flash_sdhc" || media == "flash_mmc" ) + return "media-flash-sd-mmc"; + else if ( media == "flash_sm" ) + return "media-flash-smart-media"; + else if ( media.startsWith( "flash" ) ) + return "media-flash"; + else if ( media == "floppy" ) // the good ol' floppy + return "media-floppy"; + + } + + // handle drives + bool isRemovable = prop( "DeviceIsRemovable" ).toBool(); + const QString conn = prop( "DriveConnectionInterface" ).toString(); + + if ( queryDeviceInterface(Solid::DeviceInterface::OpticalDrive) ) + return "drive-optical"; + else if ( isRemovable && !isOptical ) + { + if ( conn == "usb" ) + return "drive-removable-media-usb"; + else + return "drive-removable-media"; + } + } + + return "drive-harddisk"; // general fallback +} + +QString UDisksDevice::product() const +{ + QString product = prop("DriveModel").toString(); + const bool isDrive = prop( "DeviceIsDrive" ).toBool() && !m_udi.endsWith(":media"); + + if (!isDrive) { + QString label = prop("IdLabel").toString(); + if (!label.isEmpty()) { + product = label; + } + } + + return product; +} + +QString UDisksDevice::vendor() const +{ + return prop("DriveVendor").toString(); +} + +QString UDisksDevice::udi() const +{ + return m_udi; +} + +QString UDisksDevice::parentUdi() const +{ + if (m_udi.endsWith(QLatin1String(":media"))) { + QString result = m_udi; + return result.remove(":media"); + } + else if ( prop( "DeviceIsLuksCleartext" ).toBool() ) + return prop( "LuksCleartextSlave" ).value().path(); + else { + QString parent = prop("PartitionSlave").value().path(); + if (parent.isEmpty() || parent=="/") { + parent = UD_UDI_DISKS_PREFIX; + } + return parent; + } +} + +void UDisksDevice::checkCache(const QString &key) const +{ + if (m_cache.isEmpty()) // recreate the cache + allProperties(); + + if (m_cache.contains(key)) + return; + + QVariant reply = m_device->property(key.toUtf8()); + + if (reply.isValid()) { + m_cache[key] = reply; + } else { + m_cache[key] = QVariant(); + } +} + +QVariant UDisksDevice::prop(const QString &key) const +{ + checkCache(key); + return m_cache.value(key); +} + +bool UDisksDevice::propertyExists(const QString &key) const +{ + checkCache(key); + return m_cache.contains(key); +} + +QMap UDisksDevice::allProperties() const +{ + QDBusMessage call = QDBusMessage::createMethodCall(m_device->service(), m_device->path(), + "org.freedesktop.DBus.Properties", "GetAll"); + call << m_device->interface(); + QDBusPendingReply< QVariantMap > reply = QDBusConnection::systemBus().asyncCall(call); + reply.waitForFinished(); + + if (reply.isValid()) + m_cache = reply.value(); + else + m_cache.clear(); + + return m_cache; +} + +void UDisksDevice::slotChanged() +{ + // given we cannot know which property/ies changed, clear the cache + m_cache.clear(); + emit changed(); +} + +bool UDisksDevice::isDeviceBlacklisted() const +{ + return prop("DevicePresentationHide").toBool() || + prop("DeviceMountPaths").toStringList().contains("/boot") || + prop("IdLabel").toString() == "System Reserved" || + ( prop("IdUsage").toString().isEmpty() && !(prop("OpticalDiscIsBlank").toBool() || (prop("OpticalDiscNumAudioTracks").toInt() > 0) )); +} + +QString UDisksDevice::errorToString(const QString & error) const +{ + if (error == UD_ERROR_UNAUTHORIZED) + return QObject::tr("You are not authorized to perform this operation."); + else if (error == UD_ERROR_BUSY) + return QObject::tr("The device is currently busy."); + else if (error == UD_ERROR_FAILED) + return QObject::tr("The requested operation has failed."); + else if (error == UD_ERROR_CANCELED) + return QObject::tr("The requested operation has been canceled."); + else if (error == UD_ERROR_INVALID_OPTION) + return QObject::tr("An invalid or malformed option has been given."); + else if (error == UD_ERROR_MISSING_DRIVER) + return QObject::tr("The kernel driver for this filesystem type is not available."); + else + return QObject::tr("An unspecified error has occurred."); +} + +Solid::ErrorType UDisksDevice::errorToSolidError(const QString & error) const +{ + if (error == UD_ERROR_BUSY) + return Solid::DeviceBusy; + else if (error == UD_ERROR_FAILED) + return Solid::OperationFailed; + else if (error == UD_ERROR_CANCELED) + return Solid::UserCanceled; + else if (error == UD_ERROR_INVALID_OPTION) + return Solid::InvalidOption; + else if (error == UD_ERROR_MISSING_DRIVER) + return Solid::MissingDriver; + else + return Solid::UnauthorizedOperation; +} diff --git a/solid-lite/backends/udisks/udisksdevice.h b/solid-lite/backends/udisks/udisksdevice.h new file mode 100644 index 000000000..85ac16eee --- /dev/null +++ b/solid-lite/backends/udisks/udisksdevice.h @@ -0,0 +1,86 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010-2011 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDISKSDEVICE_H +#define UDISKSDEVICE_H + +#include +#include +#include + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ + +class UDisksDevice : public Solid::Ifaces::Device +{ + Q_OBJECT +public: + UDisksDevice(const QString &udi); + virtual ~UDisksDevice(); + + + virtual QObject* createDeviceInterface(const Solid::DeviceInterface::Type& type); + virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type& type) const; + virtual QString description() const; + virtual QStringList emblems() const; + virtual QString icon() const; + virtual QString product() const; + virtual QString vendor() const; + virtual QString udi() const; + virtual QString parentUdi() const; + + QVariant prop(const QString &key) const; + bool propertyExists(const QString &key) const; + QMap allProperties() const; + + bool isDeviceBlacklisted() const; + + QString errorToString(const QString & error) const; + Solid::ErrorType errorToSolidError(const QString & error) const; + +Q_SIGNALS: + void changed(); + +private Q_SLOTS: + void slotChanged(); + +private: + QString storageDescription() const; + QString volumeDescription() const; + mutable QDBusInterface *m_device; + QString m_udi; + mutable QVariantMap m_cache; + + void checkCache(const QString &key) const; +}; + +} +} +} + +#endif // UDISKSDEVICE_H diff --git a/solid-lite/backends/udisks/udisksdeviceinterface.cpp b/solid-lite/backends/udisks/udisksdeviceinterface.cpp new file mode 100644 index 000000000..556a421af --- /dev/null +++ b/solid-lite/backends/udisks/udisksdeviceinterface.cpp @@ -0,0 +1,33 @@ +/* + Copyright 2010 Michael Zanetti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udisksdeviceinterface.h" + +using namespace Solid::Backends::UDisks; + +DeviceInterface::DeviceInterface(UDisksDevice *device) + : QObject(device), m_device(device) +{ + +} + +DeviceInterface::~DeviceInterface() +{ +} diff --git a/solid-lite/backends/udisks/udisksdeviceinterface.h b/solid-lite/backends/udisks/udisksdeviceinterface.h new file mode 100644 index 000000000..fe5cfa811 --- /dev/null +++ b/solid-lite/backends/udisks/udisksdeviceinterface.h @@ -0,0 +1,176 @@ +/* + Copyright 2010 Michael Zanetti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDISKSDEVICEINTERFACE_H +#define UDISKSDEVICEINTERFACE_H + +#include +#include "udisksdevice.h" + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ + +class DeviceInterface : public QObject, virtual public Solid::Ifaces::DeviceInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::DeviceInterface) +public: + DeviceInterface(UDisksDevice *device); + virtual ~DeviceInterface(); + +protected: + UDisksDevice *m_device; + +public: + inline static QStringList toStringList(Solid::DeviceInterface::Type type) + { + QStringList list; + + switch(type) + { + case Solid::DeviceInterface::GenericInterface: + list << "generic"; + break; + //case Solid::DeviceInterface::Processor: + // Doesn't exist with UDisks + // break; + case Solid::DeviceInterface::Block: + list << "block"; + break; + case Solid::DeviceInterface::StorageAccess: + list << "volume"; + break; + case Solid::DeviceInterface::StorageDrive: + list << "storage"; + break; + case Solid::DeviceInterface::OpticalDrive: + list << "storage.cdrom"; + break; + case Solid::DeviceInterface::StorageVolume: + list << "volume"; + break; + case Solid::DeviceInterface::OpticalDisc: + list << "volume.disc"; + break; + //case Solid::DeviceInterface::Camera: + // Doesn't exist with UDisks + // break; + case Solid::DeviceInterface::PortableMediaPlayer: + // Doesn't exist with UDisks + break; + /* + case Solid::DeviceInterface::NetworkInterface: + // Doesn't exist with UDisks + break; + case Solid::DeviceInterface::AcAdapter: + // Doesn't exist with UDisks + break; + case Solid::DeviceInterface::Battery: + // Doesn't exist with UDisks + break; + case Solid::DeviceInterface::Button: + // Doesn't exist with UDisks + break; + case Solid::DeviceInterface::AudioInterface: + // Doesn't exist with UDisks + break; + case Solid::DeviceInterface::DvbInterface: + // Doesn't exist with UDisks + break; + case Solid::DeviceInterface::Video: + // Doesn't exist with UDisks + break; + case Solid::DeviceInterface::SerialInterface: + // Doesn't exist with UDisks + break; + case Solid::DeviceInterface::InternetGateway: + break; + case Solid::DeviceInterface::SmartCardReader: + // Doesn't exist with UDisks + case Solid::DeviceInterface::NetworkShare: + // Doesn't exist with UDisks + break; + */ + case Solid::DeviceInterface::Unknown: + break; + case Solid::DeviceInterface::Last: + break; + } + + return list; + } + + inline static Solid::DeviceInterface::Type fromString(const QString &capability) + { + if (capability == "generic") + return Solid::DeviceInterface::GenericInterface; + /*else if (capability == "processor") + return Solid::DeviceInterface::Processor; + else if (capability == "block") + return Solid::DeviceInterface::Block; */ + else if (capability == "storage") + return Solid::DeviceInterface::StorageDrive; + else if (capability == "storage.cdrom") + return Solid::DeviceInterface::OpticalDrive; + else if (capability == "volume") + return Solid::DeviceInterface::StorageVolume; + else if (capability == "volume.disc") + return Solid::DeviceInterface::OpticalDisc; + /*else if (capability == "camera") + return Solid::DeviceInterface::Camera;*/ + else if (capability == "portable_audio_player") + return Solid::DeviceInterface::PortableMediaPlayer; + /*else if (capability == "net") + return Solid::DeviceInterface::NetworkInterface; + else if (capability == "ac_adapter") + return Solid::DeviceInterface::AcAdapter; + else if (capability == "battery") + return Solid::DeviceInterface::Battery; + else if (capability == "button") + return Solid::DeviceInterface::Button; + else if (capability == "alsa" || capability == "oss") + return Solid::DeviceInterface::AudioInterface; + else if (capability == "dvb") + return Solid::DeviceInterface::DvbInterface; + else if (capability == "video4linux") + return Solid::DeviceInterface::Video; + else if (capability == "serial") + return Solid::DeviceInterface::SerialInterface; + else if (capability == "smart_card_reader") + return Solid::DeviceInterface::SmartCardReader; + else if (capability == "networkshare") + return Solid::DeviceInterface::NetworkShare;*/ + else + return Solid::DeviceInterface::Unknown; + } +}; + +} +} +} + +#endif // UDISKSDEVICEINTERFACE_H diff --git a/solid-lite/backends/udisks/udisksgenericinterface.cpp b/solid-lite/backends/udisks/udisksgenericinterface.cpp new file mode 100644 index 000000000..56e57b48b --- /dev/null +++ b/solid-lite/backends/udisks/udisksgenericinterface.cpp @@ -0,0 +1,57 @@ +/* + Copyright 2009 Pino Toscano + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udisksgenericinterface.h" + +#include "udisksdevice.h" + +using namespace Solid::Backends::UDisks; + +GenericInterface::GenericInterface(UDisksDevice *device) + : DeviceInterface(device) +{ +/* TODO + connect(device, SIGNAL(propertyChanged(QMap)), + this, SIGNAL(propertyChanged(QMap))); + connect(device, SIGNAL(conditionRaised(QString,QString)), + this, SIGNAL(conditionRaised(QString,QString))); +*/ +} + +GenericInterface::~GenericInterface() +{ +} + +QVariant GenericInterface::property(const QString &key) const +{ + return m_device->prop(key); +} + +QMap GenericInterface::allProperties() const +{ + return m_device->allProperties(); +} + +bool GenericInterface::propertyExists(const QString &key) const +{ + return m_device->propertyExists(key); +} + +//#include "backends/udisks/udisksgenericinterface.moc" diff --git a/solid-lite/backends/udisks/udisksgenericinterface.h b/solid-lite/backends/udisks/udisksgenericinterface.h new file mode 100644 index 000000000..33ecfcbb3 --- /dev/null +++ b/solid-lite/backends/udisks/udisksgenericinterface.h @@ -0,0 +1,57 @@ +/* + Copyright 2009 Pino Toscano + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_UDISKS_GENERICINTERFACE_H +#define SOLID_BACKENDS_UDISKS_GENERICINTERFACE_H + +#include +#include +#include "udisksdeviceinterface.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ +class UDisksDevice; + +class GenericInterface : public DeviceInterface, virtual public Solid::Ifaces::GenericInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::GenericInterface) + +public: + GenericInterface(UDisksDevice *device); + virtual ~GenericInterface(); + + virtual QVariant property(const QString &key) const; + virtual QMap allProperties() const; + virtual bool propertyExists(const QString &key) const; + +Q_SIGNALS: + void propertyChanged(const QMap &changes); + void conditionRaised(const QString &condition, const QString &reason); +}; +} +} +} + +#endif // SOLID_BACKENDS_UDISKS_GENERICINTERFACE_H diff --git a/solid-lite/backends/udisks/udisksmanager.cpp b/solid-lite/backends/udisks/udisksmanager.cpp new file mode 100644 index 000000000..11454ceab --- /dev/null +++ b/solid-lite/backends/udisks/udisksmanager.cpp @@ -0,0 +1,270 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udisksmanager.h" +#include "udisks.h" + +#include +#include +#include +#include + +#include "../shared/rootdevice.h" + +using namespace Solid::Backends::UDisks; +using namespace Solid::Backends::Shared; + +UDisksManager::UDisksManager(QObject *parent) + : Solid::Ifaces::DeviceManager(parent), + m_manager(UD_DBUS_SERVICE, + UD_DBUS_PATH, + UD_DBUS_INTERFACE_DISKS, + QDBusConnection::systemBus()) +{ + m_supportedInterfaces + << Solid::DeviceInterface::GenericInterface + << Solid::DeviceInterface::Block + << Solid::DeviceInterface::StorageAccess + << Solid::DeviceInterface::StorageDrive + << Solid::DeviceInterface::OpticalDrive + << Solid::DeviceInterface::OpticalDisc + << Solid::DeviceInterface::StorageVolume; + + qDBusRegisterMetaType >(); + qDBusRegisterMetaType(); + + bool serviceFound = m_manager.isValid(); + if (!serviceFound) { + // find out whether it will be activated automatically + QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "ListActivatableNames"); + + QDBusReply reply = QDBusConnection::systemBus().call(message); + if (reply.isValid() && reply.value().contains(UD_DBUS_SERVICE)) { + QDBusConnection::systemBus().interface()->startService(UD_DBUS_SERVICE); + serviceFound = true; + } + } + + if (serviceFound) { + connect(&m_manager, SIGNAL(DeviceAdded(QDBusObjectPath)), + this, SLOT(slotDeviceAdded(QDBusObjectPath))); + connect(&m_manager, SIGNAL(DeviceRemoved(QDBusObjectPath)), + this, SLOT(slotDeviceRemoved(QDBusObjectPath))); + connect(&m_manager, SIGNAL(DeviceChanged(QDBusObjectPath)), + this, SLOT(slotDeviceChanged(QDBusObjectPath))); + } +} + +UDisksManager::~UDisksManager() +{ + +} + +QObject* UDisksManager::createDevice(const QString& udi) +{ + if (udi==udiPrefix()) { + RootDevice *root = new RootDevice(udi); + + root->setProduct(tr("Storage")); + root->setDescription(tr("Storage devices")); + root->setIcon("server-database"); // Obviously wasn't meant for that, but maps nicely in oxygen icon set :-p + + return root; + + } else if (deviceCache().contains(udi)) { + return new UDisksDevice(udi); + + } else { + return 0; + } +} + +QStringList UDisksManager::devicesFromQuery(const QString& parentUdi, Solid::DeviceInterface::Type type) +{ + QStringList result; + + if (!parentUdi.isEmpty()) + { + foreach (const QString &udi, deviceCache()) + { + if (udi==udiPrefix()) + continue; + + UDisksDevice device(udi); + if (device.queryDeviceInterface(type) && device.parentUdi() == parentUdi) + result << udi; + } + + return result; + } + else if (type != Solid::DeviceInterface::Unknown) + { + foreach (const QString &udi, deviceCache()) + { + if (udi==udiPrefix()) + continue; + + UDisksDevice device(udi); + if (device.queryDeviceInterface(type)) + result << udi; + } + + return result; + } + + return deviceCache(); +} + +QStringList UDisksManager::allDevices() +{ + m_knownDrivesWithMedia.clear(); + m_deviceCache.clear(); + m_deviceCache << udiPrefix(); + + foreach(const QString &udi, allDevicesInternal()) + { + m_deviceCache.append(udi); + + UDisksDevice device(udi); + if (device.queryDeviceInterface(Solid::DeviceInterface::OpticalDrive)) // forge a special (separate) device for optical discs + { + if (device.prop("DeviceIsOpticalDisc").toBool()) + { + if (!m_knownDrivesWithMedia.contains(udi)) + m_knownDrivesWithMedia.append(udi); + m_deviceCache.append(udi + ":media"); + } + } + } + + return m_deviceCache; +} + +QStringList UDisksManager::allDevicesInternal() +{ + QDBusReply > reply = m_manager.call("EnumerateDevices"); + + if (!reply.isValid()) { + qWarning() << Q_FUNC_INFO << " error: " << reply.error().name(); + return QStringList(); + } + + QStringList retList; + foreach(const QDBusObjectPath &path, reply.value()) { + retList << path.path(); + } + + return retList; +} + +QSet< Solid::DeviceInterface::Type > UDisksManager::supportedInterfaces() const +{ + return m_supportedInterfaces; +} + +QString UDisksManager::udiPrefix() const +{ + return UD_UDI_DISKS_PREFIX; +} + +void UDisksManager::slotDeviceAdded(const QDBusObjectPath &opath) +{ + const QString udi = opath.path(); + + if (!m_deviceCache.contains(udi)) { + m_deviceCache.append(udi); + } + + UDisksDevice device(udi); + if (device.queryDeviceInterface(Solid::DeviceInterface::StorageDrive) + && !device.prop("DeviceIsMediaAvailable").toBool() + && !m_dirtyDevices.contains(udi)) + m_dirtyDevices.append(udi); + + emit deviceAdded(udi); + slotDeviceChanged(opath); // case: hotswap event (optical drive with media inside) +} + +void UDisksManager::slotDeviceRemoved(const QDBusObjectPath &opath) +{ + const QString udi = opath.path(); + + // case: hotswap event (optical drive with media inside) + if (m_knownDrivesWithMedia.contains(udi)) { + m_knownDrivesWithMedia.removeAll(udi); + m_deviceCache.removeAll(udi + ":media"); + emit deviceRemoved(udi + ":media"); + } + + if (m_dirtyDevices.contains(udi)) + m_dirtyDevices.removeAll(udi); + + emit deviceRemoved(udi); + m_deviceCache.removeAll(opath.path()); +} + +void UDisksManager::slotDeviceChanged(const QDBusObjectPath &opath) +{ + const QString udi = opath.path(); + UDisksDevice device(udi); + + if (device.queryDeviceInterface(Solid::DeviceInterface::OpticalDrive)) + { + if (!m_knownDrivesWithMedia.contains(udi) && device.prop("DeviceIsOpticalDisc").toBool()) + { + m_knownDrivesWithMedia.append(udi); + if (!m_deviceCache.isEmpty()) { + m_deviceCache.append(udi + ":media"); + } + emit deviceAdded(udi + ":media"); + } + + if (m_knownDrivesWithMedia.contains(udi) && !device.prop("DeviceIsOpticalDisc").toBool()) + { + m_knownDrivesWithMedia.removeAll(udi); + m_deviceCache.removeAll(udi + ":media"); + emit deviceRemoved(udi + ":media"); + } + } + + if (device.queryDeviceInterface(Solid::DeviceInterface::StorageDrive) + && device.prop("DeviceIsMediaAvailable").toBool() + && m_dirtyDevices.contains(udi)) + { + //qDebug() << "dirty device added:" << udi; + emit deviceAdded(udi); + m_dirtyDevices.removeAll(udi); + } +} + +const QStringList &UDisksManager::deviceCache() +{ + if (m_deviceCache.isEmpty()) + allDevices(); + + return m_deviceCache; +} + + +//#include "backends/udisks/udisksmanager.moc" diff --git a/solid-lite/backends/udisks/udisksmanager.h b/solid-lite/backends/udisks/udisksmanager.h new file mode 100644 index 000000000..4b9d45f86 --- /dev/null +++ b/solid-lite/backends/udisks/udisksmanager.h @@ -0,0 +1,70 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDISKSMANAGER_H +#define UDISKSMANAGER_H + +#include "udisksdevice.h" + +#include "solid-lite/ifaces/devicemanager.h" + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ + +class UDisksManager : public Solid::Ifaces::DeviceManager +{ + Q_OBJECT + +public: + UDisksManager(QObject *parent); + virtual QObject* createDevice(const QString& udi); + virtual QStringList devicesFromQuery(const QString& parentUdi, Solid::DeviceInterface::Type type); + virtual QStringList allDevices(); + virtual QSet< Solid::DeviceInterface::Type > supportedInterfaces() const; + virtual QString udiPrefix() const; + virtual ~UDisksManager(); + +private Q_SLOTS: + void slotDeviceAdded(const QDBusObjectPath &opath); + void slotDeviceRemoved(const QDBusObjectPath &opath); + void slotDeviceChanged(const QDBusObjectPath &opath); + +private: + const QStringList &deviceCache(); + QStringList allDevicesInternal(); + QStringList m_knownDrivesWithMedia; // list of known optical drives which contain a media + QSet m_supportedInterfaces; + QDBusInterface m_manager; + QStringList m_deviceCache; + QStringList m_dirtyDevices; // special 2-stage storage like Nokia N900 +}; + +} +} +} +#endif // UDISKSMANAGER_H diff --git a/solid-lite/backends/udisks/udisksopticaldisc.cpp b/solid-lite/backends/udisks/udisksopticaldisc.cpp new file mode 100644 index 000000000..42272aad8 --- /dev/null +++ b/solid-lite/backends/udisks/udisksopticaldisc.cpp @@ -0,0 +1,260 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010, 2011 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include +#include +#include +#include + +#include + +#include "udisksopticaldisc.h" + +// inspired by http://cgit.freedesktop.org/hal/tree/hald/linux/probing/probe-volume.c +static Solid::OpticalDisc::ContentType advancedDiscDetect(const QString & device_file) +{ + /* the discs block size */ + unsigned short bs; + /* the path table size */ + unsigned short ts; + /* the path table location (in blocks) */ + unsigned int tl; + /* length of the directory name in current path table entry */ + unsigned char len_di = 0; + /* the number of the parent directory's path table entry */ + unsigned int parent = 0; + /* filename for the current path table entry */ + char dirname[256]; + /* our position into the path table */ + int pos = 0; + /* the path table record we're on */ + int curr_record = 1; + + Solid::OpticalDisc::ContentType result = Solid::OpticalDisc::NoContent; + + int fd = open (QFile::encodeName(device_file), O_RDONLY); + + /* read the block size */ + lseek (fd, 0x8080, SEEK_CUR); + if (read (fd, &bs, 2) != 2) + { + qDebug("Advanced probing on %s failed while reading block size", qPrintable(device_file)); + goto out; + } + + /* read in size of path table */ + lseek (fd, 2, SEEK_CUR); + if (read (fd, &ts, 2) != 2) + { + qDebug("Advanced probing on %s failed while reading path table size", qPrintable(device_file)); + goto out; + } + + /* read in which block path table is in */ + lseek (fd, 6, SEEK_CUR); + if (read (fd, &tl, 4) != 4) + { + qDebug("Advanced probing on %s failed while reading path table block", qPrintable(device_file)); + goto out; + } + + /* seek to the path table */ + lseek (fd, bs * tl, SEEK_SET); + + /* loop through the path table entries */ + while (pos < ts) + { + /* get the length of the filename of the current entry */ + if (read (fd, &len_di, 1) != 1) + { + qDebug("Advanced probing on %s failed, cannot read more entries", qPrintable(device_file)); + break; + } + + /* get the record number of this entry's parent + i'm pretty sure that the 1st entry is always the top directory */ + lseek (fd, 5, SEEK_CUR); + if (read (fd, &parent, 2) != 2) + { + qDebug("Advanced probing on %s failed, couldn't read parent entry", qPrintable(device_file)); + break; + } + + /* read the name */ + if (read (fd, dirname, len_di) != len_di) + { + qDebug("Advanced probing on %s failed, couldn't read the entry name", qPrintable(device_file)); + break; + } + dirname[len_di] = 0; + + /* if we found a folder that has the root as a parent, and the directory name matches + one of the special directories then set the properties accordingly */ + if (parent == 1) + { + if (!strcasecmp (dirname, "VIDEO_TS")) + { + qDebug("Disc in %s is a Video DVD", qPrintable(device_file)); + result = Solid::OpticalDisc::VideoDvd; + break; + } + else if (!strcasecmp (dirname, "BDMV")) + { + qDebug("Disc in %s is a Blu-ray video disc", qPrintable(device_file)); + result = Solid::OpticalDisc::VideoBluRay; + break; + } + else if (!strcasecmp (dirname, "VCD")) + { + qDebug("Disc in %s is a Video CD", qPrintable(device_file)); + result = Solid::OpticalDisc::VideoCd; + break; + } + else if (!strcasecmp (dirname, "SVCD")) + { + qDebug("Disc in %s is a Super Video CD", qPrintable(device_file)); + result = Solid::OpticalDisc::SuperVideoCd; + break; + } + } + + /* all path table entries are padded to be even, + so if this is an odd-length table, seek a byte to fix it */ + if (len_di%2 == 1) + { + lseek (fd, 1, SEEK_CUR); + pos++; + } + + /* update our position */ + pos += 8 + len_di; + curr_record++; + } + + close(fd); + return result; + +out: + /* go back to the start of the file */ + lseek (fd, 0, SEEK_SET); + close(fd); + return result; +} + +using namespace Solid::Backends::UDisks; + +OpticalDisc::OpticalDisc(UDisksDevice *device) + : UDisksStorageVolume(device), m_needsReprobe(true), m_cachedContent(Solid::OpticalDisc::NoContent) +{ + connect(device, SIGNAL(changed()), this, SLOT(slotChanged())); +} + +OpticalDisc::~OpticalDisc() +{ + +} + +qulonglong OpticalDisc::capacity() const +{ + return m_device->prop("DeviceSize").toULongLong(); +} + +bool OpticalDisc::isRewritable() const +{ + // the hard way, udisks has no notion of a disc "rewritability" + const QString mediaType = m_device->prop("DriveMedia").toString(); + return mediaType == "optical_cd_rw" || mediaType == "optical_dvd_rw" || mediaType == "optical_dvd_ram" || + mediaType == "optical_dvd_plus_rw" || mediaType == "optical_dvd_plus_rw_dl" || + mediaType == "optical_bd_re" || mediaType == "optical_hddvd_rw"; // TODO check completeness +} + +bool OpticalDisc::isBlank() const +{ + return m_device->prop("OpticalDiscIsBlank").toBool(); +} + +bool OpticalDisc::isAppendable() const +{ + return m_device->prop("OpticalDiscIsAppendable").toBool(); +} + +Solid::OpticalDisc::DiscType OpticalDisc::discType() const +{ + const QString discType = m_device->prop("DriveMedia").toString(); + + QMap map; + map[Solid::OpticalDisc::CdRom] = "optical_cd"; + map[Solid::OpticalDisc::CdRecordable] = "optical_cd_r"; + map[Solid::OpticalDisc::CdRewritable] = "optical_cd_rw"; + map[Solid::OpticalDisc::DvdRom] = "optical_dvd"; + map[Solid::OpticalDisc::DvdRecordable] = "optical_dvd_r"; + map[Solid::OpticalDisc::DvdRewritable] ="optical_dvd_rw"; + map[Solid::OpticalDisc::DvdRam] ="optical_dvd_ram"; + map[Solid::OpticalDisc::DvdPlusRecordable] ="optical_dvd_plus_r"; + map[Solid::OpticalDisc::DvdPlusRewritable] ="optical_dvd_plus_rw"; + map[Solid::OpticalDisc::DvdPlusRecordableDuallayer] ="optical_dvd_plus_r_dl"; + map[Solid::OpticalDisc::DvdPlusRewritableDuallayer] ="optical_dvd_plus_rw_dl"; + map[Solid::OpticalDisc::BluRayRom] ="optical_bd"; + map[Solid::OpticalDisc::BluRayRecordable] ="optical_bd_r"; + map[Solid::OpticalDisc::BluRayRewritable] ="optical_bd_re"; + map[Solid::OpticalDisc::HdDvdRom] ="optical_hddvd"; + map[Solid::OpticalDisc::HdDvdRecordable] ="optical_hddvd_r"; + map[Solid::OpticalDisc::HdDvdRewritable] ="optical_hddvd_rw"; + // TODO add these to Solid + //map[Solid::OpticalDisc::MagnetoOptical] ="optical_mo"; + //map[Solid::OpticalDisc::MountRainer] ="optical_mrw"; + //map[Solid::OpticalDisc::MountRainerWritable] ="optical_mrw_w"; + + return map.key( discType, Solid::OpticalDisc::UnknownDiscType ); +} + +Solid::OpticalDisc::ContentTypes OpticalDisc::availableContent() const +{ + if (isBlank()) { + m_needsReprobe = false; + return Solid::OpticalDisc::NoContent; + } + + if (m_needsReprobe) { + m_cachedContent = Solid::OpticalDisc::NoContent; + bool hasData = m_device->prop("OpticalDiscNumTracks").toInt() > 0 && + m_device->prop("OpticalDiscNumTracks").toInt() > m_device->prop("OpticalDiscNumAudioTracks").toInt(); + bool hasAudio = m_device->prop("OpticalDiscNumAudioTracks").toInt() > 0; + + if ( hasData ) { + m_cachedContent |= Solid::OpticalDisc::Data; + m_cachedContent |= advancedDiscDetect(m_device->prop("DeviceFile").toString()); + } + if ( hasAudio ) + m_cachedContent |= Solid::OpticalDisc::Audio; + + m_needsReprobe = false; + } + + return m_cachedContent; +} + +void OpticalDisc::slotChanged() +{ + m_needsReprobe = true; + m_cachedContent = Solid::OpticalDisc::NoContent; +} + diff --git a/solid-lite/backends/udisks/udisksopticaldisc.h b/solid-lite/backends/udisks/udisksopticaldisc.h new file mode 100644 index 000000000..a0319764c --- /dev/null +++ b/solid-lite/backends/udisks/udisksopticaldisc.h @@ -0,0 +1,63 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010, 2011 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef OPTICALDISC_H +#define OPTICALDISC_H + +#include +#include "udisksstoragevolume.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ + +class OpticalDisc : public UDisksStorageVolume, virtual public Solid::Ifaces::OpticalDisc +{ + + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::OpticalDisc) + +public: + OpticalDisc(UDisksDevice *device); + virtual ~OpticalDisc(); + + virtual qulonglong capacity() const; + virtual bool isRewritable() const; + virtual bool isBlank() const; + virtual bool isAppendable() const; + virtual Solid::OpticalDisc::DiscType discType() const; + virtual Solid::OpticalDisc::ContentTypes availableContent() const; + +private slots: + void slotChanged(); + +private: + mutable bool m_needsReprobe; + mutable Solid::OpticalDisc::ContentTypes m_cachedContent; +}; + +} +} +} +#endif // OPTICALDISC_H diff --git a/solid-lite/backends/udisks/udisksopticaldrive.cpp b/solid-lite/backends/udisks/udisksopticaldrive.cpp new file mode 100644 index 000000000..601c84237 --- /dev/null +++ b/solid-lite/backends/udisks/udisksopticaldrive.cpp @@ -0,0 +1,197 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010-2011 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "udisksopticaldrive.h" +#include "udisks.h" +#include "udisksdevice.h" + +using namespace Solid::Backends::UDisks; + +UDisksOpticalDrive::UDisksOpticalDrive(UDisksDevice *device) + : UDisksStorageDrive(device), m_ejectInProgress(false), m_readSpeed(0), m_writeSpeed(0), m_speedsInit(false) +{ + m_device->registerAction("eject", this, + SLOT(slotEjectRequested()), + SLOT(slotEjectDone(int,QString))); + + connect(m_device, SIGNAL(changed()), this, SLOT(slotChanged())); +} + +UDisksOpticalDrive::~UDisksOpticalDrive() +{ + +} + +bool UDisksOpticalDrive::eject() +{ + if (m_ejectInProgress) + return false; + m_ejectInProgress = true; + m_device->broadcastActionRequested("eject"); + + QDBusConnection c = QDBusConnection::systemBus(); + + QString path = m_device->udi(); + + // check if the device is mounted and call umount if needed + if (m_device->prop("DeviceIsMounted").toBool()) + { + QDBusMessage msg = QDBusMessage::createMethodCall(UD_DBUS_SERVICE, path, UD_DBUS_INTERFACE_DISKS_DEVICE, "FilesystemUnmount"); + msg << QStringList(); // options, unused now + c.call(msg, QDBus::NoBlock); + } + + QDBusMessage msg = QDBusMessage::createMethodCall(UD_DBUS_SERVICE, path, UD_DBUS_INTERFACE_DISKS_DEVICE, "DriveEject"); + msg << QStringList(); + return c.callWithCallback(msg, this, SLOT(slotDBusReply(QDBusMessage)), SLOT(slotDBusError(QDBusError))); +} + +void UDisksOpticalDrive::slotDBusReply(const QDBusMessage &/*reply*/) +{ + m_ejectInProgress = false; + m_device->broadcastActionDone("eject"); +} + +void UDisksOpticalDrive::slotDBusError(const QDBusError &error) +{ + m_ejectInProgress = false; + m_device->broadcastActionDone("eject", m_device->errorToSolidError(error.name()), + m_device->errorToString(error.name()) + ": " +error.message()); +} + +void UDisksOpticalDrive::slotEjectRequested() +{ + m_ejectInProgress = true; + emit ejectRequested(m_device->udi()); +} + +void UDisksOpticalDrive::slotEjectDone(int error, const QString &errorString) +{ + m_ejectInProgress = false; + emit ejectDone(static_cast(error), errorString, m_device->udi()); +} + +void UDisksOpticalDrive::initReadWriteSpeeds() const +{ +#if 0 + int read_speed, write_speed; + char *write_speeds = 0; + QByteArray device_file = QFile::encodeName(m_device->property("DeviceFile").toString()); + + //qDebug("Doing open (\"%s\", O_RDONLY | O_NONBLOCK)", device_file.constData()); + int fd = open(device_file, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + qWarning("Cannot open %s: %s", device_file.constData(), strerror (errno)); + return; + } + + if (get_read_write_speed(fd, &read_speed, &write_speed, &write_speeds) >= 0) { + m_readSpeed = read_speed; + m_writeSpeed = write_speed; + + QStringList list = QString::fromLatin1(write_speeds).split(',', QString::SkipEmptyParts); + foreach (const QString & speed, list) + m_writeSpeeds.append(speed.toInt()); + + free(write_speeds); + + m_speedsInit = true; + } + + close(fd); +#endif +} + +QList UDisksOpticalDrive::writeSpeeds() const +{ + if (!m_speedsInit) + initReadWriteSpeeds(); + //qDebug() << "solid write speeds:" << m_writeSpeeds; + return m_writeSpeeds; +} + +int UDisksOpticalDrive::writeSpeed() const +{ + if (!m_speedsInit) + initReadWriteSpeeds(); + return m_writeSpeed; +} + +int UDisksOpticalDrive::readSpeed() const +{ + if (!m_speedsInit) + initReadWriteSpeeds(); + return m_readSpeed; +} + +Solid::OpticalDrive::MediumTypes UDisksOpticalDrive::supportedMedia() const +{ + const QStringList mediaTypes = m_device->prop("DriveMediaCompatibility").toStringList(); + Solid::OpticalDrive::MediumTypes supported; + + QMap map; + map[Solid::OpticalDrive::Cdr] = "optical_cd_r"; + map[Solid::OpticalDrive::Cdrw] = "optical_cd_rw"; + map[Solid::OpticalDrive::Dvd] = "optical_dvd"; + map[Solid::OpticalDrive::Dvdr] = "optical_dvd_r"; + map[Solid::OpticalDrive::Dvdrw] ="optical_dvd_rw"; + map[Solid::OpticalDrive::Dvdram] ="optical_dvd_ram"; + map[Solid::OpticalDrive::Dvdplusr] ="optical_dvd_plus_r"; + map[Solid::OpticalDrive::Dvdplusrw] ="optical_dvd_plus_rw"; + map[Solid::OpticalDrive::Dvdplusdl] ="optical_dvd_plus_r_dl"; + map[Solid::OpticalDrive::Dvdplusdlrw] ="optical_dvd_plus_rw_dl"; + map[Solid::OpticalDrive::Bd] ="optical_bd"; + map[Solid::OpticalDrive::Bdr] ="optical_bd_r"; + map[Solid::OpticalDrive::Bdre] ="optical_bd_re"; + map[Solid::OpticalDrive::HdDvd] ="optical_hddvd"; + map[Solid::OpticalDrive::HdDvdr] ="optical_hddvd_r"; + map[Solid::OpticalDrive::HdDvdrw] ="optical_hddvd_rw"; + // TODO add these to Solid + //map[Solid::OpticalDrive::Mo] ="optical_mo"; + //map[Solid::OpticalDrive::Mr] ="optical_mrw"; + //map[Solid::OpticalDrive::Mrw] ="optical_mrw_w"; + + foreach ( const Solid::OpticalDrive::MediumType & type, map.keys() ) + { + if ( mediaTypes.contains( map[type] ) ) + { + supported |= type; + } + } + + return supported; +} + +void UDisksOpticalDrive::slotChanged() +{ + m_speedsInit = false; // reset the read/write speeds, changes eg. with an inserted media +} diff --git a/solid-lite/backends/udisks/udisksopticaldrive.h b/solid-lite/backends/udisks/udisksopticaldrive.h new file mode 100644 index 000000000..1e5d634f7 --- /dev/null +++ b/solid-lite/backends/udisks/udisksopticaldrive.h @@ -0,0 +1,81 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDISKSOPTICALDRIVE_H +#define UDISKSOPTICALDRIVE_H + +#include +#include "udisksstoragedrive.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ + +class UDisksOpticalDrive: public UDisksStorageDrive, virtual public Solid::Ifaces::OpticalDrive +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::OpticalDrive) + +public: + UDisksOpticalDrive(UDisksDevice *device); + virtual ~UDisksOpticalDrive(); + +Q_SIGNALS: + void ejectPressed(const QString &udi); + void ejectDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void ejectRequested(const QString &udi); + +public: + virtual bool eject(); + virtual QList writeSpeeds() const; + virtual int writeSpeed() const; + virtual int readSpeed() const; + virtual Solid::OpticalDrive::MediumTypes supportedMedia() const; + +private Q_SLOTS: + void slotDBusReply(const QDBusMessage &reply); + void slotDBusError(const QDBusError &error); + + void slotEjectRequested(); + void slotEjectDone(int error, const QString &errorString); + + void slotChanged(); + +private: + void initReadWriteSpeeds() const; + + bool m_ejectInProgress; + + // read/write speeds + mutable int m_readSpeed; + mutable int m_writeSpeed; + mutable QList m_writeSpeeds; + mutable bool m_speedsInit; +}; + +} +} +} + +#endif // UDISKSOPTICALDRIVE_H diff --git a/solid-lite/backends/udisks/udisksstorageaccess.cpp b/solid-lite/backends/udisks/udisksstorageaccess.cpp new file mode 100644 index 000000000..49ace5b44 --- /dev/null +++ b/solid-lite/backends/udisks/udisksstorageaccess.cpp @@ -0,0 +1,382 @@ +/* + Copyright 2009 Pino Toscano + Copyright 2009, 2011 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udisksstorageaccess.h" +#include "udisks.h" + +#include +#include +#include +#include + +using namespace Solid::Backends::UDisks; + +UDisksStorageAccess::UDisksStorageAccess(UDisksDevice *device) + : DeviceInterface(device), m_setupInProgress(false), m_teardownInProgress(false), m_passphraseRequested(false) +{ + connect(device, SIGNAL(changed()), this, SLOT(slotChanged())); + updateCache(); + + // Delay connecting to DBus signals to avoid the related time penalty + // in hot paths such as predicate matching + QTimer::singleShot(0, this, SLOT(connectDBusSignals())); +} + +UDisksStorageAccess::~UDisksStorageAccess() +{ +} + +void UDisksStorageAccess::connectDBusSignals() +{ + m_device->registerAction("setup", this, + SLOT(slotSetupRequested()), + SLOT(slotSetupDone(int,QString))); + + m_device->registerAction("teardown", this, + SLOT(slotTeardownRequested()), + SLOT(slotTeardownDone(int,QString))); +} + +bool UDisksStorageAccess::isLuksDevice() const +{ + return m_device->prop("DeviceIsLuks").toBool(); +} + +bool UDisksStorageAccess::isAccessible() const +{ + if (isLuksDevice()) { // check if the cleartext slave is mounted + UDisksDevice holderDevice(m_device->prop("LuksHolder").value().path()); + return holderDevice.prop("DeviceIsMounted").toBool(); + } + + return m_device->prop("DeviceIsMounted").toBool(); +} + +QString UDisksStorageAccess::filePath() const +{ + if (!isAccessible()) + return QString(); + + QStringList mntPoints; + + if (isLuksDevice()) { // encrypted (and unlocked) device + QString path = m_device->prop("LuksHolder").value().path(); + if (path.isEmpty() || path == "/") + return QString(); + UDisksDevice holderDevice(path); + mntPoints = holderDevice.prop("DeviceMountPaths").toStringList(); + if (!mntPoints.isEmpty()) + return mntPoints.first(); // FIXME Solid doesn't support multiple mount points + else + return QString(); + } + + mntPoints = m_device->prop("DeviceMountPaths").toStringList(); + + if (!mntPoints.isEmpty()) + return mntPoints.first(); // FIXME Solid doesn't support multiple mount points + else + return QString(); +} + +bool UDisksStorageAccess::isIgnored() const +{ + return m_device->isDeviceBlacklisted(); +} + +bool UDisksStorageAccess::setup() +{ + if ( m_teardownInProgress || m_setupInProgress ) + return false; + m_setupInProgress = true; + m_device->broadcastActionRequested("setup"); + + if (m_device->prop("IdUsage").toString() == "crypto") + return requestPassphrase(); + else + return mount(); +} + +bool UDisksStorageAccess::teardown() +{ + if ( m_teardownInProgress || m_setupInProgress ) + return false; + m_teardownInProgress = true; + m_device->broadcastActionRequested("teardown"); + + return unmount(); +} + +void UDisksStorageAccess::slotChanged() +{ + const bool old_isAccessible = m_isAccessible; + updateCache(); + + if (old_isAccessible != m_isAccessible) + { + emit accessibilityChanged(m_isAccessible, m_device->udi()); + } +} + +void UDisksStorageAccess::updateCache() +{ + m_isAccessible = isAccessible(); +} + +void UDisksStorageAccess::slotDBusReply( const QDBusMessage & reply ) +{ + Q_UNUSED(reply); + if (m_setupInProgress) + { + if (isLuksDevice() && !isAccessible()) // unlocked device, now mount it + mount(); + + else // Don't broadcast setupDone unless the setup is really done. (Fix kde#271156) + { + m_setupInProgress = false; + m_device->broadcastActionDone("setup"); + } + } + else if (m_teardownInProgress) + { + QString clearTextPath = m_device->prop("LuksHolder").value().path(); + if (isLuksDevice() && clearTextPath != "/") // unlocked device, lock it + { + callCryptoTeardown(); + } + else if (m_device->prop("DeviceIsLuksCleartext").toBool()) { + callCryptoTeardown(true); // Lock crypted parent + } + else + { + if (m_device->prop("DriveIsMediaEjectable").toBool() && + m_device->prop("DeviceIsMediaAvailable").toBool() && + !m_device->prop("DeviceIsOpticalDisc").toBool()) // optical drives have their Eject method + { + QString devnode = m_device->prop("DeviceFile").toString(); + +#if defined(Q_OS_OPENBSD) + QString program = "cdio"; + QStringList args; + args << "-f" << devnode << "eject"; +#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) + devnode.remove("/dev/").replace("([0-9]).", "\\1"); + QString program = "cdcontrol"; + QStringList args; + args << "-f" << devnode << "eject"; +#else + QString program = "eject"; + QStringList args; + args << devnode; +#endif + + QProcess::startDetached( program, args ); + } + + // try to eject the (parent) drive, e.g. SD card from a reader + QString drivePath = m_device->prop("PartitionSlave").value().path(); + if (!drivePath.isEmpty() || drivePath != "/") + { + QDBusConnection c = QDBusConnection::systemBus(); + QDBusMessage msg = QDBusMessage::createMethodCall(UD_DBUS_SERVICE, drivePath, UD_DBUS_INTERFACE_DISKS_DEVICE, "DriveEject"); + msg << QStringList(); // options, unused now + c.call(msg, QDBus::NoBlock); + } + + m_teardownInProgress = false; + m_device->broadcastActionDone("teardown"); + } + } +} + +void UDisksStorageAccess::slotDBusError( const QDBusError & error ) +{ + if (m_setupInProgress) + { + m_setupInProgress = false; + m_device->broadcastActionDone("setup", m_device->errorToSolidError(error.name()), + m_device->errorToString(error.name()) + ": " +error.message()); + + } + else if (m_teardownInProgress) + { + m_teardownInProgress = false; + m_device->broadcastActionDone("teardown", m_device->errorToSolidError(error.name()), + m_device->errorToString(error.name()) + ": " + error.message()); + } +} + +void UDisksStorageAccess::slotSetupRequested() +{ + m_setupInProgress = true; + emit setupRequested(m_device->udi()); +} + +void UDisksStorageAccess::slotSetupDone(int error, const QString &errorString) +{ + m_setupInProgress = false; + emit setupDone(static_cast(error), errorString, m_device->udi()); + slotChanged(); +} + +void UDisksStorageAccess::slotTeardownRequested() +{ + m_teardownInProgress = true; + emit teardownRequested(m_device->udi()); +} + +void UDisksStorageAccess::slotTeardownDone(int error, const QString &errorString) +{ + m_teardownInProgress = false; + emit teardownDone(static_cast(error), errorString, m_device->udi()); + slotChanged(); +} + +bool UDisksStorageAccess::mount() +{ + QString path = m_device->udi(); + if (path.endsWith(":media")) { + path.chop(6); + } + QString fstype; + QStringList options; + + if (isLuksDevice()) { // mount options for the cleartext volume + path = m_device->prop("LuksHolder").value().path(); + UDisksDevice holderDevice(path); + fstype = holderDevice.prop("IdType").toString(); + } + + QDBusConnection c = QDBusConnection::systemBus(); + QDBusMessage msg = QDBusMessage::createMethodCall(UD_DBUS_SERVICE, path, UD_DBUS_INTERFACE_DISKS_DEVICE, "FilesystemMount"); + + if (m_device->prop("IdUsage").toString() == "filesystem") + fstype = m_device->prop("IdType").toString(); + + if (fstype == "vfat") { + options << "flush"; + } + + msg << fstype; + msg << options; + + return c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError))); +} + +bool UDisksStorageAccess::unmount() +{ + QString path = m_device->udi(); + if (path.endsWith(":media")) { + path.chop(6); + } + + if (isLuksDevice()) { // unmount options for the cleartext volume + path = m_device->prop("LuksHolder").value().path(); + } + + QDBusConnection c = QDBusConnection::systemBus(); + QDBusMessage msg = QDBusMessage::createMethodCall(UD_DBUS_SERVICE, path, UD_DBUS_INTERFACE_DISKS_DEVICE, "FilesystemUnmount"); + + msg << QStringList(); // options, unused now + + return c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError)), + s_unmountTimeout); +} + +QString UDisksStorageAccess::generateReturnObjectPath() +{ + static int number = 1; + + return "/org/kde/solid/UDisksStorageAccess_"+QString::number(number++); +} + +bool UDisksStorageAccess::requestPassphrase() +{ + QString udi = m_device->udi(); + QString returnService = QDBusConnection::sessionBus().baseService(); + m_lastReturnObject = generateReturnObjectPath(); + + QDBusConnection::sessionBus().registerObject(m_lastReturnObject, this, QDBusConnection::ExportScriptableSlots); + + QWidget *activeWindow = QApplication::activeWindow(); + uint wId = 0; + if (activeWindow!=0) + wId = (uint)activeWindow->winId(); + + QString appId = QCoreApplication::applicationName(); + + QDBusInterface soliduiserver("org.kde.kded", "/modules/soliduiserver", "org.kde.SolidUiServer"); + QDBusReply reply = soliduiserver.call("showPassphraseDialog", udi, returnService, + m_lastReturnObject, wId, appId); + m_passphraseRequested = reply.isValid(); + if (!m_passphraseRequested) + qWarning() << "Failed to call the SolidUiServer, D-Bus said:" << reply.error(); + + return m_passphraseRequested; +} + +void UDisksStorageAccess::passphraseReply( const QString & passphrase ) +{ + if (m_passphraseRequested) + { + QDBusConnection::sessionBus().unregisterObject(m_lastReturnObject); + m_passphraseRequested = false; + if (!passphrase.isEmpty()) + callCryptoSetup(passphrase); + else + { + m_setupInProgress = false; + m_device->broadcastActionDone("setup"); + } + } +} + +void UDisksStorageAccess::callCryptoSetup( const QString & passphrase ) +{ + QDBusConnection c = QDBusConnection::systemBus(); + QDBusMessage msg = QDBusMessage::createMethodCall(UD_DBUS_SERVICE, m_device->udi(), UD_DBUS_INTERFACE_DISKS_DEVICE, "LuksUnlock"); + + msg << passphrase; + msg << QStringList(); // options, unused now + + c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError))); +} + +bool UDisksStorageAccess::callCryptoTeardown(bool actOnParent) +{ + QDBusConnection c = QDBusConnection::systemBus(); + QDBusMessage msg = QDBusMessage::createMethodCall(UD_DBUS_SERVICE, + actOnParent?(m_device->prop("LuksCleartextSlave").value().path()):m_device->udi(), + UD_DBUS_INTERFACE_DISKS_DEVICE, "LuksLock"); + msg << QStringList(); // options, unused now + + return c.callWithCallback(msg, this, + SLOT(slotDBusReply(QDBusMessage)), + SLOT(slotDBusError(QDBusError))); +} + +//#include "backends/udisks/udisksstorageaccess.moc" diff --git a/solid-lite/backends/udisks/udisksstorageaccess.h b/solid-lite/backends/udisks/udisksstorageaccess.h new file mode 100644 index 000000000..57db63ea7 --- /dev/null +++ b/solid-lite/backends/udisks/udisksstorageaccess.h @@ -0,0 +1,102 @@ +/* + Copyright 2009 Pino Toscano + Copyright 2009 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDISKSSTORAGEACCESS_H +#define UDISKSSTORAGEACCESS_H + +#include +#include "udisksdeviceinterface.h" + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ +class UDisksStorageAccess : public DeviceInterface, virtual public Solid::Ifaces::StorageAccess +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::StorageAccess) + +public: + UDisksStorageAccess(UDisksDevice *device); + virtual ~UDisksStorageAccess(); + + virtual bool isAccessible() const; + virtual QString filePath() const; + virtual bool isIgnored() const; + virtual bool setup(); + virtual bool teardown(); + +Q_SIGNALS: + void accessibilityChanged(bool accessible, const QString &udi); + void setupDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void teardownDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void setupRequested(const QString &udi); + void teardownRequested(const QString &udi); + +public Q_SLOTS: + Q_SCRIPTABLE Q_NOREPLY void passphraseReply( const QString & passphrase ); + +private Q_SLOTS: + void slotChanged(); + void slotDBusReply( const QDBusMessage & reply ); + void slotDBusError( const QDBusError & error ); + + void connectDBusSignals(); + + void slotSetupRequested(); + void slotSetupDone(int error, const QString &errorString); + void slotTeardownRequested(); + void slotTeardownDone(int error, const QString &errorString); + +private: + /// @return true if this device is luks and unlocked + bool isLuksDevice() const; + + void updateCache(); + + bool mount(); + bool unmount(); + + bool requestPassphrase(); + void callCryptoSetup( const QString & passphrase ); + bool callCryptoTeardown( bool actOnParent=false ); + + QString generateReturnObjectPath(); + +private: + bool m_isAccessible; + bool m_setupInProgress; + bool m_teardownInProgress; + bool m_passphraseRequested; + QString m_lastReturnObject; + + static const int s_unmountTimeout = 0x7fffffff; +}; +} +} +} + +#endif // UDISKSSTORAGEACCESS_H diff --git a/solid-lite/backends/udisks/udisksstoragedrive.cpp b/solid-lite/backends/udisks/udisksstoragedrive.cpp new file mode 100644 index 000000000..ad3b8884b --- /dev/null +++ b/solid-lite/backends/udisks/udisksstoragedrive.cpp @@ -0,0 +1,154 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udisksstoragedrive.h" + +#include + +using namespace Solid::Backends::UDisks; + +UDisksStorageDrive::UDisksStorageDrive(UDisksDevice* device) + : Block(device) +{ + +} + +UDisksStorageDrive::~UDisksStorageDrive() +{ + +} + +qulonglong UDisksStorageDrive::size() const +{ + return m_device->prop("DeviceSize").toULongLong(); +} + +bool UDisksStorageDrive::isHotpluggable() const +{ + return m_device->prop("DriveCanDetach").toBool(); +} + +bool UDisksStorageDrive::isRemovable() const +{ + return m_device->prop("DeviceIsRemovable").toBool() || + !m_device->prop( "DeviceIsSystemInternal" ).toBool(); +} + +Solid::StorageDrive::DriveType UDisksStorageDrive::driveType() const +{ + const QStringList mediaTypes = m_device->prop("DriveMediaCompatibility").toStringList(); + bool isHardDisk = m_device->prop( "DeviceIsSystemInternal" ).toBool(); + + if ( isHardDisk ) + { + return Solid::StorageDrive::HardDisk; + } + else if ( !mediaTypes.filter( "optical" ).isEmpty() ) // optical disks + { + return Solid::StorageDrive::CdromDrive; + } + else if ( mediaTypes.contains( "floppy" ) ) + { + return Solid::StorageDrive::Floppy; + } +#if 0 // TODO add to Solid + else if ( mediaTypes.contains( "floppy_jaz" ) ) + { + return Solid::StorageDrive::Jaz; + } + else if ( mediaTypes.contains( "floppy_zip" ) ) + { + return Solid::StorageDrive::Zip; + } +#endif + /* + else if (type=="tape") // FIXME: DK doesn't know about tapes + { + return Solid::StorageDrive::Tape; + } + */ +#if 0 // TODO add to Solid + else if ( mediaTypes.contains( "flash" ) ) + { + return Solid::StorageDrive::Flash; + } +#endif + else if ( mediaTypes.contains( "flash_cf" ) ) + { + return Solid::StorageDrive::CompactFlash; + } + else if ( mediaTypes.contains( "flash_ms" ) ) + { + return Solid::StorageDrive::MemoryStick; + } + else if ( mediaTypes.contains( "flash_sm" ) ) + { + return Solid::StorageDrive::SmartMedia; + } + else if ( mediaTypes.contains( "flash_sd" ) || mediaTypes.contains( "flash_sdhc" ) || mediaTypes.contains( "flash_mmc" ) ) + { + return Solid::StorageDrive::SdMmc; + } + // FIXME: DK doesn't know about xD cards either + else + { + return Solid::StorageDrive::HardDisk; + } +} + +Solid::StorageDrive::Bus UDisksStorageDrive::bus() const +{ + const QString bus = m_device->prop( "DriveConnectionInterface" ).toString(); + + if ( bus == "ata" || bus == "ata_parallel" ) // parallel (classical) ATA + { + return Solid::StorageDrive::Ide; + } + else if ( bus == "usb" ) + { + return Solid::StorageDrive::Usb; + } + else if ( bus == "firewire" ) + { + return Solid::StorageDrive::Ieee1394; + } + else if ( bus == "scsi" ) + { + return Solid::StorageDrive::Scsi; + } + else if ( bus == "ata_serial" || bus == "ata_serial_esata" ) // serial ATA + { + return Solid::StorageDrive::Sata; + } +#if 0 // TODO add these to Solid + else if ( bus == "sdio" ) + { + return Solid::StorageDrive::SDIO; + } + else if ( bus == "virtual" ) + { + return Solid::StorageDrive::Virtual; + } +#endif + else + return Solid::StorageDrive::Platform; +} + diff --git a/solid-lite/backends/udisks/udisksstoragedrive.h b/solid-lite/backends/udisks/udisksstoragedrive.h new file mode 100644 index 000000000..e9f3dd711 --- /dev/null +++ b/solid-lite/backends/udisks/udisksstoragedrive.h @@ -0,0 +1,55 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDISKSSTORAGEDRIVE_H +#define UDISKSSTORAGEDRIVE_H + +#include +#include "udisksblock.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ + +class UDisksStorageDrive: public Block, virtual public Solid::Ifaces::StorageDrive +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::StorageDrive) + +public: + UDisksStorageDrive(UDisksDevice *device); + virtual ~UDisksStorageDrive(); + + virtual qulonglong size() const; + virtual bool isHotpluggable() const; + virtual bool isRemovable() const; + virtual Solid::StorageDrive::DriveType driveType() const; + virtual Solid::StorageDrive::Bus bus() const; +}; + +} +} +} + +#endif // UDISKSSTORAGEDRIVE_H diff --git a/solid-lite/backends/udisks/udisksstoragevolume.cpp b/solid-lite/backends/udisks/udisksstoragevolume.cpp new file mode 100644 index 000000000..c6fbc4c9a --- /dev/null +++ b/solid-lite/backends/udisks/udisksstoragevolume.cpp @@ -0,0 +1,99 @@ +/* + Copyright 2010 Michael Zanetti + Copyright 2010 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udisksstoragevolume.h" + +using namespace Solid::Backends::UDisks; + +UDisksStorageVolume::UDisksStorageVolume(UDisksDevice *device) + : Block(device) +{ +} + +UDisksStorageVolume::~UDisksStorageVolume() +{ +} + +QString UDisksStorageVolume::encryptedContainerUdi() const +{ + if ( m_device->prop( "DeviceIsLuksCleartext" ).toBool() ) + return m_device->prop( "LuksCleartextSlave" ).value().path(); + + return QString(); +} + +qulonglong UDisksStorageVolume::size() const +{ + return m_device->prop("PartitionSize").toULongLong(); +} + +QString UDisksStorageVolume::uuid() const +{ + return m_device->prop("IdUuid").toString(); +} + +QString UDisksStorageVolume::label() const +{ + QString label = m_device->prop("IdLabel").toString(); + if (label.isEmpty()) + label = m_device->prop("PartitionLabel").toString(); + return label; +} + +QString UDisksStorageVolume::fsType() const +{ + return m_device->prop("IdType").toString(); +} + +Solid::StorageVolume::UsageType UDisksStorageVolume::usage() const +{ + QString usage = m_device->prop("IdUsage").toString(); + + if (usage == "filesystem") + { + return Solid::StorageVolume::FileSystem; + } + else if (usage == "partitiontable") + { + return Solid::StorageVolume::PartitionTable; + } + else if (usage == "raid") + { + return Solid::StorageVolume::Raid; + } + else if (usage == "crypto") + { + return Solid::StorageVolume::Encrypted; + } + else if (usage == "unused") + { + return Solid::StorageVolume::Unused; + } + else + { + return Solid::StorageVolume::Other; + } +} + +bool UDisksStorageVolume::isIgnored() const +{ + return m_device->isDeviceBlacklisted(); +} diff --git a/solid-lite/backends/udisks/udisksstoragevolume.h b/solid-lite/backends/udisks/udisksstoragevolume.h new file mode 100644 index 000000000..f6a8feee7 --- /dev/null +++ b/solid-lite/backends/udisks/udisksstoragevolume.h @@ -0,0 +1,57 @@ +/* + Copyright 2010 Michael Zanetti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDISKSSTORAGEVOLUME_H +#define UDISKSSTORAGEVOLUME_H + +#include +#include "udisksblock.h" + + +namespace Solid +{ +namespace Backends +{ +namespace UDisks +{ + +class UDisksStorageVolume: public Block, virtual public Solid::Ifaces::StorageVolume +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::StorageVolume) + +public: + UDisksStorageVolume(UDisksDevice *device); + virtual ~UDisksStorageVolume(); + + virtual QString encryptedContainerUdi() const; + virtual qulonglong size() const; + virtual QString uuid() const; + virtual QString label() const; + virtual QString fsType() const; + virtual Solid::StorageVolume::UsageType usage() const; + virtual bool isIgnored() const; +}; + +} +} +} + +#endif // UDISKSSTORAGEVOLUME_H diff --git a/solid-lite/backends/wmi/wmiblock.cpp b/solid-lite/backends/wmi/wmiblock.cpp new file mode 100644 index 000000000..abb09f423 --- /dev/null +++ b/solid-lite/backends/wmi/wmiblock.cpp @@ -0,0 +1,65 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmiblock.h" + +#include "wmidevice.h" + +using namespace Solid::Backends::Wmi; + +Block::Block(WmiDevice *device) + : DeviceInterface(device) +{ + +} + +Block::~Block() +{ + +} + +int Block::deviceMajor() const +{ + return 0; +} + +int Block::deviceMinor() const +{ + return 0; +} + +QString Block::device() const +{ + QString drive; + switch(m_device->type()){ + case Solid::DeviceInterface::StorageVolume: + { + drive = WmiDevice::win32LogicalDiskByDiskPartitionID(m_device->property("DeviceID").toString()).getProperty("DeviceID").toString(); + } + break; + case Solid::DeviceInterface::OpticalDrive: + case Solid::DeviceInterface::OpticalDisc: + drive = m_device->property("Drive").toString(); + break; + } + return drive; +} + +//#include "backends/wmi/wmiblock.moc" diff --git a/solid-lite/backends/wmi/wmiblock.h b/solid-lite/backends/wmi/wmiblock.h new file mode 100644 index 000000000..990c7f3e2 --- /dev/null +++ b/solid-lite/backends/wmi/wmiblock.h @@ -0,0 +1,50 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_BLOCK_H +#define SOLID_BACKENDS_WMI_BLOCK_H + +#include +#include "wmideviceinterface.h" + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class Block : public DeviceInterface, virtual public Solid::Ifaces::Block +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::Block) + +public: + Block(WmiDevice *device); + virtual ~Block(); + + virtual int deviceMajor() const; + virtual int deviceMinor() const; + virtual QString device() const; +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_BLOCK_H diff --git a/solid-lite/backends/wmi/wmicdrom.cpp b/solid-lite/backends/wmi/wmicdrom.cpp new file mode 100644 index 000000000..6e0cc8566 --- /dev/null +++ b/solid-lite/backends/wmi/wmicdrom.cpp @@ -0,0 +1,157 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmicdrom.h" + +#include + + +using namespace Solid::Backends::Wmi; + +Cdrom::Cdrom(WmiDevice *device) + : Storage(device), m_ejectInProgress(false) +{ + connect(device, SIGNAL(conditionRaised(QString,QString)), + this, SLOT(slotCondition(QString,QString))); +} + +Cdrom::~Cdrom() +{ + +} + + +Solid::OpticalDrive::MediumTypes Cdrom::supportedMedia() const +{ + Solid::OpticalDrive::MediumTypes supported; + + QString type = m_device->property("MediaType").toString(); + if (type == "CdRomOnly" || type == "CD-ROM") + { + supported |= Solid::OpticalDrive::Cdr; + } + else if (type == "CdRomWrite") + { + supported |= Solid::OpticalDrive::Cdr|Solid::OpticalDrive::Cdrw; + } + else if (type == "DVDRomOnly") + { + supported |= Solid::OpticalDrive::Dvd; + } + else if (type == "DVDRomWrite" || type == "DVD Writer") + { + supported |= Solid::OpticalDrive::Dvd|Solid::OpticalDrive::Dvdr|Solid::OpticalDrive::Dvdrw; + } + + return supported; +} + +int Cdrom::readSpeed() const +{ + return m_device->property("TransferRate").toInt(); +} + +int Cdrom::writeSpeed() const +{ + return m_device->property("TransferRate").toInt(); +} + +QList Cdrom::writeSpeeds() const +{ + QList speeds; + return speeds; +} + +void Cdrom::slotCondition(const QString &name, const QString &/*reason */) +{ + if (name == "EjectPressed") + { + emit ejectPressed(m_device->udi()); + } +} + +bool Cdrom::eject() +{ + if (m_ejectInProgress) { + return false; + } + m_ejectInProgress = true; + + return callWmiDriveEject(); +} + +bool Cdrom::callWmiDriveEject() +{ +// QString udi = m_device->udi(); +// QString interface = "org.freedesktop.Wmi.Device.Storage"; + + // HACK: Eject doesn't work on cdrom drives when there's a mounted disc, + // let's try to workaround this by calling a child volume... + // if (m_device->property("storage.removable.media_available").toBool()) { + // QDBusInterface manager("org.freedesktop.Wmi", + // "/org/freedesktop/Wmi/Manager", + // "org.freedesktop.Wmi.Manager", + // QDBusConnection::systemBus()); + + // QDBusReply reply = manager.call("FindDeviceStringMatch", "info.parent", udi); + + // if (reply.isValid()) + // { + // QStringList udis = reply; + // if (!udis.isEmpty()) { + // udi = udis[0]; + // interface = "org.freedesktop.Wmi.Device.Volume"; + // } + // } + // } + + // QDBusConnection c = QDBusConnection::systemBus(); + // QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Wmi", udi, + // interface, "Eject"); + + // msg << QStringList(); + + + // return c.callWithCallback(msg, this, + // SLOT(slotDBusReply(QDBusMessage)), + // SLOT(slotDBusError(QDBusError))); + return false; +} + +void Solid::Backends::Wmi::Cdrom::slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + Q_UNUSED(exitStatus); + if (m_ejectInProgress) { + m_ejectInProgress = false; + + if (exitCode==0) { + emit ejectDone(Solid::NoError, QVariant(), m_device->udi()); + } else { + emit ejectDone(Solid::UnauthorizedOperation, + m_process->readAllStandardError(), + m_device->udi()); + } + } + + delete m_process; +} + +//#include "backends/wmi/wmicdrom.moc" diff --git a/solid-lite/backends/wmi/wmicdrom.h b/solid-lite/backends/wmi/wmicdrom.h new file mode 100644 index 000000000..6c7fda6a3 --- /dev/null +++ b/solid-lite/backends/wmi/wmicdrom.h @@ -0,0 +1,69 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_CDROM_H +#define SOLID_BACKENDS_WMI_CDROM_H + +#include +#include "wmistorage.h" + +#include + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class Cdrom : public Storage, virtual public Solid::Ifaces::OpticalDrive +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::OpticalDrive) + +public: + Cdrom(WmiDevice *device); + virtual ~Cdrom(); + + virtual Solid::OpticalDrive::MediumTypes supportedMedia() const; + virtual int readSpeed() const; + virtual int writeSpeed() const; + virtual QList writeSpeeds() const; + virtual bool eject(); + +Q_SIGNALS: + void ejectPressed(const QString &udi); + void ejectDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + +private Q_SLOTS: + void slotCondition(const QString &name, const QString &reason); + void slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + +private: + bool callWmiDriveEject(); + + bool m_ejectInProgress; + QProcess *m_process; +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_CDROM_H diff --git a/solid-lite/backends/wmi/wmidevice.cpp b/solid-lite/backends/wmi/wmidevice.cpp new file mode 100644 index 000000000..08f62669b --- /dev/null +++ b/solid-lite/backends/wmi/wmidevice.cpp @@ -0,0 +1,705 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2005-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmidevice.h" + +#include + +#include "wmiquery.h" +#include "wmimanager.h" +#include "wmideviceinterface.h" +#include "wmigenericinterface.h" +//#include "wmiprocessor.h" +#include "wmiblock.h" +#include "wmistorageaccess.h" +#include "wmistorage.h" +#include "wmicdrom.h" +#include "wmivolume.h" +#include "wmiopticaldisc.h" +//#include "wmicamera.h" +#include "wmiportablemediaplayer.h" +//#include "wminetworkinterface.h" +//#include "wmiacadapter.h" +//#include "wmibattery.h" +//#include "wmibutton.h" +//#include "wmiaudiointerface.h" +//#include "wmidvbinterface.h" +//#include "wmivideo.h" + +#include + +using namespace Solid::Backends::Wmi; + +class Solid::Backends::Wmi::WmiDevicePrivate +{ +public: + WmiDevicePrivate(const QString &_udi) + : parent(0) + , m_udi(_udi) + , m_wmiTable() + , m_wmiProperty() + , m_wmiValue() + { + } + + ~WmiDevicePrivate() + { + } + + void discoverType() + { + if (!convertUDItoWMI(m_udi,m_wmiTable,m_wmiProperty,m_wmiValue,m_type)) + return; + interfaceList< 0) + return true; + qWarning()<<"Device UDI:"< getInterfaces(const Solid::DeviceInterface::Type &type) + { + QList interfaceList; + interfaceList< 0 ? list[0] : QString(); + return value; + } + + static QString getWMITable(const Solid::DeviceInterface::Type &type) + { + QString wmiTable; + switch (type) + { + case Solid::DeviceInterface::GenericInterface: + break; + //case Solid::DeviceInterface::Processor: + // wmiTable = "Win32_Processor"; + // break; + case Solid::DeviceInterface::Block: + break; + case Solid::DeviceInterface::StorageAccess: + wmiTable = "Win32_DiskPartition"; + break; + case Solid::DeviceInterface::StorageDrive: + wmiTable = "Win32_DiskDrive"; + break; + case Solid::DeviceInterface::OpticalDrive: + wmiTable = "Win32_CDROMDrive"; + break; + case Solid::DeviceInterface::StorageVolume: + wmiTable = "Win32_DiskPartition"; + break; + case Solid::DeviceInterface::OpticalDisc: + wmiTable = "Win32_CDROMDrive"; + break; + //case Solid::DeviceInterface::Camera: + // break; + case Solid::DeviceInterface::PortableMediaPlayer: + break; + /*case Solid::DeviceInterface::NetworkInterface: + break; + case Solid::DeviceInterface::AcAdapter: + case Solid::DeviceInterface::Battery: + wmiTable = "Win32_Battery"; + break; + case Solid::DeviceInterface::Button: + break; + case Solid::DeviceInterface::AudioInterface: + break; + case Solid::DeviceInterface::DvbInterface: + break; + case Solid::DeviceInterface::Video: + break; + */ + case Solid::DeviceInterface::Unknown: + case Solid::DeviceInterface::Last: + default: + wmiTable = "unknown"; + break; + } + return wmiTable; + } + + static QString getIgnorePattern(const Solid::DeviceInterface::Type &type) + { + QString propertyName; + switch(type){ + case Solid::DeviceInterface::OpticalDisc: + propertyName = " WHERE MediaLoaded=TRUE"; + break; + } + return propertyName; + } + + static QString getPropertyNameForUDI(const Solid::DeviceInterface::Type &type) + { + QString propertyName; + switch(type){ + case Solid::DeviceInterface::OpticalDrive: + case Solid::DeviceInterface::OpticalDisc: + propertyName = "Drive"; + break; + case Solid::DeviceInterface::StorageDrive: + propertyName = "Index"; + break; + default: + propertyName = "DeviceID"; + } + + return propertyName; + } + + static QStringList generateUDIList(const Solid::DeviceInterface::Type &type) + { + QStringList result; + + WmiQuery::ItemList list = WmiQuery::instance().sendQuery( "SELECT * FROM " + getWMITable(type) + getIgnorePattern(type)); + foreach(const WmiQuery::Item& item, list) { + QString propertyName = getPropertyNameForUDI(type); + QString property = item.getProperty(propertyName).toString(); + result << generateUDI(getUDIKey(type),property.toLower()); + } + return result; + } + + WmiDevice *parent; + static int m_instanceCount; + QString m_parent_uid; + QString m_udi; + QString m_wmiTable; + QString m_wmiProperty; + QString m_wmiValue; + Solid::DeviceInterface::Type m_type; + WmiQuery::Item m_item; + QList interfaceList; + +}; + +Q_DECLARE_METATYPE(ChangeDescription) +Q_DECLARE_METATYPE(QList) +WmiDevice::WmiDevice(const QString &udi) + : Device(), d(new WmiDevicePrivate(udi)) +{ + d->discoverType(); + foreach (Solid::DeviceInterface::Type type, d->interfaceList) + { + createDeviceInterface(type); + } +} + +WmiDevice::~WmiDevice() +{ + //delete d->parent; + delete d; +} + +QStringList WmiDevice::generateUDIList(const Solid::DeviceInterface::Type &type) +{ + return WmiDevicePrivate::generateUDIList(type); +} + + +bool WmiDevice::exists(const QString &udi) +{ + return WmiDevicePrivate::exists(udi); +} + +bool WmiDevice::isValid() const +{ + // does not work + //return sendQuery( "SELECT * FROM Win32_SystemDevices WHERE PartComponent='\\\\\\\\BEAST\root\cimv2:Win32_Processor.DeviceID=\"CPU0\"'" ).count() == 1; + return true; +} + +QString WmiDevice::udi() const +{ + return d->udi(); +} + +QString WmiDevice::parentUdi() const +{ + if(!d->m_parent_uid.isEmpty()) + return d->m_parent_uid; + QString result; + const QString value = udi().split("/").last(); + + switch(d->m_type){ + case Solid::DeviceInterface::StorageVolume: + case Solid::DeviceInterface::StorageAccess: + result = "/org/kde/solid/wmi/storage/"+property("DiskIndex").toString(); + break; + case Solid::DeviceInterface::OpticalDisc: + result = "/org/kde/solid/wmi/storage.cdrom/"+property("Drive").toString().toLower(); + break; + } + + if(result.isEmpty() && !value.isEmpty()){ + result = udi(); + result = result.remove("/"+value); + } + d->m_parent_uid = result; + return d->m_parent_uid; +} + +QString WmiDevice::vendor() const +{ + QString propertyName; + switch(type()){ + //case Solid::DeviceInterface::Processor: + // propertyName = "Manufacturer"; + // break; + case Solid::DeviceInterface::OpticalDrive: + case Solid::DeviceInterface::OpticalDisc: + propertyName = "Caption"; + break; + //case Solid::DeviceInterface::Battery: + // propertyName = "DeviceID"; + // break; + case Solid::DeviceInterface::StorageAccess: + case Solid::DeviceInterface::StorageVolume: + { + WmiDevice parent(parentUdi()); + return parent.vendor(); + } + break; + case Solid::DeviceInterface::StorageDrive: + propertyName = "Model"; + break; + default: + propertyName = "DeviceID";//TODO: + } + return property(propertyName).toString(); +} + +QString WmiDevice::product() const +{ + QString propertyName; + switch(type()){ + //case Solid::DeviceInterface::Processor: + // propertyName = "Name"; + // break; + case Solid::DeviceInterface::StorageAccess: + case Solid::DeviceInterface::StorageVolume: + { + WmiQuery::Item item = win32LogicalDiskByDiskPartitionID(property("DeviceID").toString()); + return item.getProperty("VolumeName").toString(); + } + break; + //case Solid::DeviceInterface::AcAdapter: + // return description(); + default: + propertyName = "Caption"; + } + return property(propertyName).toString(); +} + +QString WmiDevice::icon() const +{ + QString propertyName; + switch(type()){ + //case Solid::DeviceInterface::Processor: + // propertyName = "cpu"; + // break; + case Solid::DeviceInterface::OpticalDisc: + { + WmiDevice dev(udi()); + OpticalDisc disk(&dev); + if(disk.availableContent() | Solid::OpticalDisc::Audio)//no other are recognized yet + propertyName = "media-optical-audio"; + else + propertyName = "drive-optical"; + + break; + } + //case Solid::DeviceInterface::Battery: + // propertyName = "battery"; + // break; + case Solid::DeviceInterface::StorageAccess: + case Solid::DeviceInterface::StorageVolume: + { + WmiDevice parent(parentUdi()); + Storage storage(&parent); + if(storage.bus() == Solid::StorageDrive::Usb) + propertyName = "drive-removable-media-usb-pendrive"; + else + propertyName = "drive-harddisk"; + } + break; + } + return propertyName; +} + +QStringList WmiDevice::emblems() const +{ + return QStringList(); // TODO +} + +QString WmiDevice::description() const +{ + switch(type()){ + case Solid::DeviceInterface::OpticalDisc: + return property("VolumeName").toString(); + /*case Solid::DeviceInterface::AcAdapter: + return QObject::tr("A/C Adapter"); + case Solid::DeviceInterface::Battery: + { + WmiDevice dev(udi()); + Battery bat(&dev); + return QObject::tr("%1 Battery", "%1 is battery technology").arg(bat.batteryTechnology()); + } + */ + default: + return product(); + } +} + + +QVariant WmiDevice::property(const QString &key) const +{ + WmiQuery::Item item = d->sendQuery(); + + QVariant result = item.getProperty(key); +// qDebug()<<"property"<m_type; +} + +/** + * @brief WmiDevice::win32DiskPartitionByDeviceIndex + * @param deviceID something like "\\.\PHYSICALDRIVE0" + * @return + */ +WmiQuery::Item WmiDevice::win32DiskPartitionByDeviceIndex(const QString &deviceID){ + WmiQuery::Item result; + QString id = deviceID; + QString query("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='"+ id +"'} WHERE AssocClass = Win32_DiskDriveToDiskPartition"); + WmiQuery::ItemList items = WmiQuery::instance().sendQuery(query); + if(items.length()>0){ + result = items[0]; + } + return result; +} + +/** + * @brief WmiDevice::win32DiskDriveByDiskPartitionID + * @param deviceID something like "disk #1, partition #0" + * @return + */ + +WmiQuery::Item WmiDevice::win32DiskDriveByDiskPartitionID(const QString &deviceID){ + WmiQuery::Item result; + QString id = deviceID; + QString query("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='"+ id +"'} WHERE AssocClass = Win32_DiskDriveToDiskPartition"); + WmiQuery::ItemList items = WmiQuery::instance().sendQuery(query); + if(items.length()>0){ + result = items[0]; + } + return result; +} + +/** + * @brief WmiDevice::win32LogicalDiskByDiskPartitionID + * @param deviceID something like "disk #1, partition #0" + * @return + */ + +WmiQuery::Item WmiDevice::win32LogicalDiskByDiskPartitionID(const QString &deviceID){ + WmiQuery::Item result; + QString id = deviceID; + QString query("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + id + "'} WHERE AssocClass = Win32_LogicalDiskToPartition"); + WmiQuery::ItemList items = WmiQuery::instance().sendQuery(query); + if(items.length()>0){ + result = items[0]; + } + return result; +} + +/** + * @brief WmiDevice::win32DiskPartitionByDriveLetter + * @param driveLetter something lik "D:" + * @return + */ + +WmiQuery::Item WmiDevice::win32DiskPartitionByDriveLetter(const QString &driveLetter){ + WmiQuery::Item result; + QString id = driveLetter; + QString query("ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='" + id + "'} WHERE AssocClass = Win32_LogicalDiskToPartition"); + WmiQuery::ItemList items = WmiQuery::instance().sendQuery(query); + if(items.length()>0){ + result = items[0]; + } + return result; +} + +/** + * @brief WmiDevice::win32LogicalDiskByDriveLetter + * @param driveLetter something lik "D:" + * @return + */ + +WmiQuery::Item WmiDevice::win32LogicalDiskByDriveLetter(const QString &driveLetter){ + WmiQuery::Item result; + QString id = driveLetter; + QString query("SELECT * FROM Win32_LogicalDisk WHERE DeviceID='"+id+"'"); + WmiQuery::ItemList items = WmiQuery::instance().sendQuery(query); + if(items.length()>0){ + result = items[0]; + } + return result; +} + +QMap WmiDevice::allProperties() const +{ + WmiQuery::Item item = d->sendQuery(); + + return item.getAllProperties(); +} + +bool WmiDevice::propertyExists(const QString &key) const +{ + WmiQuery::Item item = d->sendQuery(); + const bool isEmpty = item.getProperty( key ).isValid(); + return isEmpty; +} + +bool WmiDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const +{ + // Special cases not matching with WMI capabilities + if (type==Solid::DeviceInterface::GenericInterface) { + return true; + } + + return d->interfaceList.contains(type); +} + +QObject *WmiDevice::createDeviceInterface(const Solid::DeviceInterface::Type &type) +{ + if (!queryDeviceInterface(type)) { + return 0; + } + + DeviceInterface *iface = 0; + + switch (type) + { + case Solid::DeviceInterface::GenericInterface: + iface = new GenericInterface(this); + break; + //case Solid::DeviceInterface::Processor: + // iface = new Processor(this); + // break; + case Solid::DeviceInterface::Block: + iface = new Block(this); + break; + case Solid::DeviceInterface::StorageAccess: + iface = new StorageAccess(this); + break; + case Solid::DeviceInterface::StorageDrive: + iface = new Storage(this); + break; + case Solid::DeviceInterface::OpticalDrive: + iface = new Cdrom(this); + break; + case Solid::DeviceInterface::StorageVolume: + iface = new Volume(this); + break; + case Solid::DeviceInterface::OpticalDisc: + iface = new OpticalDisc(this); + break; + //case Solid::DeviceInterface::Camera: + // iface = new Camera(this); + // break; + case Solid::DeviceInterface::PortableMediaPlayer: + iface = new PortableMediaPlayer(this); + break; + /*case Solid::DeviceInterface::NetworkInterface: + iface = new NetworkInterface(this); + break; + case Solid::DeviceInterface::AcAdapter: + iface = new AcAdapter(this); + break; + case Solid::DeviceInterface::Battery: + iface = new Battery(this); + break; + case Solid::DeviceInterface::Button: + iface = new Button(this); + break; + case Solid::DeviceInterface::AudioInterface: + iface = new AudioInterface(this); + break; + case Solid::DeviceInterface::DvbInterface: + iface = new DvbInterface(this); + break; + case Solid::DeviceInterface::Video: + iface = new Video(this); + break; + */ + case Solid::DeviceInterface::Unknown: + case Solid::DeviceInterface::Last: + break; + } + + return iface; +} + +void WmiDevice::slotPropertyModified(int /*count */, const QList &changes) +{ + QMap result; + + foreach (const ChangeDescription &change, changes) + { + QString key = change.key; + bool added = change.added; + bool removed = change.removed; + + Solid::GenericInterface::PropertyChange type = Solid::GenericInterface::PropertyModified; + + if (added) + { + type = Solid::GenericInterface::PropertyAdded; + } + else if (removed) + { + type = Solid::GenericInterface::PropertyRemoved; + } + + result[key] = type; + } + + emit propertyChanged(result); +} + +void WmiDevice::slotCondition(const QString &condition, const QString &reason) +{ + emit conditionRaised(condition, reason); +} + +//#include "backends/wmi/wmidevice.moc" diff --git a/solid-lite/backends/wmi/wmidevice.h b/solid-lite/backends/wmi/wmidevice.h new file mode 100644 index 000000000..2ed88ee9a --- /dev/null +++ b/solid-lite/backends/wmi/wmidevice.h @@ -0,0 +1,101 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2005,2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_WMIDEVICE_H +#define SOLID_BACKENDS_WMI_WMIDEVICE_H + +#include +#include "wmiquery.h" + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class WmiManager; +class WmiDevicePrivate; + +struct ChangeDescription +{ + QString key; + bool added; + bool removed; +}; + +class WmiDevice : public Solid::Ifaces::Device +{ + Q_OBJECT + +public: + WmiDevice(const QString &udi); + virtual ~WmiDevice(); + + virtual QString udi() const; + virtual QString parentUdi() const; + + virtual QString vendor() const; + virtual QString product() const; + virtual QString icon() const; + virtual QStringList emblems() const; + virtual QString description() const; + + virtual bool isValid() const; + + virtual QVariant property(const QString &key) const; + + virtual QMap allProperties() const; + + virtual bool propertyExists(const QString &key) const; + + virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type &type) const; + virtual QObject *createDeviceInterface(const Solid::DeviceInterface::Type &type); + + static QStringList generateUDIList(const Solid::DeviceInterface::Type &type); + static bool exists(const QString &udi); + const Solid::DeviceInterface::Type type() const; + + + //TODO:rename the folowing methodes... + static WmiQuery::Item win32LogicalDiskByDiskPartitionID(const QString &deviceID); + static WmiQuery::Item win32DiskDriveByDiskPartitionID(const QString &deviceID); + static WmiQuery::Item win32DiskPartitionByDeviceIndex(const QString &deviceID); + static WmiQuery::Item win32DiskPartitionByDriveLetter(const QString &driveLetter); + static WmiQuery::Item win32LogicalDiskByDriveLetter(const QString &driveLetter); + + +Q_SIGNALS: + void propertyChanged(const QMap &changes); + void conditionRaised(const QString &condition, const QString &reason); + +private Q_SLOTS: + void slotPropertyModified(int count, const QList &changes); + void slotCondition(const QString &condition, const QString &reason); + +private: + WmiDevicePrivate *d; + friend class WmiDevicePrivate; +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_WMIDEVICE_H diff --git a/solid-lite/backends/wmi/wmideviceinterface.cpp b/solid-lite/backends/wmi/wmideviceinterface.cpp new file mode 100644 index 000000000..58659c560 --- /dev/null +++ b/solid-lite/backends/wmi/wmideviceinterface.cpp @@ -0,0 +1,34 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmideviceinterface.h" + +using namespace Solid::Backends::Wmi; + +DeviceInterface::DeviceInterface(WmiDevice *device) + : QObject(device), m_device(device) +{ +} + +DeviceInterface::~DeviceInterface() +{ +} + +//#include "backends/wmi/wmideviceinterface.moc" diff --git a/solid-lite/backends/wmi/wmideviceinterface.h b/solid-lite/backends/wmi/wmideviceinterface.h new file mode 100644 index 000000000..faac80d56 --- /dev/null +++ b/solid-lite/backends/wmi/wmideviceinterface.h @@ -0,0 +1,163 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_DEVICEINTERFACE_H +#define SOLID_BACKENDS_WMI_DEVICEINTERFACE_H + +#include +#include "wmidevice.h" + +#include +#include + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class DeviceInterface : public QObject, virtual public Solid::Ifaces::DeviceInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::DeviceInterface) +public: + DeviceInterface(WmiDevice *device); + virtual ~DeviceInterface(); + +protected: + WmiDevice *m_device; + +public: + inline static QStringList toStringList(Solid::DeviceInterface::Type type) + { + QStringList list; + + switch(type) + { + case Solid::DeviceInterface::GenericInterface: + // Doesn't exist with WMI + break; + case Solid::DeviceInterface::Processor: + list << "processor"; + break; + case Solid::DeviceInterface::Block: + list << "block"; + break; + case Solid::DeviceInterface::StorageAccess: + // Doesn't exist with WMI, but let's assume volume always cover this type + list << "volume"; + break; + case Solid::DeviceInterface::StorageDrive: + list << "storage"; + break; + case Solid::DeviceInterface::OpticalDrive: + list << "storage.cdrom"; + break; + case Solid::DeviceInterface::StorageVolume: + list << "volume"; + break; + case Solid::DeviceInterface::OpticalDisc: + list << "volume.disc"; + break; + case Solid::DeviceInterface::Camera: + list << "camera"; + break; + case Solid::DeviceInterface::PortableMediaPlayer: + list << "portable_audio_player"; + break; + case Solid::DeviceInterface::NetworkInterface: + list << "net"; + break; + case Solid::DeviceInterface::AcAdapter: + list << "ac_adapter"; + break; + case Solid::DeviceInterface::Battery: + list << "battery"; + break; + case Solid::DeviceInterface::Button: + list << "button"; + break; + case Solid::DeviceInterface::AudioInterface: + list << "alsa" << "oss"; + break; + case Solid::DeviceInterface::DvbInterface: + list << "dvb"; + break; + case Solid::DeviceInterface::Video: + list << "video4linux"; + break; + case Solid::DeviceInterface::InternetGateway: + list << "internet_gateway"; + break; + case Solid::DeviceInterface::NetworkShare: + list << "networkshare"; + break; + case Solid::DeviceInterface::Unknown: + break; + case Solid::DeviceInterface::Last: + break; + } + + return list; + } + + inline static Solid::DeviceInterface::Type fromString(const QString &capability) + { + if (capability == "processor") + return Solid::DeviceInterface::Processor; + else if (capability == "block") + return Solid::DeviceInterface::Block; + else if (capability == "storage") + return Solid::DeviceInterface::StorageDrive; + else if (capability == "storage.cdrom") + return Solid::DeviceInterface::OpticalDrive; + else if (capability == "volume") + return Solid::DeviceInterface::StorageVolume; + else if (capability == "volume.disc") + return Solid::DeviceInterface::OpticalDisc; + else if (capability == "camera") + return Solid::DeviceInterface::Camera; + else if (capability == "portable_audio_player") + return Solid::DeviceInterface::PortableMediaPlayer; + else if (capability == "net") + return Solid::DeviceInterface::NetworkInterface; + else if (capability == "ac_adapter") + return Solid::DeviceInterface::AcAdapter; + else if (capability == "battery") + return Solid::DeviceInterface::Battery; + else if (capability == "button") + return Solid::DeviceInterface::Button; + else if (capability == "alsa" || capability == "oss") + return Solid::DeviceInterface::AudioInterface; + else if (capability == "dvb") + return Solid::DeviceInterface::DvbInterface; + else if (capability == "video4linux") + return Solid::DeviceInterface::Video; + else if (capability == "networkshare") + return Solid::DeviceInterface::NetworkShare; + else + return Solid::DeviceInterface::Unknown; + } +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_DEVICEINTERFACE_H diff --git a/solid-lite/backends/wmi/wmigenericinterface.cpp b/solid-lite/backends/wmi/wmigenericinterface.cpp new file mode 100644 index 000000000..626f22206 --- /dev/null +++ b/solid-lite/backends/wmi/wmigenericinterface.cpp @@ -0,0 +1,56 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmigenericinterface.h" + +#include "wmidevice.h" + +using namespace Solid::Backends::Wmi; + +GenericInterface::GenericInterface(WmiDevice *device) + : DeviceInterface(device) +{ + connect(device, SIGNAL(propertyChanged(QMap)), + this, SIGNAL(propertyChanged(QMap))); + connect(device, SIGNAL(conditionRaised(QString,QString)), + this, SIGNAL(conditionRaised(QString,QString))); +} + +GenericInterface::~GenericInterface() +{ + +} + +QVariant GenericInterface::property(const QString &key) const +{ + return m_device->property(key); +} + +QMap GenericInterface::allProperties() const +{ + return m_device->allProperties(); +} + +bool GenericInterface::propertyExists(const QString &key) const +{ + return m_device->propertyExists(key); +} + +//#include "backends/wmi/wmigenericinterface.moc" diff --git a/solid-lite/backends/wmi/wmigenericinterface.h b/solid-lite/backends/wmi/wmigenericinterface.h new file mode 100644 index 000000000..7a0b88062 --- /dev/null +++ b/solid-lite/backends/wmi/wmigenericinterface.h @@ -0,0 +1,57 @@ +/* + Copyright 2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_GENERICINTERFACE_H +#define SOLID_BACKENDS_WMI_GENERICINTERFACE_H + +#include +#include +#include "wmideviceinterface.h" + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class WmiDevice; + +class GenericInterface : public DeviceInterface, virtual public Solid::Ifaces::GenericInterface +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::GenericInterface) + +public: + GenericInterface(WmiDevice *device); + virtual ~GenericInterface(); + + virtual QVariant property(const QString &key) const; + virtual QMap allProperties() const; + virtual bool propertyExists(const QString &key) const; + +Q_SIGNALS: + void propertyChanged(const QMap &changes); + void conditionRaised(const QString &condition, const QString &reason); +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_GENERICINTERFACE_H diff --git a/solid-lite/backends/wmi/wmimanager.cpp b/solid-lite/backends/wmi/wmimanager.cpp new file mode 100644 index 000000000..3b161042c --- /dev/null +++ b/solid-lite/backends/wmi/wmimanager.cpp @@ -0,0 +1,271 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2005,2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmimanager.h" + +#include + +#include "wmidevice.h" +#include "wmideviceinterface.h" +#include "wmiquery.h" + + +using namespace Solid::Backends::Wmi; + +class Solid::Backends::Wmi::WmiManagerPrivate +{ +public: + WmiManagerPrivate(WmiManager *parent) + :m_parent(parent) + { + supportedInterfaces << Solid::DeviceInterface::GenericInterface + << Solid::DeviceInterface::Processor + // << Solid::DeviceInterface::Block + << Solid::DeviceInterface::StorageAccess + << Solid::DeviceInterface::StorageDrive + << Solid::DeviceInterface::OpticalDrive + << Solid::DeviceInterface::StorageVolume + << Solid::DeviceInterface::OpticalDisc + // << Solid::DeviceInterface::Camera + // << Solid::DeviceInterface::PortableMediaPlayer + // << Solid::DeviceInterface::NetworkInterface + << Solid::DeviceInterface::AcAdapter + << Solid::DeviceInterface::Battery + // << Solid::DeviceInterface::Button + // << Solid::DeviceInterface::AudioInterface + // << Solid::DeviceInterface::DvbInterface + // << Solid::DeviceInterface::Video + // << Solid::DeviceInterface::SerialInterface + // << Solid::DeviceInterface::SmartCardReader + ; + + update(); + } + + ~WmiManagerPrivate() + { + + } + + void update(){ + init(); + + } + + void init(){ + if(m_deviceCache.isEmpty()) + { + foreach(const Solid::DeviceInterface::Type &dev, supportedInterfaces){ + updateDeviceCache(dev); + } + } + } + + + + void updateDeviceCache(const Solid::DeviceInterface::Type & type){ + QSet devSet = m_parent->findDeviceByDeviceInterface(type).toSet(); + if(m_deviceCache.contains(type)){ + QSet added = devSet - m_deviceCache[type]; + foreach(const QString & s,added){ + m_parent->slotDeviceAdded(s); + } + QSet removed = m_deviceCache[type] - devSet; + foreach(const QString & s,removed){ + m_parent->slotDeviceRemoved(s); + } + } + m_deviceCache[type] = devSet; + } + + + WmiQuery::ItemList sendQuery( const QString &wql ) + { + return WmiQuery::instance().sendQuery( wql ); + } + + WmiManager *m_parent; + QSet supportedInterfaces; + QMap > m_deviceCache; +}; + + +WmiManager::WmiManager(QObject *parent) + : DeviceManager(parent) +{ + d = new WmiManagerPrivate(this); + + + QList types; + types< WmiManager::supportedInterfaces() const +{ + return d->supportedInterfaces; +} + +QStringList WmiManager::allDevices() +{ + QStringList list; + foreach(const Solid::DeviceInterface::Type &type,d->supportedInterfaces){ + list<m_deviceCache[type].toList(); + } + return list; +} + +bool WmiManager::deviceExists(const QString &udi) +{ + return WmiDevice::exists(udi); +} + + +QStringList WmiManager::devicesFromQuery(const QString &parentUdi, + Solid::DeviceInterface::Type type) +{ + QStringList result; + if (!parentUdi.isEmpty()) + { + foreach(const QString &udi,allDevices()){ + WmiDevice device(udi); + if(device.type() == type && device.parentUdi() == parentUdi ){ + result< &types): + m_parent(parent), + m_query(query), + m_types(types), + m_count(0) +{} + +WmiManager::WmiEventSink::~WmiEventSink() +{} + +ulong STDMETHODCALLTYPE WmiManager::WmiEventSink::AddRef() +{ + return InterlockedIncrement(&m_count); +} + +ulong STDMETHODCALLTYPE WmiManager::WmiEventSink::Release() +{ + long lRef = InterlockedDecrement(&m_count); + if(lRef == 0) + delete this; + return lRef; +} + +HRESULT STDMETHODCALLTYPE WmiManager::WmiEventSink::QueryInterface(REFIID riid, void** ppv) +{ + if (riid == IID_IUnknown || riid == IID_IWbemObjectSink) + { + *ppv = (IWbemObjectSink *) this; + AddRef(); + return WBEM_S_NO_ERROR; + } + else return E_NOINTERFACE; +} + +HRESULT STDMETHODCALLTYPE WmiManager::WmiEventSink::Indicate(long lObjectCount,IWbemClassObject **apObjArray) +{ + foreach(const Solid::DeviceInterface::Type &type,m_types){ + m_parent->d->updateDeviceCache(type); + } + return WBEM_S_NO_ERROR; +} + +HRESULT STDMETHODCALLTYPE WmiManager::WmiEventSink::SetStatus(long lFlags,HRESULT hResult,BSTR strParam,IWbemClassObject *pObjParam) +{ + return WBEM_S_NO_ERROR; +} + +const QString& WmiManager::WmiEventSink::query() const { + return m_query; +} + + +//#include "backends/wmi/wmimanager.moc" diff --git a/solid-lite/backends/wmi/wmimanager.h b/solid-lite/backends/wmi/wmimanager.h new file mode 100644 index 000000000..a1d0436a8 --- /dev/null +++ b/solid-lite/backends/wmi/wmimanager.h @@ -0,0 +1,102 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2005,2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_WMIMANAGER_H +#define SOLID_BACKENDS_WMI_WMIMANAGER_H + +#include +#include + +#include +#include + +#include + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class WmiManagerPrivate; + +class WmiManager : public Solid::Ifaces::DeviceManager +{ + Q_OBJECT + +public: + + class WmiEventSink : public IWbemObjectSink + { + public: + WmiEventSink(class WmiManager* parent,const QString &query,const QList &types); + ~WmiEventSink(); + + virtual ulong STDMETHODCALLTYPE AddRef(); + virtual ulong STDMETHODCALLTYPE Release(); + + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv); + + virtual HRESULT STDMETHODCALLTYPE Indicate(long lObjectCount,IWbemClassObject **apObjArray); + + virtual HRESULT STDMETHODCALLTYPE SetStatus(long lFlags,HRESULT hResult,BSTR strParam,IWbemClassObject *pObjParam); + + const QString& query() const; + + private: + WmiManager *m_parent; + QString m_query; + QList m_types; + long m_count; + + }; + + WmiManager(QObject *parent=0); + virtual ~WmiManager(); + + virtual QString udiPrefix() const ; + virtual QSet supportedInterfaces() const; + + virtual QStringList allDevices(); + virtual bool deviceExists(const QString &udi); + + virtual QStringList devicesFromQuery(const QString &parentUdi, + Solid::DeviceInterface::Type type); + + virtual QObject *createDevice(const QString &udi); + + +private Q_SLOTS: + void slotDeviceAdded(const QString &udi); + void slotDeviceRemoved(const QString &udi); + +private: + QStringList findDeviceStringMatch(const QString &key, const QString &value); + QStringList findDeviceByDeviceInterface(Solid::DeviceInterface::Type type); + + WmiManagerPrivate *d; + friend class WmiManagerPrivate; +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_WMIMANAGER_H diff --git a/solid-lite/backends/wmi/wmiopticaldisc.cpp b/solid-lite/backends/wmi/wmiopticaldisc.cpp new file mode 100644 index 000000000..05ba8084e --- /dev/null +++ b/solid-lite/backends/wmi/wmiopticaldisc.cpp @@ -0,0 +1,113 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmiopticaldisc.h" + + +#include + +using namespace Solid::Backends::Wmi; + +OpticalDisc::OpticalDisc(WmiDevice *device) + : Volume(device) +{ + m_logicalDisk = WmiDevice::win32LogicalDiskByDriveLetter(m_device->property("Drive").toString()); +} + +OpticalDisc::~OpticalDisc() +{ + +} + + +Solid::OpticalDisc::ContentTypes OpticalDisc::availableContent() const +{ + Solid::OpticalDisc::ContentTypes content; + + QDir dir(m_device->property("Drive").toString()); + QStringList files = dir.entryList(); + if(files.length()>0) + if(files[0].endsWith(".cda")) + content |= Solid::OpticalDisc::Audio; + + return content; +} + +Solid::OpticalDisc::DiscType OpticalDisc::discType() const +{ + QString type = m_logicalDisk.getProperty("FileSystem").toString(); + + if (type == "CDFS") + { + return Solid::OpticalDisc::CdRom; + } +// else if (type == "CdRomWrite") +// { +// return Solid::OpticalDisc::CdRecordable; +// } + else if (type == "UDF") + { + return Solid::OpticalDisc::DvdRom; + } +// else if (type == "DVDRomWrite") +// { +// return Solid::OpticalDisc::DvdRecordable; +// } + else + { + qDebug()<<"Solid::OpticalDisc::DiscType OpticalDisc::discType(): Unknown Type"<property("FileSystemFlagsEx").toUInt(); + if(val == 0) + return true; + return false; +} + +bool OpticalDisc::isRewritable() const +{ + //TODO: + return capacity()>0 && isWriteable(); +} + +qulonglong OpticalDisc::capacity() const +{ + return m_device->property("Size").toULongLong(); +} + +bool OpticalDisc::isWriteable() const +{ + ushort val = m_device->property("FileSystemFlagsEx").toUInt(); + if(val == 0) + return true; + return !val & 0x80001;//read only +} + +//#include "backends/wmi/wmiopticaldisc.moc" diff --git a/solid-lite/backends/wmi/wmiopticaldisc.h b/solid-lite/backends/wmi/wmiopticaldisc.h new file mode 100644 index 000000000..a2bbf3bbf --- /dev/null +++ b/solid-lite/backends/wmi/wmiopticaldisc.h @@ -0,0 +1,57 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_OPTICALDISC_H +#define SOLID_BACKENDS_WMI_OPTICALDISC_H + +#include +#include "wmivolume.h" + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class OpticalDisc : public Volume, virtual public Solid::Ifaces::OpticalDisc +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::OpticalDisc) + +public: + OpticalDisc(WmiDevice *device); + virtual ~OpticalDisc(); + + virtual Solid::OpticalDisc::ContentTypes availableContent() const; + virtual Solid::OpticalDisc::DiscType discType() const; + virtual bool isAppendable() const; + virtual bool isBlank() const; + virtual bool isRewritable() const; + virtual qulonglong capacity() const; +private: + bool isWriteable() const; + WmiQuery::Item m_logicalDisk; +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_OPTICALDISC_H diff --git a/solid-lite/backends/wmi/wmiportablemediaplayer.cpp b/solid-lite/backends/wmi/wmiportablemediaplayer.cpp new file mode 100644 index 000000000..57dd0ea87 --- /dev/null +++ b/solid-lite/backends/wmi/wmiportablemediaplayer.cpp @@ -0,0 +1,68 @@ +/* + Copyright 2006 Davide Bettio + Copyright 2007 Jeff Mitchell + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmiportablemediaplayer.h" + +using namespace Solid::Backends::Wmi; + +PortableMediaPlayer::PortableMediaPlayer(WmiDevice *device) + : DeviceInterface(device) +{ + +} + +PortableMediaPlayer::~PortableMediaPlayer() +{ + +} + +QStringList PortableMediaPlayer::supportedProtocols() const +{ + return m_device->property("portable_audio_player.access_method.protocols").toStringList(); +} + +QStringList PortableMediaPlayer::supportedDrivers(QString protocol) const +{ + QStringList drivers = m_device->property("portable_audio_player.access_method.drivers").toStringList(); + if(protocol.isNull()) + return drivers; + QStringList returnedDrivers; + QString temp; + for(int i = 0; i < drivers.size(); i++) + { + temp = drivers.at(i); + if(m_device->property("portable_audio_player." + temp + ".protocol") == protocol) + returnedDrivers << temp; + } + return returnedDrivers; +} + +QVariant Solid::Backends::Wmi::PortableMediaPlayer::driverHandle(const QString &driver) const +{ + if (driver=="mtp") { + return m_device->property("usb.serial"); + } + // TODO: Fill in the blank for other drivers + + return QVariant(); +} + +//#include "backends/wmi/wmiportablemediaplayer.moc" diff --git a/solid-lite/backends/wmi/wmiportablemediaplayer.h b/solid-lite/backends/wmi/wmiportablemediaplayer.h new file mode 100644 index 000000000..c5f1fa2c9 --- /dev/null +++ b/solid-lite/backends/wmi/wmiportablemediaplayer.h @@ -0,0 +1,55 @@ +/* + Copyright 2006 Davide Bettio + Copyright 2007 Jeff Mitchell + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_PORTABLEMEDIAPLAYER_H +#define SOLID_BACKENDS_WMI_PORTABLEMEDIAPLAYER_H + +#include +#include "wmideviceinterface.h" + +#include + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class WmiDevice; + +class PortableMediaPlayer : public DeviceInterface, virtual public Solid::Ifaces::PortableMediaPlayer +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::PortableMediaPlayer) + +public: + PortableMediaPlayer(WmiDevice *device); + virtual ~PortableMediaPlayer(); + + virtual QStringList supportedProtocols() const; + virtual QStringList supportedDrivers(QString protocol = QString()) const; + virtual QVariant driverHandle(const QString &driver) const; +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_PORTABLEMEDIAPLAYER_H diff --git a/solid-lite/backends/wmi/wmiquery.cpp b/solid-lite/backends/wmi/wmiquery.cpp new file mode 100644 index 000000000..a88a1647a --- /dev/null +++ b/solid-lite/backends/wmi/wmiquery.cpp @@ -0,0 +1,390 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2008 Jeff Mitchell + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +//#define _WIN32_DCOM +//#include + +#define INSIDE_WMIQUERY +#include "wmiquery.h" +#include "wmimanager.h" + +#ifdef _DEBUG +# pragma comment(lib, "comsuppwd.lib") +#else +# pragma comment(lib, "comsuppw.lib") +#endif +# pragma comment(lib, "wbemuuid.lib") + +#include +#include +#include + +# pragma comment(lib, "wbemuuid.lib") + +#include +#include +#include +#include +#include + +//needed for mingw +inline OLECHAR* SysAllocString(const QString &s){ + const OLECHAR *olename = reinterpret_cast(s.utf16()); + return ::SysAllocString(olename); +} + +using namespace Solid::Backends::Wmi; + + +QString bstrToQString(BSTR bstr) +{ + QString str((QChar*)bstr,::SysStringLen(bstr)); + return str; + +} + +QVariant WmiQuery::Item::msVariantToQVariant(VARIANT msVariant, CIMTYPE variantType) +{ + QVariant returnVariant(QVariant::Invalid); + if(msVariant.vt == VT_NULL){ + return QVariant(QVariant::String); + } + + switch(variantType) { + case CIM_STRING: + case CIM_CHAR16: + case CIM_UINT64://bug I get a wrong value from ullVal + { + QString str = bstrToQString(msVariant.bstrVal); + QVariant vs(str); + returnVariant = vs; + + } + break; + case CIM_BOOLEAN: + { + QVariant vb(msVariant.boolVal); + returnVariant = vb; + } + break; + case CIM_UINT8: + { + QVariant vb(msVariant.uintVal); + returnVariant = vb; + } + break; + case CIM_UINT16: + { + QVariant vb(msVariant.uintVal); + returnVariant = vb; + } + break; + case CIM_UINT32: + { + QVariant vb(msVariant.uintVal); + returnVariant = vb; + } + break; + // case CIM_UINT64: + // { + // QVariant vb(msVariant.ullVal); + //// wprintf(L"ulonglong %d %I64u\r\n",variantType, msVariant.ullVal); // 32-bit on x86, 64-bit on x64 + // returnVariant = vb; + // } + // break; + // default: + // qDebug()<<"Unsupported variant"<ConnectServer. + Please DO NOT USE the following or similar statement in + the global space or a class. + + static WmiQuery instance; +*/ + +QVariant WmiQuery::Item::getProperty(BSTR bstrProp) const +{ + QVariant result; + if(m_p == NULL) + return result; + VARIANT vtProp; + CIMTYPE variantType; + HRESULT hr = m_p->Get(bstrProp, 0, &vtProp, &variantType, 0); + if (SUCCEEDED(hr)) { + result = msVariantToQVariant(vtProp,variantType); + }else{ + QString className = getProperty(L"__CLASS").toString(); + QString qprop = bstrToQString(bstrProp); + qFatal("\r\n--------------------------------------------------------------\r\n" + "Error: Property: %s not found in %s\r\n" + "--------------------------------------------------------------\r\n",qPrintable(qprop),qPrintable(className)); + } + return result; +} +QVariant WmiQuery::Item::getProperty(const QString &property) const +{ + QVariant result; + BSTR bstrProp; + bstrProp = ::SysAllocString(property); + result = getProperty(bstrProp); + ::SysFreeString(bstrProp); + return result; +} + +QVariantMap WmiQuery::Item::getAllProperties() +{ + if(m_properies.isEmpty()){ + SAFEARRAY *psaNames; + HRESULT hr = m_p->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY,NULL,&psaNames); + if (SUCCEEDED(hr)) { + long lLower, lUpper; + SafeArrayGetLBound( psaNames, 1, &lLower ); + SafeArrayGetUBound( psaNames, 1, &lUpper ); + for(long i=lLower;iAddRef(); +} + +WmiQuery::Item::Item(const Item& other) : m_p(other.m_p) +{ + if(m_p != NULL) + m_p->AddRef(); +} + +WmiQuery::Item& WmiQuery::Item::operator=(const Item& other) +{ + if(m_p != NULL){ + m_p->Release(); + m_p = NULL; + } + if(other.m_p != NULL){ + m_p = other.m_p; + m_p->AddRef(); + } + return *this; +} + +WmiQuery::Item::~Item() +{ + if(m_p != NULL && + !(qApp->closingDown() || WmiQuery::instance().m_bNeedUninit))//this means we are in a QApplication, so qt already called CoUninitialize and all COM references are all ready freed + m_p->Release(); +} + +IWbemClassObject* WmiQuery::Item::data() const +{ + if(m_p != NULL) + m_p->AddRef(); + return m_p; +} + +bool WmiQuery::Item::isNull() const +{ + return m_p == NULL; +} + +WmiQuery::WmiQuery() + : m_failed(false) + , pLoc(0) + , pSvc(0) +{ + HRESULT hres; + + hres = CoInitializeEx(0,COINIT_MULTITHREADED); + if( FAILED(hres) && hres != S_FALSE && hres != RPC_E_CHANGED_MODE ) + { + qCritical() << "Failed to initialize COM library. Error code = 0x" << hex << quint32(hres) << endl; + m_failed = true; + } + m_bNeedUninit = ( hres != S_FALSE && hres != RPC_E_CHANGED_MODE ); + if( !m_failed ) + { + hres = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, + RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); + + // RPC_E_TOO_LATE --> security already initialized + if( FAILED(hres) && hres != RPC_E_TOO_LATE ) + { + qCritical() << "Failed to initialize security. " << "Error code = " << hres << endl; + if ( m_bNeedUninit ) + CoUninitialize(); + m_failed = true; + } + } + if( !m_failed ) + { + hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc ); + if (FAILED(hres)) + { + qCritical() << "Failed to create IWbemLocator object. " << "Error code = " << hres << endl; + if ( m_bNeedUninit ) + CoUninitialize(); + m_failed = true; + } + } + if( !m_failed ) + { + hres = pLoc->ConnectServer( L"ROOT\\CIMV2", NULL, NULL, 0, NULL, 0, 0, &pSvc ); + if( FAILED(hres) ) + { + qCritical() << "Could not connect. Error code = " << hres << endl; + pLoc->Release(); + if ( m_bNeedUninit ) + CoUninitialize(); + m_failed = true; + } + // else + // qDebug() << "Connected to ROOT\\CIMV2 WMI namespace" << endl; + } + + if( !m_failed ) + { + hres = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); + if( FAILED(hres) ) + { + qCritical() << "Could not set proxy blanket. Error code = " << hres << endl; + pSvc->Release(); + pLoc->Release(); + if ( m_bNeedUninit ) + CoUninitialize(); + m_failed = true; + } + } +} + +WmiQuery::~WmiQuery() +{ + if( m_failed ) + return; // already cleaned up properly + if( pSvc ) + pSvc->Release(); + if( pLoc ) + pLoc->Release(); + if( m_bNeedUninit ) + CoUninitialize(); +} + +void WmiQuery::addDeviceListeners(WmiManager::WmiEventSink *sink){ + if(m_failed) + return; + BSTR bstrQuery; + bstrQuery = ::SysAllocString(sink->query()); + HRESULT hr = pSvc->ExecNotificationQueryAsync(L"WQL",bstrQuery,0, NULL,sink); + ::SysFreeString(bstrQuery); + if(FAILED(hr)){ + qWarning()<<"WmiQuery::addDeviceListeners "<query()<<" failed!"; + } +} + +WmiQuery::ItemList WmiQuery::sendQuery( const QString &wql ) +{ +// qDebug()<<"WmiQuery::ItemList WmiQuery::sendQuery"<ExecQuery( L"WQL",bstrQuery , + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); + ::SysFreeString(bstrQuery); + + if( FAILED(hres) ) + { + qDebug() << "Query with string \"" << wql << "\" failed. Error code = " << hres << endl; + } + else + { + ULONG uReturn = 0; + + while( pEnumerator ) + { + IWbemClassObject *pclsObj; + hres = pEnumerator->Next( WBEM_INFINITE, 1, &pclsObj, &uReturn ); + + if( !uReturn ) + break; + + // pclsObj will be released on destruction of Item + retList.append( Item( pclsObj ) ); + pclsObj->Release(); + } + if( pEnumerator ) + pEnumerator->Release(); + else + qDebug() << "failed to release enumerator!"; + } +// if(retList.size()== 0) +// qDebug()<<"querying"< + Copyright 2008 Jeff Mitchell + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_WMIQUERY_H +#define SOLID_BACKENDS_WMI_WMIQUERY_H + +#include +#include +#include +#include +#include + +#include + + +#include +#include +#include +#include +#include + +#include "wmimanager.h" + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class WmiQuery +{ +public: + class Item { + public: + Item(); + Item(IWbemClassObject *p); + Item(const Item& other); + Item& operator=(const Item& other); + ~Item(); + + IWbemClassObject* data() const; + bool isNull() const; + QVariant getProperty(const QString &property) const; + QVariantMap getAllProperties(); + + private: + + static QVariant msVariantToQVariant(VARIANT msVariant, CIMTYPE variantType); + QVariant getProperty(BSTR property) const; + // QSharedPointer alone doesn't help because we need to call Release() + IWbemClassObject* m_p; + QVariantMap m_properies; + }; + + typedef QList ItemList; + + WmiQuery(); + ~WmiQuery(); + ItemList sendQuery( const QString &wql ); + void addDeviceListeners(WmiManager::WmiEventSink *sink); + bool isLegit() const; + static WmiQuery &instance(); + +private: + bool m_failed; + bool m_bNeedUninit; + IWbemLocator *pLoc; + IWbemServices *pSvc; +}; +} +} +} + +#endif diff --git a/solid-lite/backends/wmi/wmistorage.cpp b/solid-lite/backends/wmi/wmistorage.cpp new file mode 100644 index 000000000..72a256a2d --- /dev/null +++ b/solid-lite/backends/wmi/wmistorage.cpp @@ -0,0 +1,112 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmistorage.h" +#include "wmiquery.h" + +using namespace Solid::Backends::Wmi; + +Storage::Storage(WmiDevice *device) + : Block(device) +{ + + if(m_device->type() == Solid::DeviceInterface::StorageDrive) + { + WmiQuery::Item item = WmiDevice::win32DiskPartitionByDeviceIndex(m_device->property("DeviceID").toString()); + QString id = item.getProperty("DeviceID").toString(); + m_logicalDisk = WmiDevice::win32LogicalDiskByDiskPartitionID(id); + }else if(m_device->type() == Solid::DeviceInterface::OpticalDrive) + { + QString id = m_device->property("Drive").toString(); + m_logicalDisk = WmiDevice::win32LogicalDiskByDriveLetter(id); + } +} + +Storage::~Storage() +{ + +} + +Solid::StorageDrive::Bus Storage::bus() const +{ + if(m_device->type() == Solid::DeviceInterface::OpticalDrive) + return Solid::StorageDrive::Platform; + + + QString bus = m_device->property("InterfaceType").toString().toLower(); + + if (bus=="ide") + { + return Solid::StorageDrive::Ide; + } + else if (bus=="usb") + { + return Solid::StorageDrive::Usb; + } + else if (bus=="1394") + { + return Solid::StorageDrive::Ieee1394; + } + else if (bus=="scsi") + { + return Solid::StorageDrive::Scsi; + } +// else if (bus=="sata")//not availible http://msdn.microsoft.com/en-us/library/windows/desktop/aa394132(v=vs.85).aspx +// { +// return Solid::StorageDrive::Sata; +// } + else + { + return Solid::StorageDrive::Platform; + } +} + +Solid::StorageDrive::DriveType Storage::driveType() const +{ + ushort type = m_logicalDisk.getProperty("DriveType").toUInt(); + switch(type){ + case 2: + return Solid::StorageDrive::MemoryStick; + case 3: + return Solid::StorageDrive::HardDisk; + case 5: + return Solid::StorageDrive::CdromDrive; + default: + return Solid::StorageDrive::HardDisk; + } +} + +bool Storage::isRemovable() const +{ + return driveType() != Solid::StorageDrive::HardDisk; +} + +bool Storage::isHotpluggable() const +{ + return bus() == Solid::StorageDrive::Usb; +} + +qulonglong Storage::size() const +{ + return m_device->property("Size").toULongLong(); +} + +//#include "backends/wmi/wmistorage.moc" diff --git a/solid-lite/backends/wmi/wmistorage.h b/solid-lite/backends/wmi/wmistorage.h new file mode 100644 index 000000000..467452ed9 --- /dev/null +++ b/solid-lite/backends/wmi/wmistorage.h @@ -0,0 +1,57 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_STORAGE_H +#define SOLID_BACKENDS_WMI_STORAGE_H + +#include +#include "wmiblock.h" +#include "wmiquery.h" + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class Storage : public Block, virtual public Solid::Ifaces::StorageDrive +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::StorageDrive) + +public: + Storage(WmiDevice *device); + virtual ~Storage(); + + virtual Solid::StorageDrive::Bus bus() const; + virtual Solid::StorageDrive::DriveType driveType() const; + + virtual bool isRemovable() const; + virtual bool isHotpluggable() const; + virtual qulonglong size() const; +private: + WmiQuery::Item m_logicalDisk; +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_STORAGE_H diff --git a/solid-lite/backends/wmi/wmistorageaccess.cpp b/solid-lite/backends/wmi/wmistorageaccess.cpp new file mode 100644 index 000000000..36aaa422b --- /dev/null +++ b/solid-lite/backends/wmi/wmistorageaccess.cpp @@ -0,0 +1,208 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmistorageaccess.h" + +#include +#include +#include + +#include + +using namespace Solid::Backends::Wmi; + +StorageAccess::StorageAccess(WmiDevice *device) + : DeviceInterface(device), m_setupInProgress(false), m_teardownInProgress(false), + m_passphraseRequested(false) +{ + connect(device, SIGNAL(propertyChanged(QMap)), + this, SLOT(slotPropertyChanged(QMap))); +// qDebug()<<"StorageAccess"<type(); + + m_logicalDisk = WmiDevice::win32LogicalDiskByDiskPartitionID(m_device->property("DeviceID").toString()); +} + +StorageAccess::~StorageAccess() +{ + +} + + +bool StorageAccess::isAccessible() const +{ + return !m_logicalDisk.isNull(); +} + +QString StorageAccess::filePath() const +{ + QString path = m_logicalDisk.getProperty("DeviceID").toString(); + if(!path.isNull()) + path.append("\\"); + return path; +} + +bool Solid::Backends::Wmi::StorageAccess::isIgnored() const +{ + return m_logicalDisk.isNull(); +} + +bool StorageAccess::setup() +{ + if (m_teardownInProgress || m_setupInProgress) { + return false; + } + m_setupInProgress = true; + + + // if (m_device->property("info.interfaces").toStringList().contains("org.freedesktop.Wmi.Device.Volume.Crypto")) { + // return requestPassphrase(); + // } else if (FstabHandling::isInFstab(m_device->property("block.device").toString())) { + // return callSystemMount(); + // } else { + // return callWmiVolumeMount(); + // } + return false; +} + +bool StorageAccess::teardown() +{ + if (m_teardownInProgress || m_setupInProgress) { + return false; + } + m_teardownInProgress = true; + + // if (m_device->property("info.interfaces").toStringList().contains("org.freedesktop.Wmi.Device.Volume.Crypto")) { + // return callCryptoTeardown(); + // } else if (FstabHandling::isInFstab(m_device->property("block.device").toString())) { + // return callSystemUnmount(); + // } else { + // return callWmiVolumeUnmount(); + // } + return false; +} + +void StorageAccess::slotPropertyChanged(const QMap &changes) +{ + if (changes.contains("volume.is_mounted")) + { + emit accessibilityChanged(isAccessible(), m_device->udi()); + } +} + +void Solid::Backends::Wmi::StorageAccess::slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ +/* + Q_UNUSED(exitStatus); + if (m_setupInProgress) { + m_setupInProgress = false; + + if (exitCode==0) { + emit setupDone(Solid::NoError, QVariant(), m_device->udi()); + } else { + emit setupDone(Solid::UnauthorizedOperation, + m_process->readAllStandardError(), + m_device->udi()); + } + } else if (m_teardownInProgress) { + m_teardownInProgress = false; + if (exitCode==0) { + emit teardownDone(Solid::NoError, QVariant(), m_device->udi()); + } else { + emit teardownDone(Solid::UnauthorizedOperation, + m_process->readAllStandardError(), + m_device->udi()); + } + } + + delete m_process; + */ +} + +QString generateReturnObjectPath() +{ + static int number = 1; + + return "/org/kde/solid/WmiStorageAccess_"+QString::number(number++); +} + +bool StorageAccess::callWmiVolumeMount() +{ + // QDBusConnection c = QDBusConnection::systemBus(); + // QString udi = m_device->udi(); + // QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Wmi", udi, + // "org.freedesktop.Wmi.Device.Volume", + // "Mount"); + // QStringList options; + // QStringList wmiOptions = m_device->property("volume.mount.valid_options").toStringList(); + + // if (wmiOptions.contains("uid=")) { + // options << "uid="+QString::number(::getuid()); + // } + + // msg << "" << "" << options; + + // return c.callWithCallback(msg, this, + // SLOT(slotDBusReply(QDBusMessage)), + // SLOT(slotDBusError(QDBusError))); + return false; +} + +bool StorageAccess::callWmiVolumeUnmount() +{ + // QDBusConnection c = QDBusConnection::systemBus(); + // QString udi = m_device->udi(); + // QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Wmi", udi, + // "org.freedesktop.Wmi.Device.Volume", + // "Unmount"); + + // msg << QStringList(); + + // return c.callWithCallback(msg, this, + // SLOT(slotDBusReply(QDBusMessage)), + // SLOT(slotDBusError(QDBusError))); + return false; +} + +bool Solid::Backends::Wmi::StorageAccess::callSystemMount() +{ +/* + const QString device = m_device->property("block.device").toString(); + m_process = FstabHandling::callSystemCommand("mount", device, + this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); + + return m_process!=0; +*/ + return 0; +} + +bool Solid::Backends::Wmi::StorageAccess::callSystemUnmount() +{ +/* + const QString device = m_device->property("block.device").toString(); + m_process = FstabHandling::callSystemCommand("umount", device, + this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); + + return m_process!=0; +*/ + return 0; +} + +//#include "backends/wmi/wmistorageaccess.moc" diff --git a/solid-lite/backends/wmi/wmistorageaccess.h b/solid-lite/backends/wmi/wmistorageaccess.h new file mode 100644 index 000000000..d5825cd00 --- /dev/null +++ b/solid-lite/backends/wmi/wmistorageaccess.h @@ -0,0 +1,81 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_STORAGEACCESS_H +#define SOLID_BACKENDS_WMI_STORAGEACCESS_H + +#include +#include "wmideviceinterface.h" + +#include + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class StorageAccess : public DeviceInterface, virtual public Solid::Ifaces::StorageAccess +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::StorageAccess) + +public: + StorageAccess(WmiDevice *device); + virtual ~StorageAccess(); + + virtual bool isAccessible() const; + virtual QString filePath() const; + virtual bool isIgnored() const; + virtual bool setup(); + virtual bool teardown(); + +Q_SIGNALS: + void accessibilityChanged(bool accessible, const QString &udi); + void setupDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void teardownDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void setupRequested(const QString &udi); + void teardownRequested(const QString &udi); + +private Q_SLOTS: + void slotPropertyChanged(const QMap &changes); + void slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + +private: + bool callWmiVolumeMount(); + bool callWmiVolumeUnmount(); + + bool callSystemMount(); + bool callSystemUnmount(); + +private: + bool m_setupInProgress; + bool m_teardownInProgress; + bool m_passphraseRequested; + QString m_lastReturnObject; + QProcess *m_process; + WmiQuery::Item m_logicalDisk; +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_STORAGEACCESS_H diff --git a/solid-lite/backends/wmi/wmivolume.cpp b/solid-lite/backends/wmi/wmivolume.cpp new file mode 100644 index 000000000..f5bfe9675 --- /dev/null +++ b/solid-lite/backends/wmi/wmivolume.cpp @@ -0,0 +1,79 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "wmivolume.h" + +using namespace Solid::Backends::Wmi; + +Volume::Volume(WmiDevice *device) + : Block(device) +{ + if(m_device->type() == Solid::DeviceInterface::StorageVolume) + { + m_logicalDisk = WmiDevice::win32LogicalDiskByDiskPartitionID(m_device->property("DeviceID").toString()); + }else if(m_device->type() == Solid::DeviceInterface::OpticalDisc) + { + m_logicalDisk = WmiDevice::win32LogicalDiskByDriveLetter(m_device->property("Drive").toString()); + } +} + +Volume::~Volume() +{ + +} + + +bool Volume::isIgnored() const +{ + return m_logicalDisk.isNull(); +} + +Solid::StorageVolume::UsageType Volume::usage() const +{ + return Solid::StorageVolume::FileSystem;//TODO:??? +} + +QString Volume::fsType() const +{ + return m_logicalDisk.getProperty("FileSystem").toString(); +} + +QString Volume::label() const +{ + return m_logicalDisk.getProperty("VolumeName").toString(); +} + +QString Volume::uuid() const +{ + return m_logicalDisk.getProperty("VolumeSerialNumber").toString(); +} + +qulonglong Volume::size() const +{ + return m_device->property("Size").toULongLong(); +} + +QString Solid::Backends::Wmi::Volume::encryptedContainerUdi() const +{ + return this->uuid(); +} + +//#include "backends/wmi/wmivolume.moc" diff --git a/solid-lite/backends/wmi/wmivolume.h b/solid-lite/backends/wmi/wmivolume.h new file mode 100644 index 000000000..f1e877194 --- /dev/null +++ b/solid-lite/backends/wmi/wmivolume.h @@ -0,0 +1,58 @@ +/* + Copyright 2012 Patrick von Reth + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BACKENDS_WMI_VOLUME_H +#define SOLID_BACKENDS_WMI_VOLUME_H + +#include +#include "wmiblock.h" + +namespace Solid +{ +namespace Backends +{ +namespace Wmi +{ +class Volume : public Block, virtual public Solid::Ifaces::StorageVolume +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::StorageVolume) + +public: + Volume(WmiDevice *device); + virtual ~Volume(); + + virtual bool isIgnored() const; + virtual Solid::StorageVolume::UsageType usage() const; + virtual QString fsType() const; + virtual QString label() const; + virtual QString uuid() const; + virtual qulonglong size() const; + virtual QString encryptedContainerUdi() const; + +private: + WmiQuery::Item m_logicalDisk; +}; +} +} +} + +#endif // SOLID_BACKENDS_WMI_VOLUME_H diff --git a/solid-lite/block.cpp b/solid-lite/block.cpp new file mode 100644 index 000000000..96268f35e --- /dev/null +++ b/solid-lite/block.cpp @@ -0,0 +1,55 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "block.h" +#include "block_p.h" + +#include "soliddefs_p.h" +#include + +Solid::Block::Block(QObject *backendObject) + : DeviceInterface(*new BlockPrivate(), backendObject) +{ +} + +Solid::Block::~Block() +{ + +} + +int Solid::Block::deviceMajor() const +{ + Q_D(const Block); + return_SOLID_CALL(Ifaces::Block *, d->backendObject(), 0, deviceMajor()); +} + +int Solid::Block::deviceMinor() const +{ + Q_D(const Block); + return_SOLID_CALL(Ifaces::Block *, d->backendObject(), 0, deviceMinor()); +} + +QString Solid::Block::device() const +{ + Q_D(const Block); + return_SOLID_CALL(Ifaces::Block *, d->backendObject(), QString(), device()); +} + +//#include "block.moc" diff --git a/solid-lite/block.h b/solid-lite/block.h new file mode 100644 index 000000000..bd40dc332 --- /dev/null +++ b/solid-lite/block.h @@ -0,0 +1,103 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BLOCK_H +#define SOLID_BLOCK_H + +#include + +#include + +namespace Solid +{ + class BlockPrivate; + class Device; + + /** + * This device interface is available on block devices. + * + * A block device is an adressable device such as drive or partition. + * It is possible to interact with such a device using a special file + * in the system. + */ + class SOLID_EXPORT Block : public DeviceInterface + { + Q_OBJECT + Q_PROPERTY(int major READ deviceMajor) + Q_PROPERTY(int minor READ deviceMinor) + Q_PROPERTY(QString device READ device) + Q_DECLARE_PRIVATE(Block) + friend class Device; + + private: + /** + * Creates a new Block object. + * You generally won't need this. It's created when necessary using + * Device::as(). + * + * @param backendObject the device interface object provided by the backend + * @see Solid::Device::as() + */ + explicit Block(QObject *backendObject); + + public: + /** + * Destroys a Block object. + */ + virtual ~Block(); + + + /** + * Get the Solid::DeviceInterface::Type of the Block device interface. + * + * @return the Block device interface type + * @see Solid::Ifaces::Enums::DeviceInterface::Type + */ + static Type deviceInterfaceType() { return DeviceInterface::Block; } + + + /** + * Retrieves the major number of the node file to interact with + * the device. + * + * @return the device major number + */ + int deviceMajor() const; + + /** + * Retrieves the minor number of the node file to interact with + * the device. + * + * @return the device minor number + */ + int deviceMinor() const; + + /** + * Retrieves the absolute path of the special file to interact + * with the device. + * + * @return the absolute path of the special file to interact with + * the device + */ + QString device() const; + }; +} + +#endif diff --git a/solid-lite/block_p.h b/solid-lite/block_p.h new file mode 100644 index 000000000..b40b73bbc --- /dev/null +++ b/solid-lite/block_p.h @@ -0,0 +1,36 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_BLOCK_P_H +#define SOLID_BLOCK_P_H + +#include "deviceinterface_p.h" + +namespace Solid +{ + class BlockPrivate : public DeviceInterfacePrivate + { + public: + BlockPrivate() + : DeviceInterfacePrivate() { } + }; +} + +#endif diff --git a/solid-lite/config-solid.h.cmake b/solid-lite/config-solid.h.cmake new file mode 100644 index 000000000..84c3b5c8c --- /dev/null +++ b/solid-lite/config-solid.h.cmake @@ -0,0 +1,22 @@ +/* + Copyright 2010 Paulo Romulo Alves Barros + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#cmakedefine UDEV_FOUND +#cmakedefine HUPNP_FOUND diff --git a/solid-lite/device.cpp b/solid-lite/device.cpp new file mode 100644 index 000000000..814f1ebb4 --- /dev/null +++ b/solid-lite/device.cpp @@ -0,0 +1,328 @@ +/* + Copyright 2005-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "device.h" +#include "device_p.h" +#include "devicenotifier.h" +#include "devicemanager_p.h" + +#include "deviceinterface_p.h" +#include "soliddefs_p.h" + +#include + +#include +#include +//#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +#include +#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include + + +Solid::Device::Device(const QString &udi) +{ + DeviceManagerPrivate *manager + = static_cast(Solid::DeviceNotifier::instance()); + d = manager->findRegisteredDevice(udi); +} + +Solid::Device::Device(const Device &device) + : d(device.d) +{ +} + +Solid::Device::~Device() +{ +} + +Solid::Device &Solid::Device::operator=(const Solid::Device &device) +{ + d = device.d; + return *this; +} + +bool Solid::Device::isValid() const +{ + return d->backendObject()!=0; +} + +QString Solid::Device::udi() const +{ + return d->udi(); +} + +QString Solid::Device::parentUdi() const +{ + return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), parentUdi()); +} + +Solid::Device Solid::Device::parent() const +{ + QString udi = parentUdi(); + + if (udi.isEmpty()) + { + return Device(); + } + else + { + return Device(udi); + } +} + +QString Solid::Device::vendor() const +{ + return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), vendor()); +} + +QString Solid::Device::product() const +{ + return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), product()); +} + +QString Solid::Device::icon() const +{ + return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), icon()); +} + +QStringList Solid::Device::emblems() const +{ + return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QStringList(), emblems()); +} + +QString Solid::Device::description() const +{ + return_SOLID_CALL(Ifaces::Device *, d->backendObject(), QString(), description()); +} + +bool Solid::Device::isDeviceInterface(const DeviceInterface::Type &type) const +{ + return_SOLID_CALL(Ifaces::Device *, d->backendObject(), false, queryDeviceInterface(type)); +} + +#define deviceinterface_cast(IfaceType, DevType, backendObject) \ + (qobject_cast(backendObject) ? new DevType(backendObject) : 0) + +Solid::DeviceInterface *Solid::Device::asDeviceInterface(const DeviceInterface::Type &type) +{ + const Solid::DeviceInterface *interface = const_cast(this)->asDeviceInterface(type); + return const_cast(interface); +} + +const Solid::DeviceInterface *Solid::Device::asDeviceInterface(const DeviceInterface::Type &type) const +{ + Ifaces::Device *device = qobject_cast(d->backendObject()); + + if (device!=0) + { + DeviceInterface *iface = d->interface(type); + + if (iface!=0) { + return iface; + } + + QObject *dev_iface = device->createDeviceInterface(type); + + if (dev_iface!=0) + { + switch (type) + { + case DeviceInterface::GenericInterface: + iface = deviceinterface_cast(Ifaces::GenericInterface, GenericInterface, dev_iface); + break; + //case DeviceInterface::Processor: + // iface = deviceinterface_cast(Ifaces::Processor, Processor, dev_iface); + // break; + case DeviceInterface::Block: + iface = deviceinterface_cast(Ifaces::Block, Block, dev_iface); + break; + case DeviceInterface::StorageAccess: + iface = deviceinterface_cast(Ifaces::StorageAccess, StorageAccess, dev_iface); + break; + case DeviceInterface::StorageDrive: + iface = deviceinterface_cast(Ifaces::StorageDrive, StorageDrive, dev_iface); + break; + case DeviceInterface::OpticalDrive: + iface = deviceinterface_cast(Ifaces::OpticalDrive, OpticalDrive, dev_iface); + break; + case DeviceInterface::StorageVolume: + iface = deviceinterface_cast(Ifaces::StorageVolume, StorageVolume, dev_iface); + break; + case DeviceInterface::OpticalDisc: + iface = deviceinterface_cast(Ifaces::OpticalDisc, OpticalDisc, dev_iface); + break; + //case DeviceInterface::Camera: + // iface = deviceinterface_cast(Ifaces::Camera, Camera, dev_iface); + // break; + case DeviceInterface::PortableMediaPlayer: + iface = deviceinterface_cast(Ifaces::PortableMediaPlayer, PortableMediaPlayer, dev_iface); + break; + /*case DeviceInterface::NetworkInterface: + iface = deviceinterface_cast(Ifaces::NetworkInterface, NetworkInterface, dev_iface); + break; + case DeviceInterface::AcAdapter: + iface = deviceinterface_cast(Ifaces::AcAdapter, AcAdapter, dev_iface); + break; + case DeviceInterface::Battery: + iface = deviceinterface_cast(Ifaces::Battery, Battery, dev_iface); + break; + case DeviceInterface::Button: + iface = deviceinterface_cast(Ifaces::Button, Button, dev_iface); + break; + case DeviceInterface::AudioInterface: + iface = deviceinterface_cast(Ifaces::AudioInterface, AudioInterface, dev_iface); + break; + case DeviceInterface::DvbInterface: + iface = deviceinterface_cast(Ifaces::DvbInterface, DvbInterface, dev_iface); + break; + case DeviceInterface::Video: + iface = deviceinterface_cast(Ifaces::Video, Video, dev_iface); + break; + case DeviceInterface::SerialInterface: + iface = deviceinterface_cast(Ifaces::SerialInterface, SerialInterface, dev_iface); + break; + case DeviceInterface::SmartCardReader: + iface = deviceinterface_cast(Ifaces::SmartCardReader, SmartCardReader, dev_iface); + break; + case DeviceInterface::InternetGateway: + iface = deviceinterface_cast(Ifaces::InternetGateway, InternetGateway, dev_iface); + break; + case DeviceInterface::NetworkShare: + iface = deviceinterface_cast(Ifaces::NetworkShare, NetworkShare, dev_iface); + break; + */ + case DeviceInterface::Unknown: + case DeviceInterface::Last: + break; + } + } + + if (iface!=0) + { + // Lie on the constness since we're simply doing caching here + const_cast(this)->d->setInterface(type, iface); + iface->d_ptr->setDevicePrivate(d.data()); + } + + return iface; + } + else + { + return 0; + } +} + + +////////////////////////////////////////////////////////////////////// + + +Solid::DevicePrivate::DevicePrivate(const QString &udi) + : QObject(), QSharedData(), m_udi(udi) +{ +} + +Solid::DevicePrivate::~DevicePrivate() +{ + foreach (DeviceInterface *iface, m_ifaces) { + delete iface->d_ptr->backendObject(); + } + setBackendObject(0); +} + +void Solid::DevicePrivate::_k_destroyed(QObject *object) +{ + Q_UNUSED(object); + setBackendObject(0); +} + +void Solid::DevicePrivate::setBackendObject(Ifaces::Device *object) +{ + + if (m_backendObject) { + m_backendObject.data()->disconnect(this); + } + + delete m_backendObject.data(); + m_backendObject = object; + + if (object) { + connect(object, SIGNAL(destroyed(QObject*)), + this, SLOT(_k_destroyed(QObject*))); + } + + if (!m_ifaces.isEmpty()) { + foreach (DeviceInterface *iface, m_ifaces) { + delete iface; + } + + m_ifaces.clear(); + if (!ref.deref()) deleteLater(); + } +} + +Solid::DeviceInterface *Solid::DevicePrivate::interface(const DeviceInterface::Type &type) const +{ + return m_ifaces[type]; +} + +void Solid::DevicePrivate::setInterface(const DeviceInterface::Type &type, DeviceInterface *interface) +{ + if(m_ifaces.isEmpty()) + ref.ref(); + m_ifaces[type] = interface; +} + +// #include "device_p.moc" diff --git a/solid-lite/device.h b/solid-lite/device.h new file mode 100644 index 000000000..06c31875f --- /dev/null +++ b/solid-lite/device.h @@ -0,0 +1,274 @@ +/* + Copyright 2005-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_DEVICE_H +#define SOLID_DEVICE_H + +#include + +#include +#include +#include + +#include + +#include + +namespace Solid +{ + class DevicePrivate; + + /** + * This class allows applications to deal with devices available in the + * underlying system. + * + * Device stores a reference to device data provided by the backend. + * Device objects are designed to be used by value. Copying these objects + * is quite cheap, so using pointers to the me is generally not needed. + * + * @author Kevin Ottens + */ + class SOLID_EXPORT Device + { + public: + /** + * Retrieves all the devices available in the underlying system. + * + * @return the list of the devices available + */ + static QList allDevices(); + + /** + * Retrieves a list of devices of the system given matching the given + * constraints (parent and device interface type) + * + * @param type device interface type available on the devices we're looking for, or DeviceInterface::Unknown + * if there's no constraint on the device interfaces + * @param parentUdi UDI of the parent of the devices we're searching for, or QString() + * if there's no constraint on the parent + * @return the list of devices corresponding to the given constraints + * @see Solid::Predicate + */ + static QList listFromType(const DeviceInterface::Type &type, + const QString &parentUdi = QString()); + + /** + * Retrieves a list of devices of the system given matching the given + * constraints (parent and predicate) + * + * @param predicate Predicate that the devices we're searching for must verify + * @param parentUdi UDI of the parent of the devices we're searching for, or QString() + * if there's no constraint on the parent + * @return the list of devices corresponding to the given constraints + * @see Solid::Predicate + */ + static QList listFromQuery(const Predicate &predicate, + const QString &parentUdi = QString()); + + /** + * Convenience function see above. + * + * @param predicate + * @param parentUdi + * @return the list of devices + */ + static QList listFromQuery(const QString &predicate, + const QString &parentUdi = QString()); + + + /** + * Constructs a device for a given Universal Device Identifier (UDI). + * + * @param udi the udi of the device to create + */ + explicit Device(const QString &udi = QString()); + + /** + * Constructs a copy of a device. + * + * @param device the device to copy + */ + Device(const Device &device); + + /** + * Destroys the device. + */ + ~Device(); + + + + /** + * Assigns a device to this device and returns a reference to it. + * + * @param device the device to assign + * @return a reference to the device + */ + Device &operator=(const Device &device); + + /** + * Indicates if this device is valid. + * A device is considered valid if it's available in the system. + * + * @return true if this device is available, false otherwise + */ + bool isValid() const; + + + /** + * Retrieves the Universal Device Identifier (UDI). + * + * \warning Don't use the UDI for anything except communication with Solid. Also don't store + * UDIs as there's no guarantee that the UDI stays the same when the hardware setup changed. + * The UDI is a unique identifier that is local to the computer in question and for the + * current boot session. The UDIs may change after a reboot. + * Similar hardware in other computers may have different values; different + * hardware could have the same UDI. + * + * @return the udi of the device + */ + QString udi() const; + + /** + * Retrieves the Universal Device Identifier (UDI) + * of the Device's parent. + * + * @return the udi of the device's parent + */ + QString parentUdi() const; + + + /** + * Retrieves the parent of the Device. + * + * @return the device's parent + * @see parentUdi() + */ + Device parent() const; + + + + /** + * Retrieves the name of the device vendor. + * + * @return the vendor name + */ + QString vendor() const; + + /** + * Retrieves the name of the product corresponding to this device. + * + * @return the product name + */ + QString product() const; + + /** + * Retrieves the name of the icon representing this device. + * The naming follows the freedesktop.org specification. + * + * @return the icon name + */ + QString icon() const; + + /** + * Retrieves the names of the emblems representing the state of this device. + * The naming follows the freedesktop.org specification. + * + * @return the emblem names + * @since 4.4 + */ + QStringList emblems() const; + + /** + * Retrieves the description of device. + * + * @return the description + * @since 4.4 + */ + QString description() const; + + /** + * Tests if a device interface is available from the device. + * + * @param type the device interface type to query + * @return true if the device interface is available, false otherwise + */ + bool isDeviceInterface(const DeviceInterface::Type &type) const; + + /** + * Retrieves a specialized interface to interact with the device corresponding to + * a particular device interface. + * + * @param type the device interface type + * @returns a pointer to the device interface interface if it exists, 0 otherwise + */ + DeviceInterface *asDeviceInterface(const DeviceInterface::Type &type); + + /** + * Retrieves a specialized interface to interact with the device corresponding to + * a particular device interface. + * + * @param type the device interface type + * @returns a pointer to the device interface interface if it exists, 0 otherwise + */ + const DeviceInterface *asDeviceInterface(const DeviceInterface::Type &type) const; + + /** + * Retrieves a specialized interface to interact with the device corresponding + * to a given device interface. + * + * @returns a pointer to the device interface if it exists, 0 otherwise + */ + template DevIface *as() + { + DeviceInterface::Type type = DevIface::deviceInterfaceType(); + DeviceInterface *iface = asDeviceInterface(type); + return qobject_cast(iface); + } + + /** + * Retrieves a specialized interface to interact with the device corresponding + * to a given device interface. + * + * @returns a pointer to the device interface if it exists, 0 otherwise + */ + template const DevIface *as() const + { + DeviceInterface::Type type = DevIface::deviceInterfaceType(); + const DeviceInterface *iface = asDeviceInterface(type); + return qobject_cast(iface); + } + + /** + * Tests if a device provides a given device interface. + * + * @returns true if the interface is available, false otherwise + */ + template bool is() const + { + return isDeviceInterface(DevIface::deviceInterfaceType()); + } + + private: + QExplicitlySharedDataPointer d; + friend class DeviceManagerPrivate; + }; +} + +#endif diff --git a/solid-lite/device_p.h b/solid-lite/device_p.h new file mode 100644 index 000000000..53ea8d820 --- /dev/null +++ b/solid-lite/device_p.h @@ -0,0 +1,64 @@ +/* + Copyright 2005-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_DEVICE_P_H +#define SOLID_DEVICE_P_H + +#include +#include +#include + +#include +#include "deviceinterface.h" + +namespace Solid +{ + namespace Ifaces + { + class Device; + } + + class DevicePrivate : public QObject, public QSharedData + { + Q_OBJECT + public: + explicit DevicePrivate(const QString &udi); + ~DevicePrivate(); + + QString udi() const { return m_udi; } + + Ifaces::Device *backendObject() const { return m_backendObject.data(); } + void setBackendObject(Ifaces::Device *object); + + DeviceInterface *interface(const DeviceInterface::Type &type) const; + void setInterface(const DeviceInterface::Type &type, DeviceInterface *interface); + + public Q_SLOTS: + void _k_destroyed(QObject *object); + + private: + QString m_udi; + QWeakPointer m_backendObject; + QMap m_ifaces; + }; +} + + +#endif diff --git a/solid-lite/deviceinterface.cpp b/solid-lite/deviceinterface.cpp new file mode 100644 index 000000000..e9a54a7c0 --- /dev/null +++ b/solid-lite/deviceinterface.cpp @@ -0,0 +1,150 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "deviceinterface.h" +#include "deviceinterface_p.h" + +#include + +#include + + +Solid::DeviceInterface::DeviceInterface(DeviceInterfacePrivate &dd, QObject *backendObject) + : d_ptr(&dd) +{ + Q_D(DeviceInterface); + + d->setBackendObject(backendObject); +} + + +Solid::DeviceInterface::~DeviceInterface() +{ + delete d_ptr; + d_ptr = 0; +} + +bool Solid::DeviceInterface::isValid() const +{ + Q_D(const DeviceInterface); + return d->backendObject()!=0; +} + +QString Solid::DeviceInterface::typeToString(Type type) +{ + int index = staticMetaObject.indexOfEnumerator("Type"); + QMetaEnum metaEnum = staticMetaObject.enumerator(index); + return QString(metaEnum.valueToKey((int)type)); +} + +Solid::DeviceInterface::Type Solid::DeviceInterface::stringToType(const QString &type) +{ + int index = staticMetaObject.indexOfEnumerator("Type"); + QMetaEnum metaEnum = staticMetaObject.enumerator(index); + return (Type)metaEnum.keyToValue(type.toUtf8()); +} + +QString Solid::DeviceInterface::typeDescription(Type type) +{ + switch (type) + { + case Unknown: + return QObject::tr("Unknown", "Unknown device type"); + case GenericInterface: + return QObject::tr("Generic Interface", "Generic Interface device type"); + //case Processor: + // return QObject::tr("Processor", "Processor device type"); + case Block: + return QObject::tr("Block", "Block device type"); + case StorageAccess: + return QObject::tr("Storage Access", "Storage Access device type"); + case StorageDrive: + return QObject::tr("Storage Drive", "Storage Drive device type"); + case OpticalDrive: + return QObject::tr("Optical Drive", "Optical Drive device type"); + case StorageVolume: + return QObject::tr("Storage Volume", "Storage Volume device type"); + case OpticalDisc: + return QObject::tr("Optical Disc", "Optical Disc device type"); + //case Camera: + // return QObject::tr("Camera", "Camera device type"); + case PortableMediaPlayer: + return QObject::tr("Portable Media Player", "Portable Media Player device type"); + /*case NetworkInterface: + return QObject::tr("Network Interface", "Network Interface device type"); + case AcAdapter: + return QObject::tr("Ac Adapter", "Ac Adapter device type"); + case Battery: + return QObject::tr("Battery", "Battery device type"); + case Button: + return QObject::tr("Button", "Button device type"); + case AudioInterface: + return QObject::tr("Audio Interface", "Audio Interface device type"); + case DvbInterface: + return QObject::tr("Dvb Interface", "Dvb Interface device type"); + case Video: + return QObject::tr("Video", "Video device type"); + case SerialInterface: + return QObject::tr("Serial Interface", "Serial Interface device type"); + case SmartCardReader: + return QObject::tr("Smart Card Reader", "Smart Card Reader device type"); + case InternetGateway: + return QObject::tr("Internet Gateway Device", "Internet Gateway device type"); + case NetworkShare: + return QObject::tr("Network Share", "Network Share device type"); + */ + case Last: + return QString(); + } + return QString(); +} + +Solid::DeviceInterfacePrivate::DeviceInterfacePrivate() + : m_devicePrivate(0) +{ + +} + +Solid::DeviceInterfacePrivate::~DeviceInterfacePrivate() +{ + +} + +QObject *Solid::DeviceInterfacePrivate::backendObject() const +{ + return m_backendObject.data(); +} + +void Solid::DeviceInterfacePrivate::setBackendObject(QObject *object) +{ + m_backendObject = object; +} + +Solid::DevicePrivate* Solid::DeviceInterfacePrivate::devicePrivate() const +{ + return m_devicePrivate; +} + +void Solid::DeviceInterfacePrivate::setDevicePrivate(DevicePrivate *devicePrivate) +{ + m_devicePrivate = devicePrivate; +} + +//#include "deviceinterface.moc" diff --git a/solid-lite/deviceinterface.h b/solid-lite/deviceinterface.h new file mode 100644 index 000000000..6e4357f26 --- /dev/null +++ b/solid-lite/deviceinterface.h @@ -0,0 +1,126 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_DEVICEINTERFACE_H +#define SOLID_DEVICEINTERFACE_H + +#include +#include + +#include + +namespace Solid +{ + class Device; + class DevicePrivate; + class Predicate; + class DeviceInterfacePrivate; + + /** + * Base class of all the device interfaces. + * + * A device interface describes what a device can do. A device generally has + * a set of device interfaces. + */ + class SOLID_EXPORT DeviceInterface : public QObject + { + Q_OBJECT + Q_ENUMS(Type) + Q_DECLARE_PRIVATE(DeviceInterface) + + public: + /** + * This enum type defines the type of device interface that a Device can have. + * + * - Unknown : An undetermined device interface + * - Processor : A processor + * - Block : A block device + * - StorageAccess : A mechanism to access data on a storage device + * - StorageDrive : A storage drive + * - OpticalDrive : An optical drive (CD-ROM, DVD, ...) + * - StorageVolume : A volume + * - OpticalDisc : An optical disc + * - Camera : A digital camera + * - PortableMediaPlayer: A portable media player + * - NetworkInterface: A network interface + * - SerialInterface: A serial interface + * - SmartCardReader: A smart card reader interface + * - NetworkShare: A network share interface + */ + enum Type { Unknown = 0, GenericInterface = 1, /*Processor = 2, */ + Block = 3, StorageAccess = 4, StorageDrive = 5, + OpticalDrive = 6, StorageVolume = 7, OpticalDisc = 8, + /*Camera = 9, */PortableMediaPlayer = 10, + /*NetworkInterface = 11, AcAdapter = 12, Battery = 13, + Button = 14, AudioInterface = 15, DvbInterface = 16, Video = 17, + SerialInterface = 18, SmartCardReader = 19, InternetGateway = 20, + NetworkShare = 21, */ Last = 0xffff }; + + /** + * Destroys a DeviceInterface object. + */ + virtual ~DeviceInterface(); + + /** + * Indicates if this device interface is valid. + * A device interface is considered valid if the device it is referring is available in the system. + * + * @return true if this device interface's device is available, false otherwise + */ + bool isValid() const; + + /** + * + * @return the class name of the device interface type + */ + static QString typeToString(Type type); + + /** + * + * @return the device interface type for the given class name + */ + static Type stringToType(const QString &type); + + /** + * + * @return a description suitable to display in the UI of the device interface type + * @since 4.4 + */ + static QString typeDescription(Type type); + + protected: + /** + * @internal + * Creates a new DeviceInterface object. + * + * @param dd the private d member. It will take care of deleting it upon destruction. + * @param backendObject the device interface object provided by the backend + */ + DeviceInterface(DeviceInterfacePrivate &dd, QObject *backendObject); + + DeviceInterfacePrivate *d_ptr; + + private: + friend class Device; + friend class DevicePrivate; + }; +} + +#endif diff --git a/solid-lite/deviceinterface_p.h b/solid-lite/deviceinterface_p.h new file mode 100644 index 000000000..822e8249c --- /dev/null +++ b/solid-lite/deviceinterface_p.h @@ -0,0 +1,45 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_DEVICEINTERFACE_P_H +#define SOLID_DEVICEINTERFACE_P_H + +#include + +namespace Solid +{ + class DeviceInterfacePrivate + { + public: + DeviceInterfacePrivate(); + virtual ~DeviceInterfacePrivate(); + + QObject *backendObject() const; + void setBackendObject(QObject *object); + DevicePrivate *devicePrivate() const; + void setDevicePrivate(DevicePrivate *devicePrivate); + + private: + QWeakPointer m_backendObject; + DevicePrivate* m_devicePrivate; + }; +} + +#endif diff --git a/solid-lite/devicemanager.cpp b/solid-lite/devicemanager.cpp new file mode 100644 index 000000000..a6989743a --- /dev/null +++ b/solid-lite/devicemanager.cpp @@ -0,0 +1,293 @@ +/* + Copyright 2005-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "devicenotifier.h" +#include "devicemanager_p.h" //krazy:exclude=includes (devicenotifier.h is the header file for this class) + +#include "device.h" +#include "device_p.h" +#include "predicate.h" + +#include "ifaces/devicemanager.h" +#include "ifaces/device.h" + +#include "soliddefs_p.h" + +SOLID_GLOBAL_STATIC(Solid::DeviceManagerStorage, globalDeviceStorage) + +Solid::DeviceManagerPrivate::DeviceManagerPrivate() + : m_nullDevice(new DevicePrivate(QString())) +{ + loadBackends(); + + QList backends = managerBackends(); + foreach (QObject *backend, backends) { + connect(backend, SIGNAL(deviceAdded(QString)), + this, SLOT(_k_deviceAdded(QString))); + connect(backend, SIGNAL(deviceRemoved(QString)), + this, SLOT(_k_deviceRemoved(QString))); + } +} + +Solid::DeviceManagerPrivate::~DeviceManagerPrivate() +{ + QList backends = managerBackends(); + foreach (QObject *backend, backends) { + disconnect(backend, 0, this, 0); + } + + foreach (QWeakPointer dev, m_devicesMap) { + if (!dev.data()->ref.deref()) { + delete dev.data(); + } + } + + m_devicesMap.clear(); +} + +QList Solid::Device::allDevices() +{ + QList list; + QList backends = globalDeviceStorage->managerBackends(); + + foreach (QObject *backendObj, backends) { + Ifaces::DeviceManager *backend = qobject_cast(backendObj); + + if (backend == 0) continue; + + QStringList udis = backend->allDevices(); + + foreach (const QString &udi, udis) { + list.append(Device(udi)); + } + } + + return list; +} + +QList Solid::Device::listFromQuery(const QString &predicate, + const QString &parentUdi) +{ + Predicate p = Predicate::fromString(predicate); + + if (p.isValid()) + { + return listFromQuery(p, parentUdi); + } + else + { + return QList(); + } +} + +QList Solid::Device::listFromType(const DeviceInterface::Type &type, + const QString &parentUdi) +{ + QList list; + QList backends = globalDeviceStorage->managerBackends(); + + foreach (QObject *backendObj, backends) { + Ifaces::DeviceManager *backend = qobject_cast(backendObj); + + if (backend == 0) continue; + if (!backend->supportedInterfaces().contains(type)) continue; + + QStringList udis = backend->devicesFromQuery(parentUdi, type); + + foreach (const QString &udi, udis) { + list.append(Device(udi)); + } + } + + return list; +} + +QList Solid::Device::listFromQuery(const Predicate &predicate, + const QString &parentUdi) +{ + QList list; + QList backends = globalDeviceStorage->managerBackends(); + QSet usedTypes = predicate.usedTypes(); + + foreach (QObject *backendObj, backends) { + Ifaces::DeviceManager *backend = qobject_cast(backendObj); + + if (backend == 0) continue; + + QSet udis; + if (predicate.isValid()) { + QSet supportedTypes = backend->supportedInterfaces(); + if (supportedTypes.intersect(usedTypes).isEmpty()) { + continue; + } + + foreach (DeviceInterface::Type type, supportedTypes) { + udis+= QSet::fromList(backend->devicesFromQuery(parentUdi, type)); + } + } else { + udis+= QSet::fromList(backend->allDevices()); + } + + foreach (const QString &udi, udis) + { + Device dev(udi); + + bool matches = false; + + if(!predicate.isValid()) { + matches = true; + } else { + matches = predicate.matches(dev); + } + + if (matches) + { + list.append(dev); + } + } + } + + return list; +} + +Solid::DeviceNotifier *Solid::DeviceNotifier::instance() +{ + return globalDeviceStorage->notifier(); +} + +void Solid::DeviceManagerPrivate::_k_deviceAdded(const QString &udi) +{ + if (m_devicesMap.contains(udi)) { + DevicePrivate *dev = m_devicesMap[udi].data(); + + // Ok, this one was requested somewhere was invalid + // and now becomes magically valid! + + if (dev && dev->backendObject() == 0) { + dev->setBackendObject(createBackendObject(udi)); + Q_ASSERT(dev->backendObject()!=0); + } + } + + emit deviceAdded(udi); +} + +void Solid::DeviceManagerPrivate::_k_deviceRemoved(const QString &udi) +{ + if (m_devicesMap.contains(udi)) { + DevicePrivate *dev = m_devicesMap[udi].data(); + + // Ok, this one was requested somewhere was valid + // and now becomes magically invalid! + + if (dev) { + Q_ASSERT(dev->backendObject()!=0); + dev->setBackendObject(0); + Q_ASSERT(dev->backendObject()==0); + } + } + + emit deviceRemoved(udi); +} + +void Solid::DeviceManagerPrivate::_k_destroyed(QObject *object) +{ + QString udi = m_reverseMap.take(object); + + if (!udi.isEmpty()) { + m_devicesMap.remove(udi); + } +} + +Solid::DevicePrivate *Solid::DeviceManagerPrivate::findRegisteredDevice(const QString &udi) +{ + if (udi.isEmpty()) { + return m_nullDevice.data(); + } else if (m_devicesMap.contains(udi)) { + return m_devicesMap[udi].data(); + } else { + Ifaces::Device *iface = createBackendObject(udi); + + DevicePrivate *devData = new DevicePrivate(udi); + devData->setBackendObject(iface); + + QWeakPointer ptr(devData); + m_devicesMap[udi] = ptr; + m_reverseMap[devData] = udi; + + connect(devData, SIGNAL(destroyed(QObject*)), + this, SLOT(_k_destroyed(QObject*))); + + return devData; + } +} + +Solid::Ifaces::Device *Solid::DeviceManagerPrivate::createBackendObject(const QString &udi) +{ + QList backends = globalDeviceStorage->managerBackends(); + + foreach (QObject *backendObj, backends) { + Ifaces::DeviceManager *backend = qobject_cast(backendObj); + + if (backend == 0) continue; + if (!udi.startsWith(backend->udiPrefix())) continue; + + Ifaces::Device *iface = 0; + + QObject *object = backend->createDevice(udi); + iface = qobject_cast(object); + + if (iface==0) { + delete object; + } + + return iface; + } + + return 0; +} + +Solid::DeviceManagerStorage::DeviceManagerStorage() +{ + +} + +QList Solid::DeviceManagerStorage::managerBackends() +{ + ensureManagerCreated(); + return m_storage.localData()->managerBackends(); +} + +Solid::DeviceNotifier *Solid::DeviceManagerStorage::notifier() +{ + ensureManagerCreated(); + return m_storage.localData(); +} + +void Solid::DeviceManagerStorage::ensureManagerCreated() +{ + if (!m_storage.hasLocalData()) { + m_storage.setLocalData(new DeviceManagerPrivate()); + } +} + +//#include "devicenotifier.moc" +// #include "devicemanager_p.moc" + diff --git a/solid-lite/devicemanager_p.h b/solid-lite/devicemanager_p.h new file mode 100644 index 000000000..0d8bd8e77 --- /dev/null +++ b/solid-lite/devicemanager_p.h @@ -0,0 +1,80 @@ +/* + Copyright 2005-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_DEVICEMANAGER_P_H +#define SOLID_DEVICEMANAGER_P_H + +#include "managerbase_p.h" + +#include "devicenotifier.h" + +#include +#include +#include +#include + +namespace Solid +{ + namespace Ifaces + { + class Device; + } + class DevicePrivate; + + + class DeviceManagerPrivate : public DeviceNotifier, public ManagerBasePrivate + { + Q_OBJECT + public: + DeviceManagerPrivate(); + ~DeviceManagerPrivate(); + + DevicePrivate *findRegisteredDevice(const QString &udi); + + private Q_SLOTS: + void _k_deviceAdded(const QString &udi); + void _k_deviceRemoved(const QString &udi); + void _k_destroyed(QObject *object); + + private: + Ifaces::Device *createBackendObject(const QString &udi); + + QExplicitlySharedDataPointer m_nullDevice; + QMap > m_devicesMap; + QMap m_reverseMap; + }; + + class DeviceManagerStorage + { + public: + DeviceManagerStorage(); + + QList managerBackends(); + DeviceNotifier *notifier(); + + private: + void ensureManagerCreated(); + + QThreadStorage m_storage; + }; +} + + +#endif diff --git a/solid-lite/devicenotifier.h b/solid-lite/devicenotifier.h new file mode 100644 index 000000000..e382529f8 --- /dev/null +++ b/solid-lite/devicenotifier.h @@ -0,0 +1,65 @@ +/* + Copyright 2005-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_DEVICENOTIFIER_H +#define SOLID_DEVICENOTIFIER_H + +#include +#include + +#include + +namespace Solid +{ + /** + * This class allow to query the underlying system to obtain information + * about the hardware available. + * + * It's the unique entry point for hardware discovery. Applications should use + * it to find devices, or to be notified about hardware changes. + * + * Note that it's implemented as a singleton and encapsulates the backend logic. + * + * @author Kevin Ottens + */ + class SOLID_EXPORT DeviceNotifier : public QObject //krazy:exclude=dpointer (interface class) + { + Q_OBJECT + public: + static DeviceNotifier *instance(); + + Q_SIGNALS: + /** + * This signal is emitted when a new device appear in the underlying system. + * + * @param udi the new device UDI + */ + void deviceAdded(const QString &udi); + + /** + * This signal is emitted when a device disappear from the underlying system. + * + * @param udi the old device UDI + */ + void deviceRemoved(const QString &udi); + }; +} + +#endif diff --git a/solid-lite/genericinterface.cpp b/solid-lite/genericinterface.cpp new file mode 100644 index 000000000..d840cde12 --- /dev/null +++ b/solid-lite/genericinterface.cpp @@ -0,0 +1,63 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "genericinterface.h" +#include "genericinterface_p.h" +#include "soliddefs_p.h" + +#include + + +Solid::GenericInterface::GenericInterface(QObject *backendObject) + : DeviceInterface(*new GenericInterfacePrivate(), backendObject) +{ + if (backendObject) { + connect(backendObject, SIGNAL(propertyChanged(QMap)), + this, SIGNAL(propertyChanged(QMap))); + connect(backendObject, SIGNAL(conditionRaised(QString,QString)), + this, SIGNAL(conditionRaised(QString,QString))); + } +} + + +Solid::GenericInterface::~GenericInterface() +{ + +} + +QVariant Solid::GenericInterface::property(const QString &key) const +{ + Q_D(const GenericInterface); + return_SOLID_CALL(Ifaces::GenericInterface *, d->backendObject(), QVariant(), property(key)); +} + +QMap Solid::GenericInterface::allProperties() const +{ + Q_D(const GenericInterface); + return_SOLID_CALL(Ifaces::GenericInterface *, d->backendObject(), QVariantMap(), allProperties()); +} + +bool Solid::GenericInterface::propertyExists(const QString &key) const +{ + Q_D(const GenericInterface); + return_SOLID_CALL(Ifaces::GenericInterface *, d->backendObject(), false, propertyExists(key)); +} + +//#include "genericinterface.moc" diff --git a/solid-lite/genericinterface.h b/solid-lite/genericinterface.h new file mode 100644 index 000000000..1b442314b --- /dev/null +++ b/solid-lite/genericinterface.h @@ -0,0 +1,150 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_GENERICINTERFACE_H +#define SOLID_GENERICINTERFACE_H + +#include +#include + +#include +#include + +namespace Solid +{ + class GenericInterfacePrivate; + class Device; + + /** + * Generic interface to deal with a device. It exposes a set of properties + * and is organized as a key/value set. + * + * Warning: Using this class could expose some backend specific details + * and lead to non portable code. Use it at your own risk, or during + * transitional phases when the provided device interfaces don't + * provide the necessary methods. + */ + class SOLID_EXPORT GenericInterface : public DeviceInterface + { + Q_OBJECT + Q_ENUMS(PropertyChange) + Q_DECLARE_PRIVATE(GenericInterface) + friend class Device; + + public: + /** + * This enum type defines the type of change that can occur to a GenericInterface + * property. + * + * - PropertyModified : A property value has changed in the device + * - PropertyAdded : A new property has been added to the device + * - PropertyRemoved : A property has been removed from the device + */ + enum PropertyChange { PropertyModified, PropertyAdded, PropertyRemoved }; + + private: + /** + * Creates a new GenericInterface object. + * You generally won't need this. It's created when necessary using + * Device::as(). + * + * @param backendObject the device interface object provided by the backend + * @see Solid::Device::as() + */ + explicit GenericInterface(QObject *backendObject); + + public: + /** + * Destroys a Processor object. + */ + virtual ~GenericInterface(); + + + /** + * Get the Solid::DeviceInterface::Type of the GenericInterface device interface. + * + * @return the Processor device interface type + * @see Solid::Ifaces::Enums::DeviceInterface::Type + */ + static Type deviceInterfaceType() { return DeviceInterface::GenericInterface; } + + /** + * Retrieves a property of the device. + * + * Warning: Using this method could expose some backend specific details + * and lead to non portable code. Use it at your own risk, or during + * transitional phases when the provided device interfaces don't + * provide the necessary methods. + * + * @param key the property key + * @return the actual value of the property, or QVariant() if the + * property is unknown + */ + QVariant property(const QString &key) const; + + /** + * Retrieves a key/value map of all the known properties for the device. + * + * Warning: Using this method could expose some backend specific details + * and lead to non portable code. Use it at your own risk, or during + * transitional phases when the provided device interfaces don't + * provide the necessary methods. + * + * @return all the properties of the device + */ + QMap allProperties() const; + + /** + * Tests if a property exist in the device. + * + * Warning: Using this method could expose some backend specific details + * and lead to non portable code. Use it at your own risk, or during + * transitional phases when the provided device interfaces don't + * provide the necessary methods. + * + * @param key the property key + * @return true if the property is available in the device, false + * otherwise + */ + bool propertyExists(const QString &key) const; + + Q_SIGNALS: + /** + * This signal is emitted when a property is changed in the device. + * + * @param changes the map describing the property changes that + * occurred in the device, keys are property name and values + * describe the kind of change done on the device property + * (added/removed/modified), it's one of the type Solid::Device::PropertyChange + */ + void propertyChanged(const QMap &changes); + + /** + * This signal is emitted when an event occurred in the device. + * For example when a button is pressed. + * + * @param condition the condition name + * @param reason a message explaining why the condition has been raised + */ + void conditionRaised(const QString &condition, const QString &reason); + }; +} + +#endif diff --git a/solid-lite/genericinterface_p.h b/solid-lite/genericinterface_p.h new file mode 100644 index 000000000..e764573b4 --- /dev/null +++ b/solid-lite/genericinterface_p.h @@ -0,0 +1,36 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_GENERICINTERFACE_P_H +#define SOLID_GENERICINTERFACE_P_H + +#include "deviceinterface_p.h" + +namespace Solid +{ + class GenericInterfacePrivate : public DeviceInterfacePrivate + { + public: + GenericInterfacePrivate() + : DeviceInterfacePrivate() { } + }; +} + +#endif diff --git a/solid-lite/ifaces/CMakeLists.txt b/solid-lite/ifaces/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/solid-lite/ifaces/block.cpp b/solid-lite/ifaces/block.cpp new file mode 100644 index 000000000..fa9913b3f --- /dev/null +++ b/solid-lite/ifaces/block.cpp @@ -0,0 +1,26 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "block.h" + +Solid::Ifaces::Block::~Block() +{ +} + diff --git a/solid-lite/ifaces/block.h b/solid-lite/ifaces/block.h new file mode 100644 index 000000000..cbc67423a --- /dev/null +++ b/solid-lite/ifaces/block.h @@ -0,0 +1,75 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_BLOCK_H +#define SOLID_IFACES_BLOCK_H + +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * This device interface is available on block devices. + * + * A block device is an adressable device such as drive or partition. + * It is possible to interact with such a device using a special file + * in the system. + */ + class Block : virtual public DeviceInterface + { + public: + /** + * Destroys a Block object. + */ + virtual ~Block(); + + /** + * Retrieves the major number of the node file to interact with + * the device. + * + * @return the device major number + */ + virtual int deviceMajor() const = 0; + + /** + * Retrieves the minor number of the node file to interact with + * the device. + * + * @return the device minor number + */ + virtual int deviceMinor() const = 0; + + /** + * Retrieves the absolute path of the special file to interact + * with the device. + * + * @return the absolute path of the special file to interact with + * the device + */ + virtual QString device() const = 0; + }; +} +} + +Q_DECLARE_INTERFACE(Solid::Ifaces::Block, "org.kde.Solid.Ifaces.Block/0.1") + +#endif diff --git a/solid-lite/ifaces/device.cpp b/solid-lite/ifaces/device.cpp new file mode 100644 index 000000000..29e185902 --- /dev/null +++ b/solid-lite/ifaces/device.cpp @@ -0,0 +1,77 @@ +/* + Copyright 2005 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "ifaces/device.h" + +#include +#include + +Solid::Ifaces::Device::Device(QObject *parent) + : QObject(parent) +{ + +} + +Solid::Ifaces::Device::~Device() +{ + +} + +QString Solid::Ifaces::Device::parentUdi() const +{ + return QString(); +} + +void Solid::Ifaces::Device::registerAction(const QString &actionName, + QObject *dest, + const char *requestSlot, + const char *doneSlot) const +{ + QDBusConnection::sessionBus().connect(QString(), deviceDBusPath(), + "org.kde.Solid.Device", actionName+"Requested", + dest, requestSlot); + + QDBusConnection::sessionBus().connect(QString(), deviceDBusPath(), + "org.kde.Solid.Device", actionName+"Done", + dest, doneSlot); +} + +void Solid::Ifaces::Device::broadcastActionDone(const QString &actionName, + int error, const QString &errorString) const +{ + QDBusMessage signal = QDBusMessage::createSignal(deviceDBusPath(), "org.kde.Solid.Device", actionName+"Done"); + signal << error << errorString; + + QDBusConnection::sessionBus().send(signal); +} + +void Solid::Ifaces::Device::broadcastActionRequested(const QString &actionName) const +{ + QDBusMessage signal = QDBusMessage::createSignal(deviceDBusPath(), "org.kde.Solid.Device", actionName+"Requested"); + QDBusConnection::sessionBus().send(signal); +} + +QString Solid::Ifaces::Device::deviceDBusPath() const +{ + const QByteArray encodedUdi = udi().toUtf8().toPercentEncoding(QByteArray(), ".~", '_'); + return QString("/org/kde/solid/Device_") + QString::fromLatin1(encodedUdi); +} + +//#include "ifaces/device.moc" diff --git a/solid-lite/ifaces/device.h b/solid-lite/ifaces/device.h new file mode 100644 index 000000000..18581b952 --- /dev/null +++ b/solid-lite/ifaces/device.h @@ -0,0 +1,170 @@ +/* + Copyright 2005 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_DEVICE_H +#define SOLID_IFACES_DEVICE_H + +#include +#include + +#include + +#include +#include +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * This class specifies the interface a device will have to comply to in order to be used in the system. + * + * Backends will have to implement it to gather and modify data in the underlying system. + * Each device has a set of key/values pair describing its properties. It has also a list of interfaces + * describing what the device actually is (a cdrom drive, a portable media player, etc.) + * + * @author Kevin Ottens + */ + class Device : public QObject + { + Q_OBJECT + + public: + /** + * Constructs a Device + */ + Device(QObject *parent = 0); + /** + * Destruct the Device object + */ + virtual ~Device(); + + + /** + * Retrieves the Universal Device Identifier (UDI) of the Device. + * This identifier is unique for each device in the system. + * + * @returns the Universal Device Identifier of the current device + */ + virtual QString udi() const = 0; + + /** + * Retrieves the Universal Device Identifier (UDI) of the Device's + * parent. + * + * @returns the Universal Device Identifier of the parent device + */ + virtual QString parentUdi() const; + + + /** + * Retrieves the name of the device vendor. + * + * @return the vendor name + */ + virtual QString vendor() const = 0; + + /** + * Retrieves the name of the product corresponding to this device. + * + * @return the product name + */ + virtual QString product() const = 0; + + /** + * Retrieves the name of the icon representing this device. + * The naming follows the freedesktop.org specification. + * + * @return the icon name + */ + virtual QString icon() const = 0; + + /** + * Retrieves the name of the emblems representing the state of this device. + * The naming follows the freedesktop.org specification. + * + * @return the emblem names + */ + virtual QStringList emblems() const = 0; + + /** + * Retrieves the description of device. + * + * @return the description + */ + virtual QString description() const = 0; + + /** + * Tests if a property exist. + * + * @param type the device interface type + * @returns true if the device interface is provided by this device, false otherwise + */ + virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type &type) const = 0; + + /** + * Create a specialized interface to interact with the device corresponding to + * a particular device interface. + * + * @param type the device interface type + * @returns a pointer to the device interface if supported by the device, 0 otherwise + */ + virtual QObject *createDeviceInterface(const Solid::DeviceInterface::Type &type) = 0; + + /** + * Register an action for the given device. Each time the same device in another process + * broadcast the begin or the end of such action, the corresponding slots will be called + * in the current process. + * + * @param actionName name of the action to register + * @param dest the object receiving the messages when the action begins and ends + * @param requestSlot the slot processing the message when the action begins + * @param doneSlot the slot processing the message when the action ends + */ + void registerAction(const QString &actionName, QObject *dest, const char *requestSlot, const char *doneSlot) const; + + /** + * Allows to broadcat that an action just got requested on a device to all + * the corresponding devices in other processes. + * + * @param actionName name of the action which just completed + */ + void broadcastActionRequested(const QString &actionName) const; + + /** + * Allows to broadcast that an action just completed in a device to all + * the corresponding devices in other processes. + * + * @param actionName name of the action which just completed + * @param error error code if the action failed + * @param errorString message describing a potential error + */ + void broadcastActionDone(const QString &actionName, + int error = Solid::NoError, + const QString &errorString = QString()) const; + + private: + QString deviceDBusPath() const; + }; +} +} + +#endif diff --git a/solid-lite/ifaces/deviceinterface.cpp b/solid-lite/ifaces/deviceinterface.cpp new file mode 100644 index 000000000..32ec1605b --- /dev/null +++ b/solid-lite/ifaces/deviceinterface.cpp @@ -0,0 +1,26 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "deviceinterface.h" + +Solid::Ifaces::DeviceInterface::~DeviceInterface() +{ +} + diff --git a/solid-lite/ifaces/deviceinterface.h b/solid-lite/ifaces/deviceinterface.h new file mode 100644 index 000000000..7cde0d85c --- /dev/null +++ b/solid-lite/ifaces/deviceinterface.h @@ -0,0 +1,52 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_DEVICEINTERFACE_H +#define SOLID_IFACES_DEVICEINTERFACE_H + +#include +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * Base interface of all the device interfaces. + * + * A device interface describes what a device can do. A device generally has + * a set of device interfaces. + * + * @see Solid::Ifaces::AbstractDeviceInterface + */ + class DeviceInterface + { + public: + /** + * Destroys a DeviceInterface object. + */ + virtual ~DeviceInterface(); + }; +} +} + +Q_DECLARE_INTERFACE(Solid::Ifaces::DeviceInterface, "org.kde.Solid.Ifaces.DeviceInterface/0.1") + +#endif diff --git a/solid-lite/ifaces/devicemanager.cpp b/solid-lite/ifaces/devicemanager.cpp new file mode 100644 index 000000000..bb61ef998 --- /dev/null +++ b/solid-lite/ifaces/devicemanager.cpp @@ -0,0 +1,35 @@ +/* + Copyright 2005 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "ifaces/devicemanager.h" + + +Solid::Ifaces::DeviceManager::DeviceManager(QObject *parent) + : QObject(parent) +{ + +} + +Solid::Ifaces::DeviceManager::~DeviceManager() +{ + +} + +//#include "ifaces/devicemanager.moc" diff --git a/solid-lite/ifaces/devicemanager.h b/solid-lite/ifaces/devicemanager.h new file mode 100644 index 000000000..ef0609faa --- /dev/null +++ b/solid-lite/ifaces/devicemanager.h @@ -0,0 +1,115 @@ +/* + Copyright 2005 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_DEVICEMANAGER_H +#define SOLID_IFACES_DEVICEMANAGER_H + +#include + +#include + +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * This class specifies the interface a backend will have to implement in + * order to be used in the system. + * + * A device manager allows to query the underlying platform to discover the + * available devices. It has also the responsibility to notify when a device + * appears or disappears. + */ + class DeviceManager : public QObject + { + Q_OBJECT + + public: + /** + * Constructs a DeviceManager + */ + DeviceManager(QObject *parent = 0); + /** + * Destructs a DeviceManager object + */ + virtual ~DeviceManager(); + + /** + * Retrieves the prefix used for the UDIs off all the devices + * reported by the device manager + */ + virtual QString udiPrefix() const = 0; + + /** + * Retrieves a set of interfaces the backend supports + */ + virtual QSet supportedInterfaces() const = 0; + + /** + * Retrieves the Universal Device Identifier (UDI) of all the devices + * available in the system. This identifier is unique for each device + * in the system. + * + * @returns the UDIs of all the devices in the system + */ + virtual QStringList allDevices() = 0; + + /** + * Retrieves the Universal Device Identifier (UDI) of all the devices + * matching the given constraints (parent and device interface) + * + * @param parentUdi UDI of the parent of the devices we're searching for, or QString() + * if there's no constraint on the parent + * @param type DeviceInterface type available on the devices we're looking for, or DeviceInterface::Unknown + * if there's no constraint on the device interfaces + * @returns the UDIs of all the devices having the given parent and device interface + */ + virtual QStringList devicesFromQuery(const QString &parentUdi, + Solid::DeviceInterface::Type type = Solid::DeviceInterface::Unknown) = 0; + + /** + * Instantiates a new Device object from this backend given its UDI. + * + * @param udi the identifier of the device instantiated + * @returns a new Device object if there's a device having the given UDI, 0 otherwise + */ + virtual QObject *createDevice(const QString &udi) = 0; + + Q_SIGNALS: + /** + * This signal is emitted when a new device appears in the system. + * + * @param udi the new device identifier + */ + void deviceAdded(const QString &udi); + + /** + * This signal is emitted when a device disappears from the system. + * + * @param udi the old device identifier + */ + void deviceRemoved(const QString &udi); + }; +} +} + +#endif diff --git a/solid-lite/ifaces/genericinterface.cpp b/solid-lite/ifaces/genericinterface.cpp new file mode 100644 index 000000000..e2208d8c6 --- /dev/null +++ b/solid-lite/ifaces/genericinterface.cpp @@ -0,0 +1,26 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "genericinterface.h" + +Solid::Ifaces::GenericInterface::~GenericInterface() +{ +} + diff --git a/solid-lite/ifaces/genericinterface.h b/solid-lite/ifaces/genericinterface.h new file mode 100644 index 000000000..d4959bb5b --- /dev/null +++ b/solid-lite/ifaces/genericinterface.h @@ -0,0 +1,99 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_GENERICINTERFACE_H +#define SOLID_IFACES_GENERICINTERFACE_H + +#include +#include +#include +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * Generic interface to deal with a device. It exposes a set of properties + * and is organized a a key/value set. + * + * Warning: Using this class could expose some backend specific details + * and lead to non portable code. Use it at your own risk, or during + * transitional phases when the provided device interfaces don't + * provide the necessary methods. + */ + class GenericInterface + { + public: + /** + * Destroys a GenericInterface object. + */ + virtual ~GenericInterface(); + + /** + * Retrieves the value of a property. + * + * @param key the property name + * @returns the property value or QVariant() if the property doesn't exist + */ + virtual QVariant property(const QString &key) const = 0; + + /** + * Retrieves all the properties of this device. + * + * @returns all properties in a map + */ + virtual QMap allProperties() const = 0; + + /** + * Tests if a property exist. + * + * @param key the property name + * @returns true if the property exists in this device, false otherwise + */ + virtual bool propertyExists(const QString &key) const = 0; + + protected: + //Q_SIGNALS: + /** + * This signal is emitted when a property is changed in the device. + * + * @param changes the map describing the property changes that + * occurred in the device, keys are property name and values + * describe the kind of change done on the device property + * (added/removed/modified), it's one of the type Solid::Device::PropertyChange + */ + virtual void propertyChanged(const QMap &changes) = 0; + + /** + * This signal is emitted when an event occurred in the device. + * For example when a button is pressed. + * + * @param condition the condition name + * @param reason a message explaining why the condition has been raised + */ + virtual void conditionRaised(const QString &condition, const QString &reason) = 0; + }; +} +} + +Q_DECLARE_INTERFACE(Solid::Ifaces::GenericInterface, "org.kde.Solid.Ifaces.GenericInterface/0.1") + +#endif diff --git a/solid-lite/ifaces/opticaldisc.cpp b/solid-lite/ifaces/opticaldisc.cpp new file mode 100644 index 000000000..5047fa0c0 --- /dev/null +++ b/solid-lite/ifaces/opticaldisc.cpp @@ -0,0 +1,26 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "opticaldisc.h" + +Solid::Ifaces::OpticalDisc::~OpticalDisc() +{ +} + diff --git a/solid-lite/ifaces/opticaldisc.h b/solid-lite/ifaces/opticaldisc.h new file mode 100644 index 000000000..4ef41e969 --- /dev/null +++ b/solid-lite/ifaces/opticaldisc.h @@ -0,0 +1,96 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_OPTICALDISC_H +#define SOLID_IFACES_OPTICALDISC_H + +#include +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * This device interface is available on optical discs. + * + * An optical disc is a volume that can be inserted in a cdrom drive. + */ + class OpticalDisc : virtual public StorageVolume + { + public: + /** + * Destroys an OpticalDisc object. + */ + virtual ~OpticalDisc(); + + + /** + * Retrieves the content types this disc contains (audio, video, + * data...). + * + * @return the flag set indicating the available contents + */ + virtual Solid::OpticalDisc::ContentTypes availableContent() const = 0; + + /** + * Retrieves the disc type (cdr, cdrw...). + * + * @return the disc type + */ + virtual Solid::OpticalDisc::DiscType discType() const = 0; + + /** + * Indicates if it's possible to write additional data to the disc. + * + * @return true if the disc is appendable, false otherwise + */ + virtual bool isAppendable() const = 0; + + /** + * Indicates if the disc is blank. + * + * @return true if the disc is blank, false otherwise + */ + virtual bool isBlank() const = 0; + + /** + * Indicates if the disc is rewritable. + * + * A disc is rewritable if you can write on it several times. + * + * @return true if the disc is rewritable, false otherwise + */ + virtual bool isRewritable() const = 0; + + /** + * Retrieves the disc capacity (that is the maximum size of a + * volume could have on this disc). + * + * @return the capacity of the disc in bytes + */ + virtual qulonglong capacity() const = 0; + }; +} +} + +Q_DECLARE_INTERFACE(Solid::Ifaces::OpticalDisc, "org.kde.Solid.Ifaces.OpticalDisc/0.1") + +#endif diff --git a/solid-lite/ifaces/opticaldrive.cpp b/solid-lite/ifaces/opticaldrive.cpp new file mode 100644 index 000000000..91679f1d3 --- /dev/null +++ b/solid-lite/ifaces/opticaldrive.cpp @@ -0,0 +1,26 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "opticaldrive.h" + +Solid::Ifaces::OpticalDrive::~OpticalDrive() +{ +} + diff --git a/solid-lite/ifaces/opticaldrive.h b/solid-lite/ifaces/opticaldrive.h new file mode 100644 index 000000000..3903a1980 --- /dev/null +++ b/solid-lite/ifaces/opticaldrive.h @@ -0,0 +1,101 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACE_OPTICALDRIVE_H +#define SOLID_IFACE_OPTICALDRIVE_H + +#include + +#include +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * This device interface is available on CD-ROM drives. + * + * A Cdrom is a storage that can handle optical discs. + */ + class OpticalDrive : virtual public StorageDrive + { + public: + /** + * Destroys a Cdrom object. + */ + virtual ~OpticalDrive(); + + /** + * Retrieves the medium types this drive supports. + * + * @return the flag set indicating the supported medium types + */ + virtual Solid::OpticalDrive::MediumTypes supportedMedia() const = 0; + + /** + * Retrieves the maximum read speed of this drive in kilobytes. + * + * @return the maximum read speed + */ + virtual int readSpeed() const = 0; + + /** + * Retrieves the maximum write speed of this drive in kilobytes. + * + * @return the maximum write speed + */ + virtual int writeSpeed() const = 0; + + /** + * Retrieves the list of supported write speeds of this drive in + * kilobytes. + * + * @return the list of supported write speeds + */ + virtual QList writeSpeeds() const = 0; + + /** + * Ejects any disc that could be contained in this drive. + * If this drive is empty, but has a tray it'll be opened + * + * @return + */ + virtual bool eject() = 0; + + protected: + //Q_SIGNALS: + /** + * This signal is emitted when the eject button is pressed + * on the drive. + * + * Please note that some (broken) drives doesn't report this event. + * @param udi the UDI of the drive + */ + virtual void ejectPressed(const QString &udi) = 0; + + virtual void ejectDone(Solid::ErrorType error, QVariant errorData, const QString &udi) = 0; + }; +} +} + +Q_DECLARE_INTERFACE(Solid::Ifaces::OpticalDrive, "org.kde.Solid.Ifaces.OpticalDrive/0.1") + +#endif // SOLID_IFACE_OPTICALDRIVE_H diff --git a/solid-lite/ifaces/portablemediaplayer.cpp b/solid-lite/ifaces/portablemediaplayer.cpp new file mode 100644 index 000000000..8de44cdb2 --- /dev/null +++ b/solid-lite/ifaces/portablemediaplayer.cpp @@ -0,0 +1,26 @@ +/* + Copyright 2006 Davide Bettio + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "portablemediaplayer.h" + +Solid::Ifaces::PortableMediaPlayer::~PortableMediaPlayer() +{ + +} diff --git a/solid-lite/ifaces/portablemediaplayer.h b/solid-lite/ifaces/portablemediaplayer.h new file mode 100644 index 000000000..69d11fe49 --- /dev/null +++ b/solid-lite/ifaces/portablemediaplayer.h @@ -0,0 +1,94 @@ +/* + Copyright 2006 Davide Bettio + Copyright 2007 Jeff Mitchell + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_PORTABLEMEDIAPLAYER_H +#define SOLID_IFACES_PORTABLEMEDIAPLAYER_H + +#include +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * This class implements Portable Media Player device interface and represents + * a portable media player attached to the system. + * A portable media player is a portable device able to play multimedia files. + * Some of them have even recording capabilities. + * @author Davide Bettio + */ + class PortableMediaPlayer : virtual public DeviceInterface + { + public: + /** + * Destroys a portable media player object. + */ + virtual ~PortableMediaPlayer(); + + /** + * Retrieves known protocols this device can speak. This list may be dependent + * on installed device driver libraries. + * + * Possible protocols: + * * storage - filesystem-based device: can browse and play media files stored + * on its volume. iPod-like devices can have both storage and ipod protocol + * set, you should use more specific (ipod) protocol in this case. + * * ipod - iPod-like device where media files are stored on filesystem, but these need + * an entry in device database in order to be playable. + * * mtp - Media Transfer Protocol-compatible devices. + * + * @return a list of known protocols this device can speak + */ + virtual QStringList supportedProtocols() const = 0; + + /** + * Retrieves known installed device drivers that claim to handle this device + * using the requested protocol. + * + * Possible drivers: + * * usb - device is talked to using USB. This driver alone does not specify which + * particular USB service/protocol should be used. + * * usbmux - device supports AFC (Apple File Connection) and usbmuxd daemon is ready + * on /var/run/usbmuxd socket on UNIX and localhost:27015 port on Windows. + * + * @param protocol The protocol to get drivers for. Specify empty protocol to get + * drivers for all possible protocols. + * @return a list of known device drivers that can handle this device + */ + virtual QStringList supportedDrivers(QString protocol = QString()) const = 0; + + /** + * Retrieves a driver specific string allowing to access the device. + * + * For example for the "mtp" driver it will return the serial number + * of the device and "usbmux" driver will return 40-digit device UUID + * + * @return the driver specific data + */ + virtual QVariant driverHandle(const QString &driver) const = 0; + }; +} +} + +Q_DECLARE_INTERFACE(Solid::Ifaces::PortableMediaPlayer, "org.kde.Solid.Ifaces.PortableMediaPlayer/0.1") + +#endif diff --git a/solid-lite/ifaces/storageaccess.cpp b/solid-lite/ifaces/storageaccess.cpp new file mode 100644 index 000000000..de8565d09 --- /dev/null +++ b/solid-lite/ifaces/storageaccess.cpp @@ -0,0 +1,26 @@ +/* + Copyright 2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "storageaccess.h" + +Solid::Ifaces::StorageAccess::~StorageAccess() +{ +} + diff --git a/solid-lite/ifaces/storageaccess.h b/solid-lite/ifaces/storageaccess.h new file mode 100644 index 000000000..567511f28 --- /dev/null +++ b/solid-lite/ifaces/storageaccess.h @@ -0,0 +1,138 @@ +/* + Copyright 2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_STORAGEACCESS_H +#define SOLID_IFACES_STORAGEACCESS_H + +#include +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * This device interface is available on volume devices. + * + * A volume is anything that can contain data (partition, optical disc, + * memory card). It's a particular kind of block device. + */ + class StorageAccess : virtual public DeviceInterface + { + public: + /** + * Destroys a StorageVolume object. + */ + virtual ~StorageAccess(); + + + /** + * Indicates if this volume is mounted. + * + * @return true if the volume is mounted + */ + virtual bool isAccessible() const = 0; + + /** + * Retrieves the absolute path of this volume mountpoint. + * + * @return the absolute path to the mount point if the volume is + * mounted, QString() otherwise + */ + virtual QString filePath() const = 0; + + /** + * Indicates if this volume should be ignored by applications. + * + * If it should be ignored, it generally means that it should be + * invisible to the user. It's useful for firmware partitions or + * OS reinstall partitions on some systems. + * + * @return true if the volume should be ignored + */ + virtual bool isIgnored() const = 0; + + /** + * Mounts the volume. + * + * @return the job handling the operation + */ + virtual bool setup() = 0; + + /** + * Unmounts the volume. + * + * @return the job handling the operation + */ + virtual bool teardown() = 0; + + protected: + //Q_SIGNALS: + /** + * This signal is emitted when the mount state of this device + * has changed. + * + * @param newState true if the volume is mounted, false otherwise + * @param udi the UDI of the volume + */ + virtual void accessibilityChanged(bool accessible, const QString &udi) = 0; + + /** + * This signal is emitted when the mount state of this device + * has changed. + * + * @param newState true if the volume is mounted, false otherwise + * @param udi the UDI of the volume + */ + virtual void setupDone(Solid::ErrorType error, QVariant resultData, const QString &udi) = 0; + + /** + * This signal is emitted when the mount state of this device + * has changed. + * + * @param newState true if the volume is mounted, false otherwise + * @param udi the UDI of the volume + */ + virtual void teardownDone(Solid::ErrorType error, QVariant resultData, const QString &udi) = 0; + + /** + * This signal is emitted when a setup of this device is requested. + * The signal might be spontaneous i.e. it can be triggered by + * another process. + * + * @param udi the UDI of the volume + */ + virtual void setupRequested(const QString &udi) = 0; + + /** + * This signal is emitted when a teardown of this device is requested. + * The signal might be spontaneous i.e. it can be triggered by + * another process + * + * @param udi the UDI of the volume + */ + virtual void teardownRequested(const QString &udi) = 0; + }; +} +} + +Q_DECLARE_INTERFACE(Solid::Ifaces::StorageAccess, "org.kde.Solid.Ifaces.StorageAccess/0.1") + +#endif diff --git a/solid-lite/ifaces/storagedrive.cpp b/solid-lite/ifaces/storagedrive.cpp new file mode 100644 index 000000000..4b037d5f0 --- /dev/null +++ b/solid-lite/ifaces/storagedrive.cpp @@ -0,0 +1,26 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "storagedrive.h" + +Solid::Ifaces::StorageDrive::~StorageDrive() +{ +} + diff --git a/solid-lite/ifaces/storagedrive.h b/solid-lite/ifaces/storagedrive.h new file mode 100644 index 000000000..8e3ff1e71 --- /dev/null +++ b/solid-lite/ifaces/storagedrive.h @@ -0,0 +1,94 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_STORAGEDRIVE_H +#define SOLID_IFACES_STORAGEDRIVE_H + +#include +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * This device interface is available on storage devices. + * + * A storage is anything that can contain a set of volumes (card reader, + * hard disk, cdrom drive...). It's a particular kind of block device. + */ + class StorageDrive : virtual public Block + { + public: + /** + * Destroys a StorageDrive object. + */ + virtual ~StorageDrive(); + + + /** + * Retrieves the type of physical interface this storage device is + * connected to. + * + * @return the bus type + * @see Solid::StorageDrive::Bus + */ + virtual Solid::StorageDrive::Bus bus() const = 0; + + /** + * Retrieves the type of this storage drive. + * + * @return the drive type + * @see Solid::StorageDrive::DriveType + */ + virtual Solid::StorageDrive::DriveType driveType() const = 0; + + + /** + * Indicates if the media contained by this drive can be removed. + * + * For example memory card can be removed from the drive by the user, + * while partitions can't be removed from hard disks. + * + * @return true if media can be removed, false otherwise. + */ + virtual bool isRemovable() const = 0; + + /** + * Indicates if this storage device can be plugged or unplugged while + * the computer is running. + * + * @return true if this storage supports hotplug, false otherwise + */ + virtual bool isHotpluggable() const = 0; + + /** + * Retrieves this drives size in bytes. + * + * @return the size of this drive + */ + virtual qulonglong size() const = 0; + }; +} +} + +Q_DECLARE_INTERFACE(Solid::Ifaces::StorageDrive, "org.kde.Solid.Ifaces.StorageDrive/0.1") + +#endif // SOLID_IFACES_STORAGEDRIVE_H diff --git a/solid-lite/ifaces/storagevolume.cpp b/solid-lite/ifaces/storagevolume.cpp new file mode 100644 index 000000000..7e8b744bb --- /dev/null +++ b/solid-lite/ifaces/storagevolume.cpp @@ -0,0 +1,26 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "storagevolume.h" + +Solid::Ifaces::StorageVolume::~StorageVolume() +{ +} + diff --git a/solid-lite/ifaces/storagevolume.h b/solid-lite/ifaces/storagevolume.h new file mode 100644 index 000000000..4fbb20477 --- /dev/null +++ b/solid-lite/ifaces/storagevolume.h @@ -0,0 +1,111 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_IFACES_STORAGEVOLUME_H +#define SOLID_IFACES_STORAGEVOLUME_H + +#include +#include + +namespace Solid +{ +namespace Ifaces +{ + /** + * This device interface is available on volume devices. + * + * A volume is anything that can contain data (partition, optical disc, + * memory card). It's a particular kind of block device. + */ + class StorageVolume : virtual public Block + { + public: + /** + * Destroys a StorageVolume object. + */ + virtual ~StorageVolume(); + + + /** + * Indicates if this volume should be ignored by applications. + * + * If it should be ignored, it generally means that it should be + * invisible to the user. It's useful for firmware partitions or + * OS reinstall partitions on some systems. + * + * @return true if the volume should be ignored + */ + virtual bool isIgnored() const = 0; + + /** + * Retrieves the type of use for this volume (for example filesystem). + * + * @return the usage type + * @see Solid::StorageVolume::UsageType + */ + virtual Solid::StorageVolume::UsageType usage() const = 0; + + /** + * Retrieves the filesystem type of this volume. + * + * @return the filesystem type if applicable, QString() otherwise + */ + virtual QString fsType() const = 0; + + /** + * Retrieves this volume label. + * + * @return the volume lavel if available, QString() otherwise + */ + virtual QString label() const = 0; + + /** + * Retrieves this volume Universal Unique IDentifier (UUID). + * + * You can generally assume that this identifier is unique with reasonable + * confidence. Except if the volume UUID has been forged to intentionally + * provoke a collision, the probability to have two volumes having the same + * UUID is low. + * + * @return the Universal Unique IDentifier if available, QString() otherwise + */ + virtual QString uuid() const = 0; + + /** + * Retrieves this volume size in bytes. + * + * @return the size of this volume + */ + virtual qulonglong size() const = 0; + + /** + * Retrieves the crypto container UDI of this volume. + * + * @return the encrypted volume UDI containing the current volume if appliable, + * an empty string otherwise + */ + virtual QString encryptedContainerUdi() const = 0; + }; +} +} + +Q_DECLARE_INTERFACE(Solid::Ifaces::StorageVolume, "org.kde.Solid.Ifaces.StorageVolume/0.1") + +#endif // SOLID_IFACES_STORAGEVOLUME_H diff --git a/solid-lite/managerbase.cpp b/solid-lite/managerbase.cpp new file mode 100644 index 000000000..098599bec --- /dev/null +++ b/solid-lite/managerbase.cpp @@ -0,0 +1,103 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "managerbase_p.h" + +#include +#if !defined (Q_WS_WIN) && !defined (Q_OS_MAC) +#include +#endif + +//#include "backends/fakehw/fakemanager.h" + +#if defined (Q_OS_MAC) +#include "backends/iokit/iokitmanager.h" +#elif defined (Q_OS_UNIX) +#include "backends/hal/halmanager.h" +#include "backends/udisks/udisksmanager.h" +//#include "backends/upower/upowermanager.h" + +#if defined (HUPNP_FOUND) +#include "backends/upnp/upnpdevicemanager.h" +#endif + +#if defined (UDEV_FOUND) +#include "backends/udev/udevmanager.h" +#endif + +//#include "backends/fstab/fstabmanager.h" + +#elif defined (Q_WS_WIN) && defined(HAVE_WBEM) && !defined(_WIN32_WCE) +#include "backends/wmi/wmimanager.h" +#endif + + +Solid::ManagerBasePrivate::ManagerBasePrivate() +{ +} + +Solid::ManagerBasePrivate::~ManagerBasePrivate() +{ + qDeleteAll(m_backends); +} + +void Solid::ManagerBasePrivate::loadBackends() +{ + /*QString solidFakeXml(QString::fromLocal8Bit(qgetenv("SOLID_FAKEHW"))); + + if (!solidFakeXml.isEmpty()) { + m_backends << new Solid::Backends::Fake::FakeManager(0, solidFakeXml); + } else*/ { +# if defined(Q_OS_MAC) + m_backends << new Solid::Backends::IOKit::IOKitManager(0); + +# elif defined(Q_WS_WIN) && defined(HAVE_WBEM) && !defined(_WIN32_WCE) + m_backends << new Solid::Backends::Wmi::WmiManager(0); + +# elif defined(Q_OS_UNIX) && !defined(Q_OS_LINUX) + m_backends << new Solid::Backends::Hal::HalManager(0); + +# elif defined(Q_OS_LINUX) + bool solidHalLegacyEnabled + = QString::fromLocal8Bit(qgetenv("SOLID_HAL_LEGACY")).toInt()==1; + if (solidHalLegacyEnabled) { + m_backends << new Solid::Backends::Hal::HalManager(0); + } else { +# if defined(UDEV_FOUND) + m_backends << new Solid::Backends::UDev::UDevManager(0); +# endif + m_backends << new Solid::Backends::UDisks::UDisksManager(0) + /*<< new Solid::Backends::UPower::UPowerManager(0) + << new Solid::Backends::Fstab::FstabManager(0)*/; + } +# endif + +//# if defined (HUPNP_FOUND) +// m_backends << new Solid::Backends::UPnP::UPnPDeviceManager(0); +//# endif + } +} + +QList Solid::ManagerBasePrivate::managerBackends() const +{ + return m_backends; +} + + diff --git a/solid-lite/managerbase_p.h b/solid-lite/managerbase_p.h new file mode 100644 index 000000000..740e3e260 --- /dev/null +++ b/solid-lite/managerbase_p.h @@ -0,0 +1,45 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_MANAGERBASE_P_H +#define SOLID_MANAGERBASE_P_H + +#include +#include + +#include "solid-lite/solid_export.h" + +namespace Solid +{ + class ManagerBasePrivate + { + public: + ManagerBasePrivate(); + virtual ~ManagerBasePrivate(); + void loadBackends(); + + QList managerBackends() const; + + private: + QList m_backends; + }; +} + +#endif diff --git a/solid-lite/opticaldisc.cpp b/solid-lite/opticaldisc.cpp new file mode 100644 index 000000000..94bc3f583 --- /dev/null +++ b/solid-lite/opticaldisc.cpp @@ -0,0 +1,73 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "opticaldisc.h" +#include "opticaldisc_p.h" + +#include "soliddefs_p.h" +#include + +Solid::OpticalDisc::OpticalDisc(QObject *backendObject) + : StorageVolume(*new OpticalDiscPrivate(), backendObject) +{ +} + +Solid::OpticalDisc::~OpticalDisc() +{ + +} + +Solid::OpticalDisc::ContentTypes Solid::OpticalDisc::availableContent() const +{ + Q_D(const OpticalDisc); + return_SOLID_CALL(Ifaces::OpticalDisc *, d->backendObject(), ContentTypes(), availableContent()); +} + +Solid::OpticalDisc::DiscType Solid::OpticalDisc::discType() const +{ + Q_D(const OpticalDisc); + return_SOLID_CALL(Ifaces::OpticalDisc *, d->backendObject(), UnknownDiscType, discType()); +} + +bool Solid::OpticalDisc::isAppendable() const +{ + Q_D(const OpticalDisc); + return_SOLID_CALL(Ifaces::OpticalDisc *, d->backendObject(), false, isAppendable()); +} + +bool Solid::OpticalDisc::isBlank() const +{ + Q_D(const OpticalDisc); + return_SOLID_CALL(Ifaces::OpticalDisc *, d->backendObject(), false, isBlank()); +} + +bool Solid::OpticalDisc::isRewritable() const +{ + Q_D(const OpticalDisc); + return_SOLID_CALL(Ifaces::OpticalDisc *, d->backendObject(), false, isRewritable()); +} + +qulonglong Solid::OpticalDisc::capacity() const +{ + Q_D(const OpticalDisc); + return_SOLID_CALL(Ifaces::OpticalDisc *, d->backendObject(), 0, capacity()); +} + +//#include "opticaldisc.moc" diff --git a/solid-lite/opticaldisc.h b/solid-lite/opticaldisc.h new file mode 100644 index 000000000..b6bf30c1d --- /dev/null +++ b/solid-lite/opticaldisc.h @@ -0,0 +1,186 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_OPTICALDISC_H +#define SOLID_OPTICALDISC_H + +#include + +#include + +namespace Solid +{ + class OpticalDiscPrivate; + class Device; + + /** + * This device interface is available on optical discs. + * + * An optical disc is a volume that can be inserted in CD-R*,DVD*,Blu-Ray,HD-DVD drives. + */ + class SOLID_EXPORT OpticalDisc : public StorageVolume + { + Q_OBJECT + Q_ENUMS(ContentType DiscType) + Q_FLAGS(ContentTypes) + Q_PROPERTY(ContentTypes availableContent READ availableContent) + Q_PROPERTY(DiscType discType READ discType) + Q_PROPERTY(bool appendable READ isAppendable) + Q_PROPERTY(bool blank READ isBlank) + Q_PROPERTY(bool rewritable READ isRewritable) + Q_PROPERTY(qulonglong capacity READ capacity) + Q_DECLARE_PRIVATE(OpticalDisc) + friend class Device; + + public: + /** + * This enum type defines the type of content available in an optical disc. + * + * - Audio : A disc containing audio + * - Data : A disc containing data + * - VideoCd : A Video Compact Disc (VCD) + * - SuperVideoCd : A Super Video Compact Disc (SVCD) + * - VideoDvd : A Video Digital Versatile Disc (DVD-Video) + */ + enum ContentType { + NoContent = 0x00, + Audio = 0x01, + Data = 0x02, + VideoCd = 0x04, + SuperVideoCd = 0x08, + VideoDvd = 0x10, + VideoBluRay = 0x20 + }; + + /** + * This type stores an OR combination of ContentType values. + */ + Q_DECLARE_FLAGS(ContentTypes, ContentType) + + /** + * This enum type defines the type of optical disc it can be. + * + * - UnknownDiscType : An undetermined disc type + * - CdRom : A Compact Disc Read-Only Memory (CD-ROM) + * - CdRecordable : A Compact Disc Recordable (CD-R) + * - CdRewritable : A Compact Disc ReWritable (CD-RW) + * - DvdRom : A Digital Versatile Disc Read-Only Memory (DVD-ROM) + * - DvdRam : A Digital Versatile Disc Random Access Memory (DVD-RAM) + * - DvdRecordable : A Digital Versatile Disc Recordable (DVD-R) + * - DvdRewritable : A Digital Versatile Disc ReWritable (DVD-RW) + * - DvdPlusRecordable : A Digital Versatile Disc Recordable (DVD+R) + * - DvdPlusRewritable : A Digital Versatile Disc ReWritable (DVD+RW) + * - DvdPlusRecordableDuallayer : A Digital Versatile Disc Recordable Dual-Layer (DVD+R DL) + * - DvdPlusRewritableDuallayer : A Digital Versatile Disc ReWritable Dual-Layer (DVD+RW DL) + * - BluRayRom : A Blu-ray Disc (BD) + * - BluRayRecordable : A Blu-ray Disc Recordable (BD-R) + * - BluRayRewritable : A Blu-ray Disc (BD-RE) + * - HdDvdRom: A High Density Digital Versatile Disc (HD DVD) + * - HdDvdRecordable : A High Density Digital Versatile Disc Recordable (HD DVD-R) + * - HdDvdRewritable : A High Density Digital Versatile Disc ReWritable (HD DVD-RW) + */ + enum DiscType { UnknownDiscType = -1, + CdRom, CdRecordable, CdRewritable, DvdRom, DvdRam, + DvdRecordable, DvdRewritable, + DvdPlusRecordable, DvdPlusRewritable, + DvdPlusRecordableDuallayer, DvdPlusRewritableDuallayer, + BluRayRom, BluRayRecordable, BluRayRewritable, + HdDvdRom, HdDvdRecordable, HdDvdRewritable }; + + + private: + /** + * Creates a new OpticalDisc object. + * You generally won't need this. It's created when necessary using + * Device::as(). + * + * @param backendObject the device interface object provided by the backend + * @see Solid::Device::as() + */ + explicit OpticalDisc(QObject *backendObject); + + public: + /** + * Destroys an OpticalDisc object. + */ + virtual ~OpticalDisc(); + + + /** + * Get the Solid::DeviceInterface::Type of the OpticalDisc device interface. + * + * @return the OpticalDisc device interface type + * @see Solid::Ifaces::Enums::DeviceInterface::Type + */ + static Type deviceInterfaceType() { return DeviceInterface::OpticalDisc; } + + + /** + * Retrieves the content types this disc contains (audio, video, + * data...). + * + * @return the flag set indicating the available contents + * @see Solid::OpticalDisc::ContentType + */ + ContentTypes availableContent() const; + + /** + * Retrieves the disc type (cdr, cdrw...). + * + * @return the disc type + */ + DiscType discType() const; + + /** + * Indicates if it's possible to write additional data to the disc. + * + * @return true if the disc is appendable, false otherwise + */ + bool isAppendable() const; + + /** + * Indicates if the disc is blank. + * + * @return true if the disc is blank, false otherwise + */ + bool isBlank() const; + + /** + * Indicates if the disc is rewritable. + * + * A disc is rewritable if you can write on it several times. + * + * @return true if the disc is rewritable, false otherwise + */ + bool isRewritable() const; + + /** + * Retrieves the disc capacity (that is the maximum size of a + * volume could have on this disc). + * + * @return the capacity of the disc in bytes + */ + qulonglong capacity() const; + }; +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(Solid::OpticalDisc::ContentTypes) + +#endif diff --git a/solid-lite/opticaldisc_p.h b/solid-lite/opticaldisc_p.h new file mode 100644 index 000000000..b5da48a56 --- /dev/null +++ b/solid-lite/opticaldisc_p.h @@ -0,0 +1,36 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_OPTICALDISC_P_H +#define SOLID_OPTICALDISC_P_H + +#include "storagevolume_p.h" + +namespace Solid +{ + class OpticalDiscPrivate : public StorageVolumePrivate + { + public: + OpticalDiscPrivate() + : StorageVolumePrivate() { } + }; +} + +#endif diff --git a/solid-lite/opticaldrive.cpp b/solid-lite/opticaldrive.cpp new file mode 100644 index 000000000..60967f2f2 --- /dev/null +++ b/solid-lite/opticaldrive.cpp @@ -0,0 +1,73 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "opticaldrive.h" +#include "opticaldrive_p.h" + +#include "soliddefs_p.h" +#include + +Solid::OpticalDrive::OpticalDrive(QObject *backendObject) + : StorageDrive(*new OpticalDrivePrivate(), backendObject) +{ + connect(backendObject, SIGNAL(ejectPressed(QString)), + this, SIGNAL(ejectPressed(QString))); + connect(backendObject, SIGNAL(ejectDone(Solid::ErrorType,QVariant,QString)), + this, SIGNAL(ejectDone(Solid::ErrorType,QVariant,QString))); + connect(backendObject, SIGNAL(ejectRequested(QString)), + this, SIGNAL(ejectRequested(QString))); +} + +Solid::OpticalDrive::~OpticalDrive() +{ + +} + +Solid::OpticalDrive::MediumTypes Solid::OpticalDrive::supportedMedia() const +{ + Q_D(const OpticalDrive); + return_SOLID_CALL(Ifaces::OpticalDrive *, d->backendObject(), MediumTypes(), supportedMedia()); +} + +int Solid::OpticalDrive::readSpeed() const +{ + Q_D(const OpticalDrive); + return_SOLID_CALL(Ifaces::OpticalDrive *, d->backendObject(), 0, readSpeed()); +} + +int Solid::OpticalDrive::writeSpeed() const +{ + Q_D(const OpticalDrive); + return_SOLID_CALL(Ifaces::OpticalDrive *, d->backendObject(), 0, writeSpeed()); +} + +QList Solid::OpticalDrive::writeSpeeds() const +{ + Q_D(const OpticalDrive); + return_SOLID_CALL(Ifaces::OpticalDrive *, d->backendObject(), QList(), writeSpeeds()); +} + +bool Solid::OpticalDrive::eject() +{ + Q_D(OpticalDrive); + return_SOLID_CALL(Ifaces::OpticalDrive *, d->backendObject(), false, eject()); +} + +//#include "opticaldrive.moc" diff --git a/solid-lite/opticaldrive.h b/solid-lite/opticaldrive.h new file mode 100644 index 000000000..26dd02741 --- /dev/null +++ b/solid-lite/opticaldrive.h @@ -0,0 +1,186 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_OPTICALDRIVE_H +#define SOLID_OPTICALDRIVE_H + +#include +#include + +#include +#include + +#include + +namespace Solid +{ + class OpticalDrivePrivate; + class Device; + + /** + * This device interface is available on CD-R*,DVD*,Blu-Ray,HD-DVD drives. + * + * An OpticalDrive is a storage that can handle optical discs. + */ + class SOLID_EXPORT OpticalDrive : public StorageDrive + { + Q_OBJECT + Q_ENUMS(MediumType) + Q_FLAGS(MediumTypes) + Q_PROPERTY(MediumTypes supportedMedia READ supportedMedia) + Q_PROPERTY(int readSpeed READ readSpeed) + Q_PROPERTY(int writeSpeed READ writeSpeed) + Q_PROPERTY(QList writeSpeeds READ writeSpeeds) + Q_DECLARE_PRIVATE(OpticalDrive) + friend class Device; + + public: + /** + * This enum type defines the type of medium an optical drive supports. + * + * - Cdr : A Recordable Compact Disc (CD-R) + * - Cdrw : A ReWritable Compact Disc (CD-RW) + * - Dvd : A Digital Versatile Disc (DVD) + * - Dvdr : A Recordable Digital Versatile Disc (DVD-R) + * - Dvdrw : A ReWritable Digital Versatile Disc (DVD-RW) + * - Dvdram : A Random Access Memory Digital Versatile Disc (DVD-RAM) + * - Dvdplusr : A Recordable Digital Versatile Disc (DVD+R) + * - Dvdplusrw : A ReWritable Digital Versatile Disc (DVD+RW) + * - Dvdplusdl : A Dual Layer Digital Versatile Disc (DVD+R DL) + * - Dvdplusdlrw : A Dual Layer Digital Versatile Disc (DVD+RW DL) + * - Bd : A Blu-ray Disc (BD) + * - Bdr : A Blu-ray Disc Recordable (BD-R) + * - Bdre : A Blu-ray Disc Recordable and Eraseable (BD-RE) + * - HdDvd : A High Density Digital Versatile Disc (HD DVD) + * - HdDvdr : A High Density Digital Versatile Disc Recordable (HD DVD-R) + * - HdDvdrw : A High Density Digital Versatile Disc ReWritable (HD DVD-RW) + */ + enum MediumType { Cdr=0x00001, Cdrw=0x00002, Dvd=0x00004, Dvdr=0x00008, + Dvdrw=0x00010, Dvdram=0x00020, Dvdplusr=0x00040, + Dvdplusrw=0x00080, Dvdplusdl=0x00100, Dvdplusdlrw=0x00200, + Bd=0x00400, Bdr=0x00800, Bdre=0x01000, + HdDvd=0x02000, HdDvdr=0x04000, HdDvdrw=0x08000 }; + + /** + * This type stores an OR combination of MediumType values. + */ + Q_DECLARE_FLAGS(MediumTypes, MediumType) + + + private: + /** + * Creates a new OpticalDrive object. + * You generally won't need this. It's created when necessary using + * Device::as(). + * + * @param backendObject the device interface object provided by the backend + * @see Solid::Device::as() + */ + explicit OpticalDrive(QObject *backendObject); + + public: + /** + * Destroys an OpticalDrive object. + */ + virtual ~OpticalDrive(); + + + /** + * Get the Solid::DeviceInterface::Type of the OpticalDrive device interface. + * + * @return the OpticalDrive device interface type + * @see Solid::Ifaces::Enums::DeviceInterface::Type + */ + static Type deviceInterfaceType() { return DeviceInterface::OpticalDrive; } + + + /** + * Retrieves the medium types this drive supports. + * + * @return the flag set indicating the supported medium types + */ + MediumTypes supportedMedia() const; + + /** + * Retrieves the maximum read speed of this drive in kilobytes per second. + * + * @return the maximum read speed + */ + int readSpeed() const; + + /** + * Retrieves the maximum write speed of this drive in kilobytes per second. + * + * @return the maximum write speed + */ + int writeSpeed() const; + + /** + * Retrieves the list of supported write speeds of this drive in + * kilobytes per second. + * + * @return the list of supported write speeds + */ + QList writeSpeeds() const; + + /** + * Ejects any disc that could be contained in this drive. + * If this drive is empty, but has a tray it'll be opened. + * + * @return the status of the eject operation + */ + bool eject(); + + Q_SIGNALS: + /** + * This signal is emitted when the eject button is pressed + * on the drive. + * + * Please note that some (broken) drives doesn't report this event. + * @param udi the UDI of the drive + */ + void ejectPressed(const QString &udi); + + /** + * This signal is emitted when the attempted eject process on this + * drive is completed. The signal might be spontaneous, i.e. + * it can be triggered by another process. + * + * @param error type of error that occurred, if any + * @param errorData more information about the error, if any + * @param udi the UDI of the volume + */ + void ejectDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + + /** + * This signal is emitted when eject on this drive is + * requested. The signal might be spontaneous, i.e. it + * can be triggered by another process. + * + * @param udi the UDI of the volume + */ + void ejectRequested(const QString &udi); + + }; +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(Solid::OpticalDrive::MediumTypes) + +#endif // SOLID_OPTICALDRIVE_H diff --git a/solid-lite/opticaldrive_p.h b/solid-lite/opticaldrive_p.h new file mode 100644 index 000000000..09a6d241d --- /dev/null +++ b/solid-lite/opticaldrive_p.h @@ -0,0 +1,36 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_OPTICALDRIVE_P_H +#define SOLID_OPTICALDRIVE_P_H + +#include "storagedrive_p.h" + +namespace Solid +{ + class OpticalDrivePrivate : public StorageDrivePrivate + { + public: + OpticalDrivePrivate() + : StorageDrivePrivate() { } + }; +} + +#endif // SOLID_OPTICALDRIVE_P_H diff --git a/solid-lite/portablemediaplayer.cpp b/solid-lite/portablemediaplayer.cpp new file mode 100644 index 000000000..b7e42d88d --- /dev/null +++ b/solid-lite/portablemediaplayer.cpp @@ -0,0 +1,57 @@ +/* + Copyright 2006 Davide Bettio + Copyright 2007 Kevin Ottens + Copyright 2007 Jeff Mitchell + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "portablemediaplayer.h" +#include "portablemediaplayer_p.h" + +#include "soliddefs_p.h" +#include + +Solid::PortableMediaPlayer::PortableMediaPlayer(QObject *backendObject) + : DeviceInterface(*new PortableMediaPlayerPrivate(), backendObject) +{ +} + +Solid::PortableMediaPlayer::~PortableMediaPlayer() +{ + +} + +QStringList Solid::PortableMediaPlayer::supportedProtocols() const +{ + Q_D(const PortableMediaPlayer); + return_SOLID_CALL(Ifaces::PortableMediaPlayer *, d->backendObject(), QStringList(), supportedProtocols()); +} + +QStringList Solid::PortableMediaPlayer::supportedDrivers(QString protocol) const +{ + Q_D(const PortableMediaPlayer); + return_SOLID_CALL(Ifaces::PortableMediaPlayer *, d->backendObject(), QStringList(), supportedDrivers(protocol)); +} + +QVariant Solid::PortableMediaPlayer::driverHandle(const QString &driver) const +{ + Q_D(const PortableMediaPlayer); + return_SOLID_CALL(Ifaces::PortableMediaPlayer *, d->backendObject(), QVariant(), driverHandle(driver)); +} + +//#include "portablemediaplayer.moc" diff --git a/solid-lite/portablemediaplayer.h b/solid-lite/portablemediaplayer.h new file mode 100644 index 000000000..360dee48b --- /dev/null +++ b/solid-lite/portablemediaplayer.h @@ -0,0 +1,110 @@ +/* + Copyright 2006 Davide Bettio + Copyright 2007 Kevin Ottens + Copyright 2007 Jeff Mitchell + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_PORTABLEMEDIAPLAYER_H +#define SOLID_PORTABLEMEDIAPLAYER_H + +#include +#include + +#include + +#include + +namespace Solid +{ + class PortableMediaPlayerPrivate; + class Device; + + /** + * This class implements Portable Media Player device interface and represents + * a portable media player attached to the system. + * A portable media player is a portable device able to play multimedia files. + * Some of them have even recording capabilities. + * @author Davide Bettio + */ + class SOLID_EXPORT PortableMediaPlayer : public DeviceInterface + { + Q_OBJECT + Q_PROPERTY(QStringList supportedProtocols READ supportedProtocols) + Q_PROPERTY(QStringList supportedDrivers READ supportedDrivers) + Q_DECLARE_PRIVATE(PortableMediaPlayer) + friend class Device; + + public: + + private: + /** + * Creates a new PortableMediaPlayer object. + * You generally won't need this. It's created when necessary using + * Device::as(). + * + * @param backendObject the device interface object provided by the backend + * @see Solid::Device::as() + */ + explicit PortableMediaPlayer(QObject *backendObject); + + public: + /** + * Destroys a portable media player object. + */ + virtual ~PortableMediaPlayer(); + + /** + * Get the Solid::DeviceInterface::Type of the PortableMediaPlayer device interface. + * + * @return the PortableMediaPlayer device interface type + * @see Solid::DeviceInterface::Type + */ + static Type deviceInterfaceType() { return DeviceInterface::PortableMediaPlayer; } + + /** + * Retrieves known protocols this device can speak. This list may be dependent + * on installed device driver libraries. + * + * @return a list of known protocols this device can speak + */ + QStringList supportedProtocols() const; + + /** + * Retrieves known installed device drivers that claim to handle this device + * using the requested protocol. If protocol is blank, returns a list of + * all drivers supporting the device. + * + * @param protocol The protocol to get drivers for. + * @return a list of installed drivers meeting the criteria + */ + QStringList supportedDrivers(QString protocol = QString()) const; + + /** + * Retrieves a driver specific string allowing to access the device. + * + * For example for the "mtp" driver it will return the serial number + * of the device. + * + * @return the driver specific data + */ + QVariant driverHandle(const QString &driver) const; + }; +} + +#endif diff --git a/solid-lite/portablemediaplayer_p.h b/solid-lite/portablemediaplayer_p.h new file mode 100644 index 000000000..a9776dbca --- /dev/null +++ b/solid-lite/portablemediaplayer_p.h @@ -0,0 +1,37 @@ +/* + Copyright 2006 Davide Bettio + Copyright 2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_PORTABLEMEDIAPLAYER_P_H +#define SOLID_PORTABLEMEDIAPLAYER_P_H + +#include "deviceinterface_p.h" + +namespace Solid +{ + class PortableMediaPlayerPrivate : public DeviceInterfacePrivate + { + public: + PortableMediaPlayerPrivate() + : DeviceInterfacePrivate() { } + }; +} + +#endif diff --git a/solid-lite/predicate.cpp b/solid-lite/predicate.cpp new file mode 100644 index 000000000..050acd157 --- /dev/null +++ b/solid-lite/predicate.cpp @@ -0,0 +1,376 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "predicate.h" + +#include +#include +#include +#include + +namespace Solid +{ + class Predicate::Private + { + public: + + Private() : isValid(false), type(PropertyCheck), + compOperator(Predicate::Equals), + operand1(0), operand2(0) {} + + bool isValid; + Type type; + + DeviceInterface::Type ifaceType; + QString property; + QVariant value; + Predicate::ComparisonOperator compOperator; + + Predicate *operand1; + Predicate *operand2; + }; +} + + +Solid::Predicate::Predicate() + : d(new Private()) +{ +} + +Solid::Predicate::Predicate(const Predicate &other) + : d(new Private()) +{ + *this = other; +} + +Solid::Predicate::Predicate(const DeviceInterface::Type &ifaceType, + const QString &property, const QVariant &value, + ComparisonOperator compOperator) + : d(new Private()) +{ + d->isValid = true; + d->ifaceType = ifaceType; + d->property = property; + d->value = value; + d->compOperator = compOperator; +} + +Solid::Predicate::Predicate(const QString &ifaceName, + const QString &property, const QVariant &value, + ComparisonOperator compOperator) + : d(new Private()) +{ + DeviceInterface::Type ifaceType = DeviceInterface::stringToType(ifaceName); + + if (((int)ifaceType)!=-1) + { + d->isValid = true; + d->ifaceType = ifaceType; + d->property = property; + d->value = value; + d->compOperator = compOperator; + } +} + +Solid::Predicate::Predicate(const DeviceInterface::Type &ifaceType) + : d(new Private()) +{ + d->isValid = true; + d->type = InterfaceCheck; + d->ifaceType = ifaceType; +} + +Solid::Predicate::Predicate(const QString &ifaceName) + : d(new Private()) +{ + DeviceInterface::Type ifaceType = DeviceInterface::stringToType(ifaceName); + + if (((int)ifaceType)!=-1) + { + d->isValid = true; + d->type = InterfaceCheck; + d->ifaceType = ifaceType; + } +} + +Solid::Predicate::~Predicate() +{ + if (d->type!=PropertyCheck && d->type!=InterfaceCheck) { + delete d->operand1; + delete d->operand2; + } + + delete d; +} + +Solid::Predicate &Solid::Predicate::operator=(const Predicate &other) +{ + d->isValid = other.d->isValid; + d->type = other.d->type; + + if (d->type!=PropertyCheck && d->type!=InterfaceCheck) + { + Predicate* operand1 = new Predicate(*(other.d->operand1)); + delete d->operand1; + d->operand1 = operand1; + Predicate* operand2 = new Predicate(*(other.d->operand2)); + delete d->operand2; + d->operand2 = operand2; + } + else + { + d->ifaceType = other.d->ifaceType; + d->property = other.d->property; + d->value = other.d->value; + d->compOperator = other.d->compOperator; + } + + return *this; +} + +Solid::Predicate Solid::Predicate::operator &(const Predicate &other) +{ + Predicate result; + + result.d->isValid = true; + result.d->type = Conjunction; + result.d->operand1 = new Predicate(*this); + result.d->operand2 = new Predicate(other); + + return result; +} + +Solid::Predicate &Solid::Predicate::operator &=(const Predicate &other) +{ + *this = *this & other; + return *this; +} + +Solid::Predicate Solid::Predicate::operator|(const Predicate &other) +{ + Predicate result; + + result.d->isValid = true; + result.d->type = Disjunction; + result.d->operand1 = new Predicate(*this); + result.d->operand2 = new Predicate(other); + + return result; +} + +Solid::Predicate &Solid::Predicate::operator |=(const Predicate &other) +{ + *this = *this | other; + return *this; +} + +bool Solid::Predicate::isValid() const +{ + return d->isValid; +} + +bool Solid::Predicate::matches(const Device &device) const +{ + if (!d->isValid) return false; + + switch(d->type) + { + case Disjunction: + return d->operand1->matches(device) + || d->operand2->matches(device); + case Conjunction: + return d->operand1->matches(device) + && d->operand2->matches(device); + case PropertyCheck: + { + const DeviceInterface *iface = device.asDeviceInterface(d->ifaceType); + + if (iface!=0) + { + const int index = iface->metaObject()->indexOfProperty(d->property.toLatin1()); + QMetaProperty metaProp = iface->metaObject()->property(index); + QVariant value = metaProp.isReadable() ? metaProp.read(iface) : QVariant(); + QVariant expected = d->value; + + if (metaProp.isEnumType() && expected.type()==QVariant::String) { + QMetaEnum metaEnum = metaProp.enumerator(); + int value = metaEnum.keysToValue(d->value.toString().toLatin1()); + if (value>=0) { // No value found for these keys, resetting expected to invalid + expected = value; + } else { + expected = QVariant(); + } + } + + if (d->compOperator==Mask) { + bool v_ok; + int v = value.toInt(&v_ok); + bool e_ok; + int e = expected.toInt(&e_ok); + + return (e_ok && v_ok && (v &e)); + } else { + return (value == expected); + } + } + break; + } + case InterfaceCheck: + return device.isDeviceInterface(d->ifaceType); + } + + return false; +} + +QSet Solid::Predicate::usedTypes() const +{ + QSet res; + + if (d->isValid) { + + switch(d->type) + { + case Disjunction: + case Conjunction: + res+= d->operand1->usedTypes(); + res+= d->operand2->usedTypes(); + break; + case PropertyCheck: + case InterfaceCheck: + res << d->ifaceType; + break; + } + + } + + return res; +} + + +QString Solid::Predicate::toString() const +{ + if (!d->isValid) return "False"; + + if (d->type!=PropertyCheck && d->type!=InterfaceCheck) + { + QString op = " AND "; + if (d->type==Disjunction) op = " OR "; + + return '['+d->operand1->toString()+op+d->operand2->toString()+']'; + } + else + { + QString ifaceName = DeviceInterface::typeToString(d->ifaceType); + + if (ifaceName.isEmpty()) ifaceName = "Unknown"; + + if (d->type==InterfaceCheck) { + return "IS "+ifaceName; + } + + QString value; + + switch (d->value.type()) + { + case QVariant::StringList: + { + value = '{'; + + const QStringList list = d->value.toStringList(); + + QStringList::ConstIterator it = list.begin(); + QStringList::ConstIterator end = list.end(); + + for (; it!=end; ++it) + { + value+= '\''+ *it+'\''; + + if (it+1!=end) + { + value+= ", "; + } + } + + value+= '}'; + break; + } + case QVariant::Bool: + value = (d->value.toBool()?"true":"false"); + break; + case QVariant::Int: + case QVariant::UInt: + case QVariant::LongLong: + case QVariant::ULongLong: + value = d->value.toString(); + break; + default: + value = '\''+d->value.toString()+'\''; + break; + } + + QString str_operator = "=="; + if (d->compOperator!=Equals) str_operator = " &"; + + + return ifaceName+'.'+d->property+' '+str_operator+' '+value; + } +} + +Solid::Predicate::Type Solid::Predicate::type() const +{ + return d->type; +} + +Solid::DeviceInterface::Type Solid::Predicate::interfaceType() const +{ + return d->ifaceType; +} + +QString Solid::Predicate::propertyName() const +{ + return d->property; +} + +QVariant Solid::Predicate::matchingValue() const +{ + return d->value; +} + +Solid::Predicate::ComparisonOperator Solid::Predicate::comparisonOperator() const +{ + return d->compOperator; +} + +Solid::Predicate Solid::Predicate::firstOperand() const +{ + if( d->operand1 ) { + return *d->operand1; + } + return Predicate(); +} + +Solid::Predicate Solid::Predicate::secondOperand() const +{ + if( d->operand2 ) { + return *d->operand2; + } + return Predicate(); +} + diff --git a/solid-lite/predicate.h b/solid-lite/predicate.h new file mode 100644 index 000000000..2d5ff535c --- /dev/null +++ b/solid-lite/predicate.h @@ -0,0 +1,273 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_PREDICATE_H +#define SOLID_PREDICATE_H + +#include +#include + +#include + +#include + +namespace Solid +{ + class Device; + + /** + * This class implements predicates for devices. + * + * A predicate is a logical condition that a given device can match or not. + * It's a constraint about the value a property must have in a given device + * interface, or any combination (conjunction, disjunction) of such + * constraints. + * + * FIXME: Add an example. + */ + class SOLID_EXPORT Predicate + { + public: + /** + * The comparison operator which can be used for matching within the predicate. + * + * - Equals, the property and the value will match for strict equality + * - Mask, the property and the value will match if the bitmasking is not null + */ + enum ComparisonOperator { Equals, Mask }; + + /** + * The predicate type which controls how the predicate is handled + * + * - PropertyCheck, the predicate contains a comparison that needs to be matched using a ComparisonOperator + * - Conjunction, the two contained predicates need to be true for this predicate to be true + * - Disjunction, either of the two contained predicates may be true for this predicate to be true + * - InterfaceCheck, the device type is compared + */ + enum Type { PropertyCheck, Conjunction, Disjunction, InterfaceCheck }; + + /** + * Constructs an invalid predicate. + */ + Predicate(); + + /** + * Copy constructor. + * + * @param other the predicate to copy + */ + Predicate(const Predicate &other); + + /** + * Constructs a predicate matching the value of a property in + * a given device interface. + * + * @param ifaceType the device interface type the device must have + * @param property the property name of the device interface + * @param value the value the property must have to make the device match + * @param compOperator the operator to apply between the property and the value when matching + */ + Predicate(const DeviceInterface::Type &ifaceType, + const QString &property, const QVariant &value, + ComparisonOperator compOperator = Equals); + + /** + * Constructs a predicate matching the value of a property in + * a given device interface. + * + * @param ifaceName the name of the device interface the device must have + * @param property the property name of the device interface + * @param value the value the property must have to make the device match + * @param compOperator the operator to apply between the property and the value when matching + */ + Predicate(const QString &ifaceName, + const QString &property, const QVariant &value, + ComparisonOperator compOperator = Equals); + + /** + * Constructs a predicate matching devices being of a particular device interface + * + * @param ifaceType the device interface the device must have + */ + explicit Predicate(const DeviceInterface::Type &ifaceType); + + /** + * Constructs a predicate matching devices being of a particular device interface + * + * @param ifaceName the name of the device interface the device must have + */ + explicit Predicate(const QString &ifaceName); + + /** + * Destroys a Predicate object. + */ + ~Predicate(); + + + /** + * Assignement operator. + * + * @param other the predicate to assign + * @return this predicate after having assigned 'other' to it + */ + Predicate &operator=(const Predicate &other); + + + /** + * 'And' operator. + * + * @param other the second operand + * @return a new 'and' predicate having 'this' and 'other' as operands + */ + Predicate operator &(const Predicate &other); + + /** + * 'AndEquals' operator. + * + * @param other the second operand + * @return assigns to 'this' a new 'and' predicate having 'this' and 'other' as operands + */ + Predicate &operator &=(const Predicate &other); + + /** + * 'Or' operator. + * + * @param other the second operand + * @return a new 'or' predicate having 'this' and 'other' as operands + */ + Predicate operator|(const Predicate &other); + + /** + * 'OrEquals' operator. + * + * @param other the second operand + * @return assigns to 'this' a new 'or' predicate having 'this' and 'other' as operands + */ + Predicate &operator|=(const Predicate &other); + + /** + * Indicates if the predicate is valid. + * + * Predicate() is the only invalid predicate. + * + * @return true if the predicate is valid, false otherwise + */ + bool isValid() const; + + /** + * Checks if a device matches the predicate. + * + * @param device the device to match against the predicate + * @return true if the given device matches the predicate, false otherwise + */ + bool matches(const Device &device) const; + + /** + * Retrieves the device interface types used in this predicate. + * + * @return all the device interface types used in this predicate + */ + QSet usedTypes() const; + + /** + * Converts the predicate to its string form. + * + * @return a string representation of the predicate + */ + QString toString() const; + + /** + * Converts a string to a predicate. + * + * @param predicate the string to convert + * @return a new valid predicate if the given string is syntactically + * correct, Predicate() otherwise + */ + static Predicate fromString(const QString &predicate); + + /** + * Retrieves the predicate type, used to determine how to handle the predicate + * + * @since 4.4 + * @return the predicate type + */ + Type type() const; + + /** + * Retrieves the interface type. + * + * @note This is only valid for InterfaceCheck and PropertyCheck types + * @since 4.4 + * @return a device interface type used by the predicate + */ + DeviceInterface::Type interfaceType() const; + + /** + * Retrieves the property name used when retrieving the value to compare against + * + * @note This is only valid for the PropertyCheck type + * @since 4.4 + * @return a property name + */ + QString propertyName() const; + + /** + * Retrieves the value used when comparing a devices property to see if it matches the predicate + * + * @note This is only valid for the PropertyCheck type + * @since 4.4 + * @return the value used + */ + QVariant matchingValue() const; + + /** + * Retrieves the comparison operator used to compare a property's value + * + * @since 4.4 + * @note This is only valid for Conjunction and Disjunction types + * @return the comparison operator used + */ + ComparisonOperator comparisonOperator() const; + + /** + * A smaller, inner predicate which is the first to appear and is compared with the second one + * + * @since 4.4 + * @note This is only valid for Conjunction and Disjunction types + * @return The predicate used for the first operand + */ + Predicate firstOperand() const; + + /** + * A smaller, inner predicate which is the second to appear and is compared with the first one + * + * @since 4.4 + * @note This is only valid for Conjunction and Disjunction types + * @return The predicate used for the second operand + */ + Predicate secondOperand() const; + + private: + class Private; + Private * const d; + }; +} + +#endif diff --git a/solid-lite/predicate_lexer.c b/solid-lite/predicate_lexer.c new file mode 100644 index 000000000..1cc46d809 --- /dev/null +++ b/solid-lite/predicate_lexer.c @@ -0,0 +1,2108 @@ +#line 2 "predicate_lexer.c" + +#line 4 "predicate_lexer.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE Solidrestart(yyin ,yyscanner ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via Solidrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void Solidrestart (FILE *input_file ,yyscan_t yyscanner ); +void Solid_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE Solid_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void Solid_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void Solid_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void Solidpush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void Solidpop_buffer_state (yyscan_t yyscanner ); + +static void Solidensure_buffer_stack (yyscan_t yyscanner ); +static void Solid_load_buffer_state (yyscan_t yyscanner ); +static void Solid_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER Solid_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE Solid_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE Solid_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE Solid_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); + +void *Solidalloc (yy_size_t ,yyscan_t yyscanner ); +void *Solidrealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void Solidfree (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer Solid_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + Solidensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + Solid_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + Solidensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + Solid_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); +static int yy_get_next_buffer (yyscan_t yyscanner ); +static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yyg->yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 16 +#define YY_END_OF_BUFFER 17 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[41] = + { 0, + 0, 0, 17, 15, 14, 14, 2, 15, 13, 15, + 13, 10, 15, 12, 12, 12, 12, 12, 12, 14, + 0, 8, 9, 11, 0, 10, 1, 12, 12, 12, + 5, 4, 12, 3, 12, 12, 12, 6, 7, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 4, 5, 1, + 1, 1, 1, 6, 7, 8, 1, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, + 10, 1, 1, 1, 11, 12, 12, 13, 14, 15, + 12, 12, 16, 12, 12, 17, 12, 18, 19, 12, + 12, 20, 21, 22, 23, 12, 12, 12, 12, 12, + 24, 1, 25, 1, 1, 1, 11, 12, 12, 13, + + 14, 15, 12, 12, 16, 12, 12, 17, 12, 18, + 19, 12, 12, 20, 21, 22, 23, 12, 12, 12, + 12, 12, 26, 1, 27, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[28] = + { 0, + 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[43] = + { 0, + 0, 0, 60, 61, 26, 28, 61, 54, 61, 49, + 48, 24, 46, 37, 0, 43, 32, 32, 31, 32, + 45, 61, 40, 39, 38, 28, 61, 0, 33, 28, + 0, 0, 21, 0, 22, 28, 27, 0, 0, 61, + 37, 38 + } ; + +static yyconst flex_int16_t yy_def[43] = + { 0, + 40, 1, 40, 40, 40, 40, 40, 41, 40, 40, + 40, 40, 40, 42, 42, 42, 42, 42, 42, 40, + 41, 40, 40, 40, 40, 40, 40, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 0, + 40, 40 + } ; + +static yyconst flex_int16_t yy_nxt[89] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 15, 15, 16, 17, 15, 15, 18, 15, + 15, 19, 15, 9, 9, 9, 9, 20, 20, 20, + 20, 25, 26, 20, 20, 25, 26, 21, 21, 28, + 39, 38, 37, 36, 35, 34, 24, 24, 23, 22, + 33, 32, 31, 30, 29, 27, 24, 23, 22, 40, + 3, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40 + } ; + +static yyconst flex_int16_t yy_chk[89] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 5, 5, 6, + 6, 12, 12, 20, 20, 26, 26, 41, 41, 42, + 37, 36, 35, 33, 30, 29, 25, 24, 23, 21, + 19, 18, 17, 16, 14, 13, 11, 10, 8, 3, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "predicate_lexer.l" +#line 2 "predicate_lexer.l" +#include "predicate_parser.h" +#include "predicateparse.h" +#include +#include +#define YY_NO_UNPUT + +int Solidwrap( yyscan_t _scanner ); +void PredicateParse_initLexer( const char *_code, yyscan_t _scanner ); +char *PredicateParse_putSymbol( char *_name ); +char *PredicateParse_putString( char *_str ); +void PredicateParse_initFlex( const char *_code, yyscan_t _scanner ); + +#line 480 "predicate_lexer.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + int yy_n_chars; + int yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + YYSTYPE * yylval_r; + + }; /* end struct yyguts_t */ + +static int yy_init_globals (yyscan_t yyscanner ); + + /* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ + # define yylval yyg->yylval_r + +int Solidlex_init (yyscan_t* scanner); + +int Solidlex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int Solidlex_destroy (yyscan_t yyscanner ); + +int Solidget_debug (yyscan_t yyscanner ); + +void Solidset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE Solidget_extra (yyscan_t yyscanner ); + +void Solidset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *Solidget_in (yyscan_t yyscanner ); + +void Solidset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *Solidget_out (yyscan_t yyscanner ); + +void Solidset_out (FILE * out_str ,yyscan_t yyscanner ); + +int Solidget_leng (yyscan_t yyscanner ); + +char *Solidget_text (yyscan_t yyscanner ); + +int Solidget_lineno (yyscan_t yyscanner ); + +void Solidset_lineno (int line_number ,yyscan_t yyscanner ); + +YYSTYPE * Solidget_lval (yyscan_t yyscanner ); + +void Solidset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int Solidwrap (yyscan_t yyscanner ); +#else +extern int Solidwrap (yyscan_t yyscanner ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner ); +#else +static int input (yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int Solidlex \ + (YYSTYPE * yylval_param ,yyscan_t yyscanner); + +#define YY_DECL int Solidlex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + +#line 25 "predicate_lexer.l" + + +#line 721 "predicate_lexer.c" + + yylval = yylval_param; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + Solidensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + Solid_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + Solid_load_buffer_state(yyscanner ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yyg->yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 41 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 40 ); + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 27 "predicate_lexer.l" +{ return EQ; } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 28 "predicate_lexer.l" +{ return MASK; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 30 "predicate_lexer.l" +{ return AND; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 31 "predicate_lexer.l" +{ return OR; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 32 "predicate_lexer.l" +{ return IS; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 34 "predicate_lexer.l" +{ yylval->valb = 1; return VAL_BOOL; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 35 "predicate_lexer.l" +{ yylval->valb = 0; return VAL_BOOL; } + YY_BREAK +case 8: +/* rule 8 can match eol */ +YY_RULE_SETUP +#line 37 "predicate_lexer.l" +{ yylval->name = PredicateParse_putString( yytext ); return VAL_STRING; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 39 "predicate_lexer.l" +{ yylval->vali = atoi( yytext ); return VAL_NUM; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 40 "predicate_lexer.l" +{ yylval->vali = atoi( yytext ); return VAL_NUM; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 42 "predicate_lexer.l" +{ yylval->vald = atof( yytext ); return VAL_FLOAT; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 44 "predicate_lexer.l" +{ yylval->name = PredicateParse_putSymbol( yytext ); return VAL_ID; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 46 "predicate_lexer.l" +{ yylval->name = 0; return (int)(*yytext); } + YY_BREAK +case 14: +/* rule 14 can match eol */ +YY_RULE_SETUP +#line 48 "predicate_lexer.l" +/* eat up whitespace */ + YY_BREAK +case 15: +YY_RULE_SETUP +#line 50 "predicate_lexer.l" +{ PredicateLexer_unknownToken(yytext); } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 52 "predicate_lexer.l" +ECHO; + YY_BREAK +#line 884 "predicate_lexer.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * Solidlex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( Solidwrap(yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of Solidlex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = yyg->yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + Solidrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + Solidrestart(yyin ,yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) Solidrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yyg->yy_start; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 41 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +{ + register int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + register char *yy_cp = yyg->yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 41 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 40); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) +{ + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_cp = yyg->yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yyg->yy_hold_char; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yyg->yy_n_chars + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + yyg->yytext_ptr = yy_bp; + yyg->yy_hold_char = *yy_cp; + yyg->yy_c_buf_p = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (yyscan_t yyscanner) +#else + static int input (yyscan_t yyscanner) +#endif + +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + Solidrestart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( Solidwrap(yyscanner ) ) + return EOF; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ + void Solidrestart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + Solidensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + Solid_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + Solid_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + Solid_load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ + void Solid_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * Solidpop_buffer_state(); + * Solidpush_buffer_state(new_buffer); + */ + Solidensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + Solid_load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (Solidwrap()) processing, but the only time this flag + * is looked at is after Solidwrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void Solid_load_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ + YY_BUFFER_STATE Solid_create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) Solidalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in Solid_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) Solidalloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in Solid_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + Solid_init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with Solid_create_buffer() + * @param yyscanner The scanner object. + */ + void Solid_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + Solidfree((void *) b->yy_ch_buf ,yyscanner ); + + Solidfree((void *) b ,yyscanner ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a Solidrestart() or at EOF. + */ + static void Solid_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + Solid_flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then Solid_init_buffer was _probably_ + * called from Solidrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ + void Solid_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + Solid_load_buffer_state(yyscanner ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void Solidpush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + Solidensure_buffer_stack(yyscanner); + + /* This block is copied from Solid_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from Solid_switch_to_buffer. */ + Solid_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void Solidpop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + Solid_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + Solid_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void Solidensure_buffer_stack (yyscan_t yyscanner) +{ + int num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yyg->yy_buffer_stack = (struct yy_buffer_state**)Solidalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in Solidensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)Solidrealloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in Solidensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE Solid_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) Solidalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in Solid_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + Solid_switch_to_buffer(b ,yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to Solidlex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * Solid_scan_bytes() instead. + */ +YY_BUFFER_STATE Solid_scan_string (yyconst char * yystr , yyscan_t yyscanner) +{ + + return Solid_scan_bytes(yystr,strlen(yystr) ,yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to Solidlex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE Solid_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) Solidalloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in Solid_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = Solid_scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in Solid_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yyg->yy_hold_char; \ + yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ + yyg->yy_hold_char = *yyg->yy_c_buf_p; \ + *yyg->yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE Solidget_extra (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int Solidget_lineno (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int Solidget_column (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *Solidget_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *Solidget_out (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +int Solidget_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *Solidget_text (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void Solidset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/** Set the current line number. + * @param line_number + * @param yyscanner The scanner object. + */ +void Solidset_lineno (int line_number , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "Solidset_lineno called with no buffer" , yyscanner); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void Solidset_column (int column_no , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "Solidset_column called with no buffer" , yyscanner); + + yycolumn = column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * @param yyscanner The scanner object. + * @see Solid_switch_to_buffer + */ +void Solidset_in (FILE * in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void Solidset_out (FILE * out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int Solidget_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void Solidset_debug (int bdebug , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; +} + +/* Accessor methods for yylval and yylloc */ + +YYSTYPE * Solidget_lval (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylval; +} + +void Solidset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylval = yylval_param; +} + +/* User-visible API */ + +/* Solidlex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ + +int Solidlex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) Solidalloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* Solidlex_init_extra has the same functionality as Solidlex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to Solidalloc in + * the yyextra field. + */ + +int Solidlex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + Solidset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) Solidalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + Solidset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +static int yy_init_globals (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from Solidlex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * Solidlex_init() + */ + return 0; +} + +/* Solidlex_destroy is for both reentrant and non-reentrant scanners. */ +int Solidlex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + Solid_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + Solidpop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + Solidfree(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + Solidfree(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * Solidlex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + Solidfree ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *Solidalloc (yy_size_t size , yyscan_t yyscanner) +{ + return (void *) malloc( size ); +} + +void *Solidrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void Solidfree (void * ptr , yyscan_t yyscanner) +{ + free( (char *) ptr ); /* see Solidrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 52 "predicate_lexer.l" + + + +char *PredicateParse_putSymbol( char *_name ) +{ + char *p = (char*)malloc( strlen( _name ) + 1 ); + if (p != NULL) + { + strcpy( p, _name ); + } + return p; +} + +char *PredicateParse_putString( char *_str ) +{ + int l = strlen( _str ); + char *p = (char*)malloc( l ); + char *s = _str + 1; + char *d = p; + + if (p == NULL) + return NULL; + + while ( s != _str + l - 1 ) + { + if ( *s != '\\' ) + *d++ = *s++; + else + { + s++; + if ( s != _str + l - 1 ) + { + if ( *s == '\\' ) + *d++ = '\\'; + else if ( *s == 'n' ) + *d++ = '\n'; + else if ( *s == 'r' ) + *d++ = '\r'; + else if ( *s == 't' ) + *d++ = '\t'; + s++; + } + } + } + *d = 0; + return p; +} + +void PredicateParse_initLexer( const char *_code, yyscan_t _scanner ) +{ + Solid_switch_to_buffer( Solid_scan_string( _code, _scanner ), _scanner ); +} + +int Solidwrap( yyscan_t _scanner ) +{ + struct yyguts_t *yyg = (struct yyguts_t*)_scanner; + Solid_delete_buffer( YY_CURRENT_BUFFER, _scanner ); + return 1; +} + + diff --git a/solid-lite/predicate_lexer.l b/solid-lite/predicate_lexer.l new file mode 100644 index 000000000..aa3ffd095 --- /dev/null +++ b/solid-lite/predicate_lexer.l @@ -0,0 +1,110 @@ +%{ +#include "predicate_parser.h" +#include "predicateparse.h" +#include +#include +#define YY_NO_UNPUT + +int Solidwrap( yyscan_t _scanner ); +void PredicateParse_initLexer( const char *_code, yyscan_t _scanner ); +char *PredicateParse_putSymbol( char *_name ); +char *PredicateParse_putString( char *_str ); +void PredicateParse_initFlex( const char *_code, yyscan_t _scanner ); + +%} + +%option nomain +%option never-interactive +%option noalways-interactive +%option nostack +%option reentrant +%option bison-bridge + +DIGIT [0-9] + +%% + +"==" { return EQ; } +"&" { return MASK; } + +[aA][nN][dD] { return AND; } +[oO][rR] { return OR; } +[iI][sS] { return IS; } + +[tT][rR][uU][eE] { yylval->valb = 1; return VAL_BOOL; } +[fF][aA][lL][sS][eE] { yylval->valb = 0; return VAL_BOOL; } + +"'"[^']*"'" { yylval->name = PredicateParse_putString( yytext ); return VAL_STRING; } + +"-"{DIGIT}+ { yylval->vali = atoi( yytext ); return VAL_NUM; } +{DIGIT}+ { yylval->vali = atoi( yytext ); return VAL_NUM; } + +{DIGIT}*"\."{DIGIT}+ { yylval->vald = atof( yytext ); return VAL_FLOAT; } + +[a-zA-Z][a-zA-Z0-9\-]* { yylval->name = PredicateParse_putSymbol( yytext ); return VAL_ID; } + +"{"|"}"|"["|"]"|","|"\." { yylval->name = 0; return (int)(*yytext); } + +[ \t\n]+ /* eat up whitespace */ + +. { PredicateLexer_unknownToken(yytext); } + +%% + +char *PredicateParse_putSymbol( char *_name ) +{ + char *p = (char*)malloc( strlen( _name ) + 1 ); + if (p != NULL) + { + strcpy( p, _name ); + } + return p; +} + +char *PredicateParse_putString( char *_str ) +{ + int l = strlen( _str ); + char *p = (char*)malloc( l ); + char *s = _str + 1; + char *d = p; + + if (p == NULL) + return NULL; + + while ( s != _str + l - 1 ) + { + if ( *s != '\\' ) + *d++ = *s++; + else + { + s++; + if ( s != _str + l - 1 ) + { + if ( *s == '\\' ) + *d++ = '\\'; + else if ( *s == 'n' ) + *d++ = '\n'; + else if ( *s == 'r' ) + *d++ = '\r'; + else if ( *s == 't' ) + *d++ = '\t'; + s++; + } + } + } + *d = 0; + return p; +} + +void PredicateParse_initLexer( const char *_code, yyscan_t _scanner ) +{ + Solid_switch_to_buffer( Solid_scan_string( _code, _scanner ), _scanner ); +} + +int Solidwrap( yyscan_t _scanner ) +{ + struct yyguts_t *yyg = (struct yyguts_t*)_scanner; + Solid_delete_buffer( YY_CURRENT_BUFFER, _scanner ); + return 1; +} + diff --git a/solid-lite/predicate_parser.c b/solid-lite/predicate_parser.c new file mode 100644 index 000000000..cd23f25da --- /dev/null +++ b/solid-lite/predicate_parser.c @@ -0,0 +1,1760 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse Solidparse +#define yylex Solidlex +#define yyerror Soliderror +#define yylval Solidlval +#define yychar Solidchar +#define yydebug Soliddebug +#define yynerrs Solidnerrs + + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 1 "predicate_parser.y" + +#include +#include +#include "predicate_parser.h" +#include "predicateparse.h" + +#define YYLTYPE_IS_TRIVIAL 0 +#define YYENABLE_NLS 0 +#define YYLEX_PARAM scanner +#define YYPARSE_PARAM scanner +typedef void* yyscan_t; +void Soliderror(const char *s); +int Solidlex( YYSTYPE *yylval, yyscan_t scanner ); +int Solidlex_init( yyscan_t *scanner ); +int Solidlex_destroy( yyscan_t *scanner ); +void PredicateParse_initLexer( const char *s, yyscan_t scanner ); +void PredicateParse_mainParse( const char *_code ); + + + +/* Line 189 of yacc.c */ +#line 102 "predicate_parser.tab.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + EQ = 258, + MASK = 259, + AND = 260, + OR = 261, + IS = 262, + VAL_BOOL = 263, + VAL_STRING = 264, + VAL_ID = 265, + VAL_NUM = 266, + VAL_FLOAT = 267 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 214 of yacc.c */ +#line 22 "predicate_parser.y" + + char valb; + int vali; + double vald; + char *name; + void *ptr; + + + +/* Line 214 of yacc.c */ +#line 160 "predicate_parser.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 172 "predicate_parser.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 11 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 29 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 19 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 8 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 18 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 34 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 267 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 18, 2, 15, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 13, 2, 14, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 16, 2, 17, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 9, 13, 19, 25, 28, 32, + 36, 38, 40, 42, 44, 46, 50, 51, 53 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 20, 0, -1, 21, -1, 13, 22, 14, -1, 13, + 23, 14, -1, 10, 15, 10, 3, 24, -1, 10, + 15, 10, 4, 24, -1, 7, 10, -1, 20, 6, + 20, -1, 20, 5, 20, -1, 9, -1, 8, -1, + 11, -1, 12, -1, 25, -1, 16, 26, 17, -1, + -1, 9, -1, 9, 18, 26, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 60, 60, 61, 62, 64, 65, 66, 68, 70, + 72, 73, 74, 75, 76, 78, 80, 81, 82 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "EQ", "MASK", "AND", "OR", "IS", + "VAL_BOOL", "VAL_STRING", "VAL_ID", "VAL_NUM", "VAL_FLOAT", "'['", "']'", + "'.'", "'{'", "'}'", "','", "$accept", "predicate", "predicate_atom", + "predicate_or", "predicate_and", "value", "string_list", + "string_list_rec", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 91, 93, 46, 123, 125, 44 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 19, 20, 20, 20, 21, 21, 21, 22, 23, + 24, 24, 24, 24, 24, 25, 26, 26, 26 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 3, 3, 5, 5, 2, 3, 3, + 1, 1, 1, 1, 1, 3, 0, 1, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 0, 0, 0, 2, 7, 0, 0, 0, + 0, 1, 0, 0, 0, 3, 4, 0, 0, 9, + 8, 11, 10, 12, 13, 16, 5, 14, 6, 17, + 0, 16, 15, 18 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 4, 5, 9, 10, 26, 27, 30 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -13 +static const yytype_int8 yypact[] = +{ + 5, -2, -12, 5, 16, -13, -13, 7, 1, 6, + 8, -13, 10, 5, 5, -13, -13, -7, -7, -13, + -13, -13, -13, -13, -13, 12, -13, -13, -13, 9, + 2, 12, -13, -13 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -13, -3, -13, -13, -13, 11, -13, -8 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 8, 21, 22, 7, 23, 24, 13, 14, 6, 25, + 19, 20, 1, 17, 18, 2, 11, 12, 3, 32, + 15, 29, 16, 33, 0, 0, 0, 31, 0, 28 +}; + +static const yytype_int8 yycheck[] = +{ + 3, 8, 9, 15, 11, 12, 5, 6, 10, 16, + 13, 14, 7, 3, 4, 10, 0, 10, 13, 17, + 14, 9, 14, 31, -1, -1, -1, 18, -1, 18 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 7, 10, 13, 20, 21, 10, 15, 20, 22, + 23, 0, 10, 5, 6, 14, 14, 3, 4, 20, + 20, 8, 9, 11, 12, 16, 24, 25, 24, 9, + 26, 18, 17, 26 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + case 20: /* "predicate" */ + +/* Line 1000 of yacc.c */ +#line 51 "predicate_parser.y" + { PredicateParse_destroy( (yyvaluep->ptr) ); }; + +/* Line 1000 of yacc.c */ +#line 1080 "predicate_parser.tab.c" + break; + case 21: /* "predicate_atom" */ + +/* Line 1000 of yacc.c */ +#line 52 "predicate_parser.y" + { PredicateParse_destroy( (yyvaluep->ptr) ); }; + +/* Line 1000 of yacc.c */ +#line 1089 "predicate_parser.tab.c" + break; + case 22: /* "predicate_or" */ + +/* Line 1000 of yacc.c */ +#line 53 "predicate_parser.y" + { PredicateParse_destroy( (yyvaluep->ptr) ); }; + +/* Line 1000 of yacc.c */ +#line 1098 "predicate_parser.tab.c" + break; + case 23: /* "predicate_and" */ + +/* Line 1000 of yacc.c */ +#line 54 "predicate_parser.y" + { PredicateParse_destroy( (yyvaluep->ptr) ); }; + +/* Line 1000 of yacc.c */ +#line 1107 "predicate_parser.tab.c" + break; + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: + +/* Line 1455 of yacc.c */ +#line 60 "predicate_parser.y" + { PredicateParse_setResult( (yyvsp[(1) - (1)].ptr) ); (yyval.ptr) = (yyvsp[(1) - (1)].ptr); ;} + break; + + case 3: + +/* Line 1455 of yacc.c */ +#line 61 "predicate_parser.y" + { PredicateParse_setResult( (yyvsp[(2) - (3)].ptr) ); (yyval.ptr) = (yyvsp[(2) - (3)].ptr); ;} + break; + + case 4: + +/* Line 1455 of yacc.c */ +#line 62 "predicate_parser.y" + { PredicateParse_setResult( (yyvsp[(2) - (3)].ptr) ); (yyval.ptr) = (yyvsp[(2) - (3)].ptr); ;} + break; + + case 5: + +/* Line 1455 of yacc.c */ +#line 64 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newAtom( (yyvsp[(1) - (5)].name), (yyvsp[(3) - (5)].name), (yyvsp[(5) - (5)].ptr) ); ;} + break; + + case 6: + +/* Line 1455 of yacc.c */ +#line 65 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newMaskAtom( (yyvsp[(1) - (5)].name), (yyvsp[(3) - (5)].name), (yyvsp[(5) - (5)].ptr) ); ;} + break; + + case 7: + +/* Line 1455 of yacc.c */ +#line 66 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newIsAtom( (yyvsp[(2) - (2)].name) ); ;} + break; + + case 8: + +/* Line 1455 of yacc.c */ +#line 68 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newOr( (yyvsp[(1) - (3)].ptr), (yyvsp[(3) - (3)].ptr) ); ;} + break; + + case 9: + +/* Line 1455 of yacc.c */ +#line 70 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newAnd( (yyvsp[(1) - (3)].ptr), (yyvsp[(3) - (3)].ptr) ); ;} + break; + + case 10: + +/* Line 1455 of yacc.c */ +#line 72 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newStringValue( (yyvsp[(1) - (1)].name) ); ;} + break; + + case 11: + +/* Line 1455 of yacc.c */ +#line 73 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newBoolValue( (yyvsp[(1) - (1)].valb) ); ;} + break; + + case 12: + +/* Line 1455 of yacc.c */ +#line 74 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newNumValue( (yyvsp[(1) - (1)].vali) ); ;} + break; + + case 13: + +/* Line 1455 of yacc.c */ +#line 75 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newDoubleValue( (yyvsp[(1) - (1)].vald) ); ;} + break; + + case 14: + +/* Line 1455 of yacc.c */ +#line 76 "predicate_parser.y" + { (yyval.ptr) = (yyvsp[(1) - (1)].ptr); ;} + break; + + case 15: + +/* Line 1455 of yacc.c */ +#line 78 "predicate_parser.y" + { (yyval.ptr) = (yyvsp[(1) - (3)].ptr); ;} + break; + + case 16: + +/* Line 1455 of yacc.c */ +#line 80 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newEmptyStringListValue(); ;} + break; + + case 17: + +/* Line 1455 of yacc.c */ +#line 81 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_newStringListValue( (yyvsp[(1) - (1)].ptr) ); ;} + break; + + case 18: + +/* Line 1455 of yacc.c */ +#line 82 "predicate_parser.y" + { (yyval.ptr) = PredicateParse_appendStringListValue( (yyvsp[(1) - (3)].name), (yyvsp[(3) - (3)].ptr) ); ;} + break; + + + +/* Line 1455 of yacc.c */ +#line 1530 "predicate_parser.tab.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1675 of yacc.c */ +#line 84 "predicate_parser.y" + + +void Soliderror ( const char *s ) /* Called by Solidparse on error */ +{ + PredicateParse_errorDetected(s); +} + +void PredicateParse_mainParse( const char *_code ) +{ + yyscan_t scanner; + Solidlex_init( &scanner ); + PredicateParse_initLexer( _code, scanner ); + Solidparse( scanner ); + Solidlex_destroy( scanner ); +} + + diff --git a/solid-lite/predicate_parser.h b/solid-lite/predicate_parser.h new file mode 100644 index 000000000..d606eabda --- /dev/null +++ b/solid-lite/predicate_parser.h @@ -0,0 +1,84 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + EQ = 258, + MASK = 259, + AND = 260, + OR = 261, + IS = 262, + VAL_BOOL = 263, + VAL_STRING = 264, + VAL_ID = 265, + VAL_NUM = 266, + VAL_FLOAT = 267 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 1676 of yacc.c */ +#line 22 "predicate_parser.y" + + char valb; + int vali; + double vald; + char *name; + void *ptr; + + + +/* Line 1676 of yacc.c */ +#line 74 "predicate_parser.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + + + diff --git a/solid-lite/predicate_parser.y b/solid-lite/predicate_parser.y new file mode 100644 index 000000000..04de2e1f8 --- /dev/null +++ b/solid-lite/predicate_parser.y @@ -0,0 +1,99 @@ +%{ +#include +#include +#include "predicate_parser.h" +#include "predicateparse.h" + +#define YYLTYPE_IS_TRIVIAL 0 +#define YYENABLE_NLS 0 +#define YYLEX_PARAM scanner +#define YYPARSE_PARAM scanner +typedef void* yyscan_t; +void Soliderror(const char *s); +int Solidlex( YYSTYPE *yylval, yyscan_t scanner ); +int Solidlex_init( yyscan_t *scanner ); +int Solidlex_destroy( yyscan_t *scanner ); +void PredicateParse_initLexer( const char *s, yyscan_t scanner ); +void PredicateParse_mainParse( const char *_code ); + +%} + +%union +{ + char valb; + int vali; + double vald; + char *name; + void *ptr; +} + +%token EQ +%token MASK + +%token AND +%token OR +%token IS + +%token VAL_BOOL +%token VAL_STRING +%token VAL_ID +%token VAL_NUM +%token VAL_FLOAT + +%type predicate +%type predicate_atom +%type predicate_or +%type predicate_and +%type string_list +%type string_list_rec +%type value + +%destructor { PredicateParse_destroy( $$ ); } predicate +%destructor { PredicateParse_destroy( $$ ); } predicate_atom +%destructor { PredicateParse_destroy( $$ ); } predicate_or +%destructor { PredicateParse_destroy( $$ ); } predicate_and + +%pure-parser + +%% + +predicate: predicate_atom { PredicateParse_setResult( $1 ); $$ = $1; } + | '[' predicate_or ']' { PredicateParse_setResult( $2 ); $$ = $2; } + | '[' predicate_and ']' { PredicateParse_setResult( $2 ); $$ = $2; } + +predicate_atom: VAL_ID '.' VAL_ID EQ value { $$ = PredicateParse_newAtom( $1, $3, $5 ); } + | VAL_ID '.' VAL_ID MASK value { $$ = PredicateParse_newMaskAtom( $1, $3, $5 ); } + | IS VAL_ID { $$ = PredicateParse_newIsAtom( $2 ); } + +predicate_or: predicate OR predicate { $$ = PredicateParse_newOr( $1, $3 ); } + +predicate_and: predicate AND predicate { $$ = PredicateParse_newAnd( $1, $3 ); } + +value: VAL_STRING { $$ = PredicateParse_newStringValue( $1 ); } + | VAL_BOOL { $$ = PredicateParse_newBoolValue( $1 ); } + | VAL_NUM { $$ = PredicateParse_newNumValue( $1 ); } + | VAL_FLOAT { $$ = PredicateParse_newDoubleValue( $1 ); } + | string_list { $$ = $1; } + +string_list: '{' string_list_rec '}' { $$ = $1; } + +string_list_rec: /* empty */ { $$ = PredicateParse_newEmptyStringListValue(); } + | VAL_STRING { $$ = PredicateParse_newStringListValue( $1 ); } + | VAL_STRING ',' string_list_rec { $$ = PredicateParse_appendStringListValue( $1, $3 ); } + +%% + +void Soliderror ( const char *s ) /* Called by Solidparse on error */ +{ + PredicateParse_errorDetected(s); +} + +void PredicateParse_mainParse( const char *_code ) +{ + yyscan_t scanner; + Solidlex_init( &scanner ); + PredicateParse_initLexer( _code, scanner ); + Solidparse( scanner ); + Solidlex_destroy( scanner ); +} + diff --git a/solid-lite/predicateparse.cpp b/solid-lite/predicateparse.cpp new file mode 100644 index 000000000..d51c2ff5a --- /dev/null +++ b/solid-lite/predicateparse.cpp @@ -0,0 +1,243 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +extern "C" +{ +#include "predicateparse.h" + +void PredicateParse_mainParse(const char *_code); +} + +#include "predicate.h" +#include "soliddefs_p.h" + +#include + +#include +#include + +namespace Solid +{ +namespace PredicateParse +{ + +struct ParsingData +{ + ParsingData() + : result(0) + {} + + Solid::Predicate *result; + QByteArray buffer; +}; + +} +} + +SOLID_GLOBAL_STATIC(QThreadStorage, s_parsingData) + +Solid::Predicate Solid::Predicate::fromString(const QString &predicate) +{ + Solid::PredicateParse::ParsingData *data = new Solid::PredicateParse::ParsingData(); + s_parsingData->setLocalData(data); + data->buffer = predicate.toAscii(); + PredicateParse_mainParse(data->buffer.constData()); + Predicate result; + if (data->result) + { + result = Predicate(*data->result); + delete data->result; + } + s_parsingData->setLocalData(0); + return result; +} + + +void PredicateParse_setResult(void *result) +{ + Solid::PredicateParse::ParsingData *data = s_parsingData->localData(); + data->result = (Solid::Predicate *) result; +} + +void PredicateParse_errorDetected(const char* s) +{ + qWarning("ERROR from solid predicate parser: %s", s); + s_parsingData->localData()->result = 0; +} + +void PredicateParse_destroy(void *pred) +{ + Solid::PredicateParse::ParsingData *data = s_parsingData->localData(); + Solid::Predicate *p = (Solid::Predicate *) pred; + if (p != data->result) { + delete p; + } +} + +void *PredicateParse_newAtom(char *interface, char *property, void *value) +{ + QString iface(interface); + QString prop(property); + QVariant *val = (QVariant *)value; + + Solid::Predicate *result = new Solid::Predicate(iface, prop, *val); + + delete val; + free(interface); + free(property); + + return result; +} + +void *PredicateParse_newMaskAtom(char *interface, char *property, void *value) +{ + QString iface(interface); + QString prop(property); + QVariant *val = (QVariant *)value; + + Solid::Predicate *result = new Solid::Predicate(iface, prop, *val, Solid::Predicate::Mask); + + delete val; + free(interface); + free(property); + + return result; +} + + +void *PredicateParse_newIsAtom(char *interface) +{ + QString iface(interface); + + Solid::Predicate *result = new Solid::Predicate(iface); + + free(interface); + + return result; +} + + +void *PredicateParse_newAnd(void *pred1, void *pred2) +{ + Solid::Predicate *result = new Solid::Predicate(); + + Solid::PredicateParse::ParsingData *data = s_parsingData->localData(); + Solid::Predicate *p1 = (Solid::Predicate *)pred1; + Solid::Predicate *p2 = (Solid::Predicate *)pred2; + + if (p1==data->result || p2==data->result) { + data->result = 0; + } + + *result = *p1 & *p2; + + delete p1; + delete p2; + + return result; +} + + +void *PredicateParse_newOr(void *pred1, void *pred2) +{ + Solid::Predicate *result = new Solid::Predicate(); + + Solid::PredicateParse::ParsingData *data = s_parsingData->localData(); + Solid::Predicate *p1 = (Solid::Predicate *)pred1; + Solid::Predicate *p2 = (Solid::Predicate *)pred2; + + if (p1==data->result || p2==data->result) { + data->result = 0; + } + + *result = *p1 | *p2; + + delete p1; + delete p2; + + return result; +} + + +void *PredicateParse_newStringValue(char *val) +{ + QString s(val); + + free(val); + + return new QVariant(s); +} + + +void *PredicateParse_newBoolValue(int val) +{ + bool b = (val != 0); + return new QVariant(b); +} + + +void *PredicateParse_newNumValue(int val) +{ + return new QVariant(val); +} + + +void *PredicateParse_newDoubleValue(double val) +{ + return new QVariant(val); +} + + +void *PredicateParse_newEmptyStringListValue() +{ + return new QVariant(QStringList()); +} + + +void *PredicateParse_newStringListValue(char *name) +{ + QStringList list; + list << QString(name); + + free(name); + + return new QVariant(list); +} + + +void *PredicateParse_appendStringListValue(char *name, void *list) +{ + QVariant *variant = (QVariant *)list; + + QStringList new_list = variant->toStringList(); + + new_list << QString(name); + + delete variant; + free(name); + + return new QVariant(new_list); +} + +void PredicateLexer_unknownToken(const char* text) +{ + qWarning("ERROR from solid predicate parser: unrecognized token '%s' in predicate '%s'\n", + text, s_parsingData->localData()->buffer.constData()); +} diff --git a/solid-lite/predicateparse.h b/solid-lite/predicateparse.h new file mode 100644 index 000000000..b15ca50ee --- /dev/null +++ b/solid-lite/predicateparse.h @@ -0,0 +1,43 @@ +/* + Copyright 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef PREDICATEPARSE_H +#define PREDICATEPARSE_H + +void PredicateLexer_unknownToken(const char* text); + +void PredicateParse_setResult(void *result); +void PredicateParse_errorDetected(const char* error); +void PredicateParse_destroy(void *pred); + +void *PredicateParse_newAtom(char *interface, char *property, void *value); +void *PredicateParse_newMaskAtom(char *interface, char *property, void *value); +void *PredicateParse_newIsAtom(char *interface); +void *PredicateParse_newAnd(void *pred1, void *pred2); +void *PredicateParse_newOr(void *pred1, void *pred2); +void *PredicateParse_newStringValue(char *val); +void *PredicateParse_newBoolValue(int val); +void *PredicateParse_newNumValue(int val); +void *PredicateParse_newDoubleValue(double val); +void *PredicateParse_newEmptyStringListValue(); +void *PredicateParse_newStringListValue(char *name); +void *PredicateParse_appendStringListValue(char *name, void *list); + +#endif diff --git a/solid-lite/solid_export.h b/solid-lite/solid_export.h new file mode 100644 index 000000000..6f765b27b --- /dev/null +++ b/solid-lite/solid_export.h @@ -0,0 +1,3 @@ +#ifndef SOLID_EXPORT +#define SOLID_EXPORT +#endif diff --git a/solid-lite/soliddefs_p.h b/solid-lite/soliddefs_p.h new file mode 100644 index 000000000..aee75a2ed --- /dev/null +++ b/solid-lite/soliddefs_p.h @@ -0,0 +1,122 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_SOLIDDEFS_P_H +#define SOLID_SOLIDDEFS_P_H + +#include + +#define return_SOLID_CALL(Type, Object, Default, Method) \ + Type t = qobject_cast(Object); \ + if (t!=0) \ + { \ + return t->Method; \ + } \ + else \ + { \ + return Default; \ + } + + + +#define SOLID_CALL(Type, Object, Method) \ + Type t = qobject_cast(Object); \ + if (t!=0) \ + { \ + t->Method; \ + } + +// +// WARNING!! +// This code uses undocumented Qt API +// Do not copy it to your application! Use only the functions that are here! +// Otherwise, it could break when a new version of Qt ships. +// + +/* + * Lame copy of K_GLOBAL_STATIC below, but that's the price for + * being completely kdecore independent. + */ + +namespace Solid +{ + typedef void (*CleanUpFunction)(); + + class CleanUpGlobalStatic + { + public: + Solid::CleanUpFunction func; + + inline ~CleanUpGlobalStatic() { func(); } + }; +} + +#ifdef Q_CC_MSVC +# define SOLID_GLOBAL_STATIC_STRUCT_NAME(NAME) _solid_##NAME##__LINE__ +#else +# define SOLID_GLOBAL_STATIC_STRUCT_NAME(NAME) +#endif + +#define SOLID_GLOBAL_STATIC(TYPE, NAME) SOLID_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ()) + +#define SOLID_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ +static QBasicAtomicPointer _solid_static_##NAME = Q_BASIC_ATOMIC_INITIALIZER(0);\ +static bool _solid_static_##NAME##_destroyed; \ +static struct SOLID_GLOBAL_STATIC_STRUCT_NAME(NAME) \ +{ \ + bool isDestroyed() \ + { \ + return _solid_static_##NAME##_destroyed; \ + } \ + inline operator TYPE*() \ + { \ + return operator->(); \ + } \ + inline TYPE *operator->() \ + { \ + if (!_solid_static_##NAME) { \ + if (isDestroyed()) { \ + qFatal("Fatal Error: Accessed global static '%s *%s()' after destruction. " \ + "Defined at %s:%d", #TYPE, #NAME, __FILE__, __LINE__); \ + } \ + TYPE *x = new TYPE ARGS; \ + if (!_solid_static_##NAME.testAndSetOrdered(0, x) \ + && _solid_static_##NAME != x ) { \ + delete x; \ + } else { \ + static Solid::CleanUpGlobalStatic cleanUpObject = { destroy }; \ + } \ + } \ + return _solid_static_##NAME; \ + } \ + inline TYPE &operator*() \ + { \ + return *operator->(); \ + } \ + static void destroy() \ + { \ + _solid_static_##NAME##_destroyed = true; \ + TYPE *x = _solid_static_##NAME; \ + _solid_static_##NAME = 0; \ + delete x; \ + } \ +} NAME; + +#endif diff --git a/solid-lite/solidnamespace.cpp b/solid-lite/solidnamespace.cpp new file mode 100644 index 000000000..69ff58038 --- /dev/null +++ b/solid-lite/solidnamespace.cpp @@ -0,0 +1,34 @@ +/* + Copyright 2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "solidnamespace.h" + +static int registerSolidMetaTypes() +{ + qRegisterMetaType(); + + return 0; // something +} + +#ifdef Q_CONSTRUCTOR_FUNCTION +Q_CONSTRUCTOR_FUNCTION(registerSolidMetaTypes) +#else +static const int _Solid_registerMetaTypes = registerSolidMetaTypes(); +#endif diff --git a/solid-lite/solidnamespace.h b/solid-lite/solidnamespace.h new file mode 100644 index 000000000..f40b5cf9e --- /dev/null +++ b/solid-lite/solidnamespace.h @@ -0,0 +1,42 @@ +/* + Copyright 2007 Kevin Ottens + Copyright 2011 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_SOLIDNAMESPACE_H +#define SOLID_SOLIDNAMESPACE_H + +namespace Solid +{ + enum ErrorType { + NoError = 0, + UnauthorizedOperation, + DeviceBusy, + OperationFailed, + UserCanceled, + InvalidOption, + MissingDriver + }; +} + +#include + +Q_DECLARE_METATYPE(Solid::ErrorType) + +#endif diff --git a/solid-lite/storageaccess.cpp b/solid-lite/storageaccess.cpp new file mode 100644 index 000000000..db993f919 --- /dev/null +++ b/solid-lite/storageaccess.cpp @@ -0,0 +1,95 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "storageaccess.h" +#include "storageaccess_p.h" + +#include "soliddefs_p.h" +#include + +Solid::StorageAccess::StorageAccess(QObject *backendObject) + : DeviceInterface(*new StorageAccessPrivate(), backendObject) +{ + connect(backendObject, SIGNAL(setupDone(Solid::ErrorType,QVariant,QString)), + this, SIGNAL(setupDone(Solid::ErrorType,QVariant,QString))); + connect(backendObject, SIGNAL(teardownDone(Solid::ErrorType,QVariant,QString)), + this, SIGNAL(teardownDone(Solid::ErrorType,QVariant,QString))); + connect(backendObject, SIGNAL(setupRequested(QString)), + this, SIGNAL(setupRequested(QString))); + connect(backendObject, SIGNAL(teardownRequested(QString)), + this, SIGNAL(teardownRequested(QString))); + + connect(backendObject, SIGNAL(accessibilityChanged(bool,QString)), + this, SIGNAL(accessibilityChanged(bool,QString))); +} + +Solid::StorageAccess::StorageAccess(StorageAccessPrivate &dd, QObject *backendObject) + : DeviceInterface(dd, backendObject) +{ + connect(backendObject, SIGNAL(setupDone(Solid::StorageAccess::SetupResult,QVariant,QString)), + this, SIGNAL(setupDone(Solid::StorageAccess::SetupResult,QVariant,QString))); + connect(backendObject, SIGNAL(teardownDone(Solid::StorageAccess::TeardownResult,QVariant,QString)), + this, SIGNAL(teardownDone(Solid::StorageAccess::TeardownResult,QVariant,QString))); + connect(backendObject, SIGNAL(setupRequested(QString)), + this, SIGNAL(setupRequested(QString))); + connect(backendObject, SIGNAL(teardownRequested(QString)), + this, SIGNAL(teardownRequested(QString))); + + + connect(backendObject, SIGNAL(accessibilityChanged(bool,QString)), + this, SIGNAL(accessibilityChanged(bool,QString))); +} + +Solid::StorageAccess::~StorageAccess() +{ + +} + +bool Solid::StorageAccess::isAccessible() const +{ + Q_D(const StorageAccess); + return_SOLID_CALL(Ifaces::StorageAccess *, d->backendObject(), false, isAccessible()); +} + +QString Solid::StorageAccess::filePath() const +{ + Q_D(const StorageAccess); + return_SOLID_CALL(Ifaces::StorageAccess *, d->backendObject(), QString(), filePath()); +} + +bool Solid::StorageAccess::setup() +{ + Q_D(StorageAccess); + return_SOLID_CALL(Ifaces::StorageAccess *, d->backendObject(), false, setup()); +} + +bool Solid::StorageAccess::teardown() +{ + Q_D(StorageAccess); + return_SOLID_CALL(Ifaces::StorageAccess *, d->backendObject(), false, teardown()); +} + +bool Solid::StorageAccess::isIgnored() const +{ + Q_D(const StorageAccess); + return_SOLID_CALL(Ifaces::StorageAccess *, d->backendObject(), true, isIgnored()); +} + +//#include "storageaccess.moc" diff --git a/solid-lite/storageaccess.h b/solid-lite/storageaccess.h new file mode 100644 index 000000000..447c55622 --- /dev/null +++ b/solid-lite/storageaccess.h @@ -0,0 +1,178 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_STORAGEACCESS_H +#define SOLID_STORAGEACCESS_H + +#include + +#include +#include +#include + +namespace Solid +{ + class StorageAccessPrivate; + class Device; + + /** + * This device interface is available on volume devices to access them + * (i.e. mount or unmount them). + * + * A volume is anything that can contain data (partition, optical disc, + * memory card). It's a particular kind of block device. + */ + class SOLID_EXPORT StorageAccess : public DeviceInterface + { + Q_OBJECT + Q_PROPERTY(bool accessible READ isAccessible) + Q_PROPERTY(QString filePath READ filePath) + Q_PROPERTY(bool ignored READ isIgnored) + Q_DECLARE_PRIVATE(StorageAccess) + friend class Device; + + private: + /** + * Creates a new StorageAccess object. + * You generally won't need this. It's created when necessary using + * Device::as(). + * + * @param backendObject the device interface object provided by the backend + * @see Solid::Device::as() + */ + explicit StorageAccess(QObject *backendObject); + + public: + /** + * Destroys a StorageAccess object. + */ + virtual ~StorageAccess(); + + + /** + * Get the Solid::DeviceInterface::Type of the StorageAccess device interface. + * + * @return the StorageVolume device interface type + * @see Solid::Ifaces::Enums::DeviceInterface::Type + */ + static Type deviceInterfaceType() { return DeviceInterface::StorageAccess; } + + + /** + * Indicates if this volume is mounted. + * + * @return true if the volume is mounted + */ + bool isAccessible() const; + + /** + * Retrieves the absolute path of this volume mountpoint. + * + * @return the absolute path to the mount point if the volume is + * mounted, QString() otherwise + */ + QString filePath() const; + + /** + * Indicates if this volume should be ignored by applications. + * + * If it should be ignored, it generally means that it should be + * invisible to the user. It's useful for firmware partitions or + * OS reinstall partitions on some systems. + * + * @return true if the volume should be ignored + */ + bool isIgnored() const; + + /** + * Mounts the volume. + * + * @return false if the operation is not supported, true if the + * operation is attempted + */ + bool setup(); + + /** + * Unmounts the volume. + * + * @return false if the operation is not supported, true if the + * operation is attempted + */ + bool teardown(); + + Q_SIGNALS: + /** + * This signal is emitted when the accessiblity of this device + * has changed. + * + * @param accessible true if the volume is accessible, false otherwise + * @param udi the UDI of the volume + */ + void accessibilityChanged(bool accessible, const QString &udi); + + /** + * This signal is emitted when the attempted setting up of this + * device is completed. The signal might be spontaneous i.e. + * it can be triggered by another process. + * + * @param error type of error that occurred, if any + * @param errorData more information about the error, if any + * @param udi the UDI of the volume + */ + void setupDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + + /** + * This signal is emitted when the attempted tearing down of this + * device is completed. The signal might be spontaneous i.e. + * it can be triggered by another process. + * + * @param error type of error that occurred, if any + * @param errorData more information about the error, if any + * @param udi the UDI of the volume + */ + void teardownDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + + /** + * This signal is emitted when a setup of this device is requested. + * The signal might be spontaneous i.e. it can be triggered by + * another process. + * + * @param udi the UDI of the volume + */ + void setupRequested(const QString &udi); + + /** + * This signal is emitted when a teardown of this device is requested. + * The signal might be spontaneous i.e. it can be triggered by + * another process + * + * @param udi the UDI of the volume + */ + void teardownRequested(const QString &udi); + + protected: + /** + * @internal + */ + StorageAccess(StorageAccessPrivate &dd, QObject *backendObject); + }; +} + +#endif diff --git a/solid-lite/storageaccess_p.h b/solid-lite/storageaccess_p.h new file mode 100644 index 000000000..5dace9832 --- /dev/null +++ b/solid-lite/storageaccess_p.h @@ -0,0 +1,36 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_STORAGEACCESS_P_H +#define SOLID_STORAGEACCESS_P_H + +#include "deviceinterface_p.h" + +namespace Solid +{ + class StorageAccessPrivate : public DeviceInterfacePrivate + { + public: + StorageAccessPrivate() + : DeviceInterfacePrivate() { } + }; +} + +#endif diff --git a/solid-lite/storagedrive.cpp b/solid-lite/storagedrive.cpp new file mode 100644 index 000000000..b171e4cc4 --- /dev/null +++ b/solid-lite/storagedrive.cpp @@ -0,0 +1,94 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "storagedrive.h" +#include "storagedrive_p.h" + +#include "soliddefs_p.h" +#include +#include "predicate.h" +#include "storageaccess.h" +#include "device.h" +#include "device_p.h" + +Solid::StorageDrive::StorageDrive(QObject *backendObject) + : DeviceInterface(*new StorageDrivePrivate(), backendObject) +{ +} + +Solid::StorageDrive::StorageDrive(StorageDrivePrivate &dd, QObject *backendObject) + : DeviceInterface(dd, backendObject) +{ + +} + +Solid::StorageDrive::~StorageDrive() +{ + +} + +Solid::StorageDrive::Bus Solid::StorageDrive::bus() const +{ + Q_D(const StorageDrive); + return_SOLID_CALL(Ifaces::StorageDrive *, d->backendObject(), Platform, bus()); +} + +Solid::StorageDrive::DriveType Solid::StorageDrive::driveType() const +{ + Q_D(const StorageDrive); + return_SOLID_CALL(Ifaces::StorageDrive *, d->backendObject(), HardDisk, driveType()); +} + +bool Solid::StorageDrive::isRemovable() const +{ + Q_D(const StorageDrive); + return_SOLID_CALL(Ifaces::StorageDrive *, d->backendObject(), false, isRemovable()); +} + +bool Solid::StorageDrive::isHotpluggable() const +{ + Q_D(const StorageDrive); + return_SOLID_CALL(Ifaces::StorageDrive *, d->backendObject(), false, isHotpluggable()); +} + +qulonglong Solid::StorageDrive::size() const +{ + Q_D(const StorageDrive); + return_SOLID_CALL(Ifaces::StorageDrive *, d->backendObject(), false, size()); +} + +bool Solid::StorageDrive::isInUse() const +{ + Q_D(const StorageDrive); + Predicate p(DeviceInterface::StorageAccess); + QList devices = Device::listFromQuery(p, d->devicePrivate()->udi()); + + bool inUse = false; + foreach (const Device &dev, devices) { + if (dev.is()) { + const Solid::StorageAccess* access = dev.as(); + inUse |= (access->isAccessible()); + } + } + return inUse; +} + +//#include "storagedrive.moc" + diff --git a/solid-lite/storagedrive.h b/solid-lite/storagedrive.h new file mode 100644 index 000000000..85f07c82b --- /dev/null +++ b/solid-lite/storagedrive.h @@ -0,0 +1,167 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_STORAGEDRIVE_H +#define SOLID_STORAGEDRIVE_H + +#include + +#include + +namespace Solid +{ + class StorageDrivePrivate; + class Device; + + /** + * This device interface is available on storage devices. + * + * A storage is anything that can contain a set of volumes (card reader, + * hard disk, cdrom drive...). It's a particular kind of block device. + */ + class SOLID_EXPORT StorageDrive : public DeviceInterface + { + Q_OBJECT + Q_ENUMS(Bus DriveType) + Q_PROPERTY(Bus bus READ bus) + Q_PROPERTY(DriveType driveType READ driveType) + Q_PROPERTY(bool removable READ isRemovable) + Q_PROPERTY(bool hotpluggable READ isHotpluggable) + Q_PROPERTY(bool inUse READ isInUse) + Q_PROPERTY(qulonglong size READ size) + Q_DECLARE_PRIVATE(StorageDrive) + friend class Device; + + public: + /** + * This enum type defines the type of bus a storage device is attached to. + * + * - Ide : An Integrated Drive Electronics (IDE) bus, also known as ATA + * - Usb : An Universal Serial Bus (USB) + * - Ieee1394 : An Ieee1394 bus, also known as Firewire + * - Scsi : A Small Computer System Interface bus + * - Sata : A Serial Advanced Technology Attachment (SATA) bus + * - Platform : A legacy bus that is part of the underlying platform + */ + enum Bus { Ide, Usb, Ieee1394, Scsi, Sata, Platform }; + + /** + * This enum type defines the type of drive a storage device can be. + * + * - HardDisk : A hard disk + * - CdromDrive : An optical drive + * - Floppy : A floppy disk drive + * - Tape : A tape drive + * - CompactFlash : A Compact Flash card reader + * - MemoryStick : A Memory Stick card reader + * - SmartMedia : A Smart Media card reader + * - SdMmc : A SecureDigital/MultiMediaCard card reader + * - Xd : A xD card reader + */ + enum DriveType { HardDisk, CdromDrive, Floppy, Tape, CompactFlash, MemoryStick, SmartMedia, SdMmc, Xd }; + + + private: + /** + * Creates a new StorageDrive object. + * You generally won't need this. It's created when necessary using + * Device::as(). + * + * @param backendObject the device interface object provided by the backend + * @see Solid::Device::as() + */ + explicit StorageDrive(QObject *backendObject); + + public: + /** + * Destroys a StorageDrive object. + */ + virtual ~StorageDrive(); + + + /** + * Get the Solid::DeviceInterface::Type of the StorageDrive device interface. + * + * @return the StorageDrive device interface type + * @see Solid::DeviceInterface::Type + */ + static Type deviceInterfaceType() { return DeviceInterface::StorageDrive; } + + + /** + * Retrieves the type of physical interface this storage device is + * connected to. + * + * @return the bus type + * @see Solid::StorageDrive::Bus + */ + Bus bus() const; + + /** + * Retrieves the type of this storage drive. + * + * @return the drive type + * @see Solid::StorageDrive::DriveType + */ + DriveType driveType() const; + + /** + * Indicates if the media contained by this drive can be removed. + * + * For example memory card can be removed from the drive by the user, + * while partitions can't be removed from hard disks. + * + * @return true if media can be removed, false otherwise. + */ + bool isRemovable() const; + + /** + * Indicates if this storage device can be plugged or unplugged while + * the computer is running. + * + * @return true if this storage supports hotplug, false otherwise + */ + bool isHotpluggable() const; + + /** + * Retrieves this drives size in bytes. + * + * @return the size of this drive + */ + qulonglong size() const; + + /** + * Indicates if the storage device is currently in use + * i.e. if at least one child storage access is + * mounted + * + * @return true if at least one child storage access is mounted + */ + bool isInUse() const; + + protected: + /** + * @internal + */ + StorageDrive(StorageDrivePrivate &dd, QObject *backendObject); + }; +} + +#endif // SOLID_STORAGEDRIVE_H diff --git a/solid-lite/storagedrive_p.h b/solid-lite/storagedrive_p.h new file mode 100644 index 000000000..ab999d9d1 --- /dev/null +++ b/solid-lite/storagedrive_p.h @@ -0,0 +1,36 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_STORAGEDRIVE_P_H +#define SOLID_STORAGEDRIVE_P_H + +#include "deviceinterface_p.h" + +namespace Solid +{ + class StorageDrivePrivate : public DeviceInterfacePrivate + { + public: + StorageDrivePrivate() + : DeviceInterfacePrivate() { } + }; +} + +#endif // SOLID_STORAGEDRIVE_P_H diff --git a/solid-lite/storagevolume.cpp b/solid-lite/storagevolume.cpp new file mode 100644 index 000000000..a4906e71f --- /dev/null +++ b/solid-lite/storagevolume.cpp @@ -0,0 +1,93 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "storagevolume.h" +#include "storagevolume_p.h" + +#include "soliddefs_p.h" +#include +#include + +Solid::StorageVolume::StorageVolume(QObject *backendObject) + : DeviceInterface(*new StorageVolumePrivate(), backendObject) +{ +} + +Solid::StorageVolume::StorageVolume(StorageVolumePrivate &dd, QObject *backendObject) + : DeviceInterface(dd, backendObject) +{ +} + +Solid::StorageVolume::~StorageVolume() +{ + +} + +bool Solid::StorageVolume::isIgnored() const +{ + Q_D(const StorageVolume); + return_SOLID_CALL(Ifaces::StorageVolume *, d->backendObject(), true, isIgnored()); +} + +Solid::StorageVolume::UsageType Solid::StorageVolume::usage() const +{ + Q_D(const StorageVolume); + return_SOLID_CALL(Ifaces::StorageVolume *, d->backendObject(), Unused, usage()); +} + +QString Solid::StorageVolume::fsType() const +{ + Q_D(const StorageVolume); + return_SOLID_CALL(Ifaces::StorageVolume *, d->backendObject(), QString(), fsType()); +} + +QString Solid::StorageVolume::label() const +{ + Q_D(const StorageVolume); + return_SOLID_CALL(Ifaces::StorageVolume *, d->backendObject(), QString(), label()); +} + +QString Solid::StorageVolume::uuid() const +{ + Q_D(const StorageVolume); + return_SOLID_CALL(Ifaces::StorageVolume *, d->backendObject(), QString(), uuid().toLower()); +} + +qulonglong Solid::StorageVolume::size() const +{ + Q_D(const StorageVolume); + return_SOLID_CALL(Ifaces::StorageVolume *, d->backendObject(), 0, size()); +} + +Solid::Device Solid::StorageVolume::encryptedContainer() const +{ + Q_D(const StorageVolume); + + Ifaces::StorageVolume *iface + = qobject_cast(d->backendObject()); + + if (iface!=0) { + return Device(iface->encryptedContainerUdi()); + } else { + return Device(); + } +} + +//#include "storagevolume.moc" diff --git a/solid-lite/storagevolume.h b/solid-lite/storagevolume.h new file mode 100644 index 000000000..94a0ff639 --- /dev/null +++ b/solid-lite/storagevolume.h @@ -0,0 +1,163 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_STORAGEVOLUME_H +#define SOLID_STORAGEVOLUME_H + +#include + +#include + +namespace Solid +{ + class StorageVolumePrivate; + class Device; + + /** + * This device interface is available on volume devices. + * + * A volume is anything that can contain data (partition, optical disc, + * memory card). It's a particular kind of block device. + */ + class SOLID_EXPORT StorageVolume : public DeviceInterface + { + Q_OBJECT + Q_ENUMS(UsageType) + Q_PROPERTY(bool ignored READ isIgnored) + Q_PROPERTY(UsageType usage READ usage) + Q_PROPERTY(QString fsType READ fsType) + Q_PROPERTY(QString label READ label) + Q_PROPERTY(QString uuid READ uuid) + Q_PROPERTY(qulonglong size READ size) + Q_DECLARE_PRIVATE(StorageVolume) + friend class Device; + + public: + /** + * This enum type defines the how a volume is used. + * + * - FileSystem : A mountable filesystem volume + * - PartitionTable : A volume containing a partition table + * - Raid : A volume member of a raid set (not mountable) + * - Other : A not mountable volume (like a swap partition) + * - Unused : An unused or free volume + */ + enum UsageType { Other = 0, Unused = 1, FileSystem = 2, PartitionTable = 3, Raid = 4, Encrypted = 5 }; + + + private: + /** + * Creates a new StorageVolume object. + * You generally won't need this. It's created when necessary using + * Device::as(). + * + * @param backendObject the device interface object provided by the backend + * @see Solid::Device::as() + */ + explicit StorageVolume(QObject *backendObject); + + public: + /** + * Destroys a StorageVolume object. + */ + virtual ~StorageVolume(); + + + /** + * Get the Solid::DeviceInterface::Type of the StorageVolume device interface. + * + * @return the StorageVolume device interface type + * @see Solid::DeviceInterface::Type + */ + static Type deviceInterfaceType() { return DeviceInterface::StorageVolume; } + + + /** + * Indicates if this volume should be ignored by applications. + * + * If it should be ignored, it generally means that it should be + * invisible to the user. It's useful for firmware partitions or + * OS reinstall partitions on some systems. + * + * @return true if the volume should be ignored + */ + bool isIgnored() const; + + /** + * Retrieves the type of use for this volume (for example filesystem). + * + * @return the usage type + * @see Solid::StorageVolume::UsageType + */ + UsageType usage() const; + + /** + * Retrieves the filesystem type of this volume. + * + * FIXME: It's a platform dependent string, maybe we should switch to + * an enum? + * + * @return the filesystem type if applicable, QString() otherwise + */ + QString fsType() const; + + /** + * Retrieves this volume label. + * + * @return the volume label if available, QString() otherwise + */ + QString label() const; + + /** + * Retrieves this volume Universal Unique IDentifier (UUID). + * + * You can generally assume that this identifier is unique with reasonable + * confidence. Except if the volume UUID has been forged to intentionally + * provoke a collision, the probability to have two volumes having the same + * UUID is low. + * + * @return the Universal Unique IDentifier if available, QString() otherwise + */ + QString uuid() const; + + /** + * Retrieves this volume size in bytes. + * + * @return the size of this volume + */ + qulonglong size() const; + + /** + * Retrieves the crypto container of this volume. + * + * @return the encrypted volume containing the current volume if appliable, + * an invalid device otherwise + */ + Device encryptedContainer() const; + + protected: + /** + * @internal + */ + StorageVolume(StorageVolumePrivate &dd, QObject *backendObject); + }; +} + +#endif // SOLID_STORAGEVOLUME_H diff --git a/solid-lite/storagevolume_p.h b/solid-lite/storagevolume_p.h new file mode 100644 index 000000000..6f8c358a2 --- /dev/null +++ b/solid-lite/storagevolume_p.h @@ -0,0 +1,36 @@ +/* + Copyright 2006-2007 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef SOLID_STORAGEVOLUME_P_H +#define SOLID_STORAGEVOLUME_P_H + +#include "deviceinterface_p.h" + +namespace Solid +{ + class StorageVolumePrivate : public DeviceInterfacePrivate + { + public: + StorageVolumePrivate() + : DeviceInterfacePrivate() { } + }; +} + +#endif // SOLID_STORAGEVOLUME_P_H diff --git a/solid-lite/xdgbasedirs.cpp b/solid-lite/xdgbasedirs.cpp new file mode 100644 index 000000000..4c9cad9c9 --- /dev/null +++ b/solid-lite/xdgbasedirs.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** + * Copyright (C) 2007 by Kevin Krammer * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +/* + * This file was copied to solid from [akonadi]/libs/xdgbasedirs.cpp and slimmed down. + * See xdgbasedirs_p.h for notes about slimming down. + */ + +#include "xdgbasedirs_p.h" + +#include +#include + +static QStringList splitPathList( const QString &pathList ) +{ + return pathList.split( QLatin1Char( ':' ) ); +} + +class XdgBaseDirsSingleton +{ + public: + QString homePath( const char *variable, const char *defaultSubDir ); + + QStringList systemPathList( const char *variable, const char *defaultDirList ); + + public: + QString mConfigHome; + QString mDataHome; + + QStringList mConfigDirs; + QStringList mDataDirs; +}; + +Q_GLOBAL_STATIC( XdgBaseDirsSingleton, instance ) + +QString Solid::XdgBaseDirs::homePath( const char *resource ) +{ + if ( qstrncmp( "data", resource, 4 ) == 0 ) { + if ( instance()->mDataHome.isEmpty() ) { + instance()->mDataHome = instance()->homePath( "XDG_DATA_HOME", ".local/share" ); + } + return instance()->mDataHome; + } else if ( qstrncmp( "config", resource, 6 ) == 0 ) { + if ( instance()->mConfigHome.isEmpty() ) { + instance()->mConfigHome = instance()->homePath( "XDG_CONFIG_HOME", ".config" ); + } + return instance()->mConfigHome; + } + + return QString(); +} + +QStringList Solid::XdgBaseDirs::systemPathList( const char *resource ) +{ + if ( qstrncmp( "data", resource, 4 ) == 0 ) { + if ( instance()->mDataDirs.isEmpty() ) { + instance()->mDataDirs = instance()->systemPathList( "XDG_DATA_DIRS", "/usr/local/share:/usr/share" ); + } + return instance()->mDataDirs; + } else if ( qstrncmp( "config", resource, 6 ) == 0 ) { + if ( instance()->mConfigDirs.isEmpty() ) { + instance()->mConfigDirs = instance()->systemPathList( "XDG_CONFIG_DIRS", "/etc/xdg" ); + } + return instance()->mConfigDirs; + } + + return QStringList(); +} + +QString Solid::XdgBaseDirs::findResourceFile( const char *resource, const QString &relPath ) +{ + const QString fullPath = homePath( resource ) + QLatin1Char( '/' ) + relPath; + + QFileInfo fileInfo( fullPath ); + if ( fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable() ) { + return fullPath; + } + + const QStringList pathList = systemPathList( resource ); + + foreach ( const QString &path, pathList ) { + fileInfo = QFileInfo( path + QLatin1Char('/' ) + relPath ); + if ( fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable() ) { + return fileInfo.absoluteFilePath(); + } + } + + return QString(); +} + +QString XdgBaseDirsSingleton::homePath( const char *variable, const char *defaultSubDir ) +{ + const QByteArray env = qgetenv( variable ); + + QString xdgPath; + if ( env.isEmpty() ) { + xdgPath = QDir::homePath() + QLatin1Char( '/' ) + QLatin1String( defaultSubDir ); + } else if ( env.startsWith( '/' ) ) { + xdgPath = QString::fromLocal8Bit( env ); + } else { + xdgPath = QDir::homePath() + QLatin1Char( '/' ) + QString::fromLocal8Bit( env ); + } + + return xdgPath; +} + +QStringList XdgBaseDirsSingleton::systemPathList( const char *variable, const char *defaultDirList ) +{ + const QByteArray env = qgetenv( variable ); + + QString xdgDirList; + if ( env.isEmpty() ) { + xdgDirList = QLatin1String( defaultDirList ); + } else { + xdgDirList = QString::fromLocal8Bit( env ); + } + + return splitPathList( xdgDirList ); +} diff --git a/solid-lite/xdgbasedirs_p.h b/solid-lite/xdgbasedirs_p.h new file mode 100644 index 000000000..369d12f67 --- /dev/null +++ b/solid-lite/xdgbasedirs_p.h @@ -0,0 +1,112 @@ +/*************************************************************************** + * Copyright (C) 2007 by Kevin Krammer * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +/* + * This file was copied to solid from [akonadi]/libs/xdgbasedirs_p.h and slimmed down. + * UDev::PortableMediaPlayer uses findResourceFile() which in turn uses homePath() and + * systemPathList() so these are exported here too + */ + +#ifndef SOLID_XDGBASEDIRS_H +#define SOLID_XDGBASEDIRS_H + +class QString; +class QStringList; + +namespace Solid +{ + /** + @brief Resource type based handling of standard directories + + Developers of several Free Software desktop projects have created + a specification for handling so-called "base directories", i.e. + lists of system wide directories and directories within each user's + home directory for installing and later finding certain files. + + This class handles the respective behaviour, i.e. environment variables + and their defaults, for the following type of resources: + - "config" + - "data" + + @author Kevin Krammer, + + @see http://www.freedesktop.org/wiki/Specifications/basedir-spec + */ + namespace XdgBaseDirs + { + /** + @brief Returns the user specific directory for the given resource type + + Unless the user's environment has a specific path set as an override + this will be the default as defined in the freedesktop.org base-dir-spec + + @note Caches the value of the first call + + @param resource a named resource type, e.g. "config" + + @return a directory path + + @see systemPathList() + */ + QString homePath( const char *resource ); + + /** + @brief Returns the list of system wide directories for a given resource type + + The returned list can contain one or more directory paths. If there are more + than one, the list is sorted by falling priority, i.e. if an entry is valid + for the respective use case (e.g. contains a file the application looks for) + the list should not be processed further. + + @note The user's resource path should, to be compliant with the spec, + always be treated as having higher priority than any path in the + list of system wide paths + + @note Caches the value of the first call + + @param resource a named resource type, e.g. "config" + + @return a priority sorted list of directory paths + + @see homePath() + */ + QStringList systemPathList( const char *resource ); + + /** + @brief Searches the resource specific directories for a given file + + Convenience method for finding a given file (with optional relative path) + in any of the configured base directories for a given resource type. + + Will check the user local directory first and then process the system + wide path list according to the inherent priority. + + @param resource a named resource type, e.g. "config" + @param relPath relative path of a file to look for, + e.g."akonadi/akonadiserverrc" + + @returns the file path of the first match, or @c QString() if no such + relative path exists in any of the base directories or if + a match is not a file + */ + QString findResourceFile( const char *resource, const QString &relPath ); + } +} + +#endif diff --git a/widgets/capacitybar.h b/widgets/capacitybar.h index 7a5a91541..2716358a0 100644 --- a/widgets/capacitybar.h +++ b/widgets/capacitybar.h @@ -24,6 +24,7 @@ #ifndef CAPACITY_BAR_H #define CAPACITY_BAR_H +#ifdef ENABLE_KDE_SUPPORT #include class CapacityBar : public KCapacityBar @@ -32,6 +33,29 @@ public: CapacityBar(QWidget *p) : KCapacityBar(KCapacityBar::DrawTextInline, p) { } + + void update(const QString &text, double value) { + setText(text); + setValue(value); + setDrawTextMode(KCapacityBar::DrawTextInline); + } }; -#endif \ No newline at end of file +#else +#include +class CapacityBar : public QProgressBar +{ +public: + CapacityBar(QWidget *p) + : QProgressBar(p) { + } + + void update(const QString &text, double value) { + setFormat(text); + setRange(0, 100*100); + setValue(value*100); + } +}; +#endif + +#endif diff --git a/widgets/dirrequester.cpp b/widgets/dirrequester.cpp index 35c339206..8fe697a16 100644 --- a/widgets/dirrequester.cpp +++ b/widgets/dirrequester.cpp @@ -39,6 +39,7 @@ DirRequester::DirRequester(QWidget *parent) button->setAutoRaise(true); button->setIcon(Icon("document-open")); connect(button, SIGNAL(clicked(bool)), SLOT(chooseDir())); + connect(edit, SIGNAL(textChanged(const QString &)), SIGNAL(textChanged(const QString &))); } void DirRequester::chooseDir() diff --git a/widgets/dirrequester.h b/widgets/dirrequester.h index a66121950..428f4d589 100644 --- a/widgets/dirrequester.h +++ b/widgets/dirrequester.h @@ -50,6 +50,9 @@ public: void setText(const QString &t) { edit->setText(t); } void setButtonVisible(bool v) { button->setVisible(v); } +Q_SIGNALS: + void textChanged(const QString &); + private Q_SLOTS: void chooseDir(); diff --git a/widgets/messagebox.h b/widgets/messagebox.h index b9a71ba47..7af2059d5 100644 --- a/widgets/messagebox.h +++ b/widgets/messagebox.h @@ -54,6 +54,9 @@ namespace MessageBox { inline void error(QWidget *parent, const QString &message, const QString &title=QString()) { QMessageBox::warning(parent, title.isEmpty() ? i18n("Error") : title, message); } + inline void information(QWidget *parent, const QString &message, const QString &title=QString()) { + QMessageBox::information(parent, title.isEmpty() ? i18n("Information") : title, message); + } void errorList(QWidget *parent, const QString &message, const QStringList &strlist, const QString &title=QString()); }; #endif