diff options
Diffstat (limited to 'tdeioslave/media')
160 files changed, 17734 insertions, 0 deletions
diff --git a/tdeioslave/media/CMakeLists.txt b/tdeioslave/media/CMakeLists.txt new file mode 100644 index 000000000..68d4bf9d6 --- /dev/null +++ b/tdeioslave/media/CMakeLists.txt @@ -0,0 +1,59 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +add_subdirectory( libmediacommon ) +add_subdirectory( mediamanager ) +add_subdirectory( medianotifier ) +add_subdirectory( mounthelper ) +add_subdirectory( tdefile-plugin ) +add_subdirectory( tdecmodule ) +add_subdirectory( mimetypes ) +add_subdirectory( services ) +add_subdirectory( propsdlgplugin ) + + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/libmediacommon + ${CMAKE_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES media.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) + + +##### kiomedia (static) ######################### + +set( target kiomedia ) + +tde_add_library( ${target} STATIC_PIC AUTOMOC + SOURCES kio_media.cpp mediaimpl.cpp mediaimpl.skel +) + + +##### kio_media (module) ######################## + +set( target kio_media ) + +tde_add_kpart( ${target} AUTOMOC + SOURCES dummy.cpp + EMBED kiomedia-static + LINK mediacommon-static tdeio-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/tdeioslave/media/Makefile.am b/tdeioslave/media/Makefile.am new file mode 100644 index 000000000..b82e48557 --- /dev/null +++ b/tdeioslave/media/Makefile.am @@ -0,0 +1,36 @@ +if include_media_halbackend +PROPSDLGPLUGINDIR = propsdlgplugin +endif + +SUBDIRS = libmediacommon . mediamanager medianotifier mounthelper \ + tdefile-plugin tdecmodule mimetypes services $(PROPSDLGPLUGINDIR) + +INCLUDES = -I$(srcdir)/libmediacommon $(all_includes) +METASOURCES = AUTO + +kde_module_LTLIBRARIES = kio_media.la + +kio_media_la_SOURCES = dummy.cpp +kio_media_la_LIBADD = libtdeiomedia.la libmediacommon/libmediacommon.la $(LIB_KIO) +kio_media_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined + +dummy.cpp: + echo > dummy.cpp + +kde_services_DATA = media.protocol + +noinst_LTLIBRARIES = libtdeiomedia.la +libtdeiomedia_la_SOURCES = kio_media.cpp mediaimpl.cpp mediaimpl.skel + +check_PROGRAMS = testmedia +testmedia_SOURCES = testmedia.cpp +testmedia_LDADD = libtdeiomedia.la $(LIB_KIO) +testmedia_LDFLAGS = $(all_libraries) + +## TODO in unsermake: TESTS = testmedia +check: testmedia + ./testmedia + +messages: rc.cpp + $(EXTRACTRC) propsdlgplugin/propertiespagegui.ui >> rc.cpp + $(XGETTEXT) *.cpp *.h tdefile-plugin/*.cpp libmediacommon/*.cpp mediamanager/*.cpp mounthelper/*.cpp propsdlgplugin/*.cpp -o $(podir)/tdeio_media.pot diff --git a/tdeioslave/media/configure.in.in b/tdeioslave/media/configure.in.in new file mode 100644 index 000000000..1f66f3b37 --- /dev/null +++ b/tdeioslave/media/configure.in.in @@ -0,0 +1,184 @@ +########### Check for linux/cdrom.h + +AC_CHECK_HEADER(linux/cdrom.h, +[ + AC_DEFINE_UNQUOTED([COMPILE_LINUXCDPOLLING], 1, [media linux cd polling compilation]) + LINUXCDPOLLING=yes + AC_SUBST(LINUXCDPOLLING) +]) + + +AC_ARG_WITH(hal,AC_HELP_STRING([--with-hal],[Enable HAL support [default=check]]),[hal_test="$withval"],[hal_test="yes"]) + +if test "x$hal_test" = "xyes" ; then + +########### Check for the HAL + AC_MSG_CHECKING(for the HAL) + + hal_inc=NOTFOUND + hal_lib=NOTFOUND + hal=NOTFOUND + + search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/hal /usr/local/include /usr/local/include/hal" + AC_FIND_FILE(libhal.h libhal-storage.h, $search_incs, hal_incdir) + + if test -r $hal_incdir/libhal.h && test -r $hal_incdir/libhal-storage.h && grep LibHalVolume $hal_incdir/libhal-storage.h > /dev/null 2>&1; then + HAL_INCS="-I$hal_incdir" + hal_inc=FOUND + fi + + search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" + AC_FIND_FILE(libhal.so libhal-storage.so, $search_libs, hal_libdir) + + if test -r $hal_libdir/libhal.so && test -r $hal_libdir/libhal-storage.so ; then + HAL_LIBS="-L$hal_libdir -lhal -lhal-storage" + hal_lib=FOUND + fi + + if test "$hal_inc" != FOUND || test "$hal_lib" != FOUND; then + KDE_PKG_CHECK_MODULES( HAL, hal > 0.5, [ HAL_INCS=$HAL_CFLAGS; hal_inc=FOUND; hal_lib=FOUND; ] , AC_MSG_RESULT(Nothing found on PKG_CONFIG_PATH) ) + fi + + if test "$hal_inc" = FOUND && test "$hal_lib" = FOUND ; then + AC_MSG_RESULT(headers $HAL_INCS libraries $HAL_LIBS) + hal=FOUND + else + AC_MSG_RESULT(searched but not found) + fi + + + AC_SUBST(HAL_INCS) + AC_SUBST(HAL_LIBS) + + +########### Check for DBus + + AC_MSG_CHECKING(for DBus) + + dbus_inc=NOTFOUND + dbus_lib=NOTFOUND + dbus=NOTFOUND + + search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" + AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir) + + search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$tdelibsuff/dbus-1.0/include /usr/local/lib$tdelibsuff/dbus-1.0/include" + AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps) + + if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then + DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps" + dbus_inc=FOUND + fi + + search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" + AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir) + + if test -r $dbus_libdir/libdbus-1.so ; then + DBUS_LIBS="-L$dbus_libdir -ldbus-1" + dbus_lib=FOUND + fi + + if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then + KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) ) + fi + + dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null` + if test -z "$dbus_bus_var"; then + dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket" + fi + AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus]) + + if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then + AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS) + dbus=FOUND + else + AC_MSG_RESULT(searched but not found) + fi + + AC_SUBST(DBUS_INCS) + AC_SUBST(DBUS_LIBS) + +########### Check for DBus-Qt3 bindings + + AC_MSG_CHECKING(for DBus-Qt3 bindings) + + dbusqt_inc=NOTFOUND + dbusqt_lib=NOTFOUND + dbusqt=NOTFOUND + + search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" + AC_FIND_FILE(dbus/connection.h, $search_incs, dbusqt_incdir) + + if test -r $dbusqt_incdir/dbus/connection.h ; then + have_qt_patch=0 + grep dbus_connection_setup_with_qt_main $dbusqt_incdir/dbus/connection.h \ + > /dev/null 2>&1 && have_qt_patch=1 + if test $have_qt_patch = 1 ; then + DBUSQT_INCS="-I$dbusqt_incdir" + dbusqt_inc=FOUND + fi + fi + + search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" + AC_FIND_FILE(libdbus-qt-1.so, $search_libs, dbusqt_libdir) + + if test -r $dbusqt_libdir/libdbus-qt-1.so ; then + DBUSQT_LIBS="-L$dbusqt_libdir -ldbus-qt-1" + dbusqt_lib=FOUND + fi + + if test $dbusqt_inc != FOUND || test $dbusqt_lib != FOUND ; then + + search_incs="`pkg-config --cflags dbus-1 |sed 's/-I//g'`" + AC_FIND_FILE(dbus/connection.h, $search_incs, dbusqt_incdir) + if test -r $dbusqt_incdir/dbus/connection.h ; then + have_qt_patch=0 + grep dbus_connection_setup_with_qt_main $dbusqt_incdir/dbus/connection.h \ + > /dev/null 2>&1 && have_qt_patch=1 + if test $have_qt_patch = 1 ; then + DBUSQT_INCS="-I$dbusqt_incdir" + dbusqt_inc=FOUND + fi + fi + + search_libs="`pkg-config --libs dbus-1 --libs-only-L | sed 's/-L//g'`" + AC_FIND_FILE(libdbus-qt-1.so, $search_libs, dbusqt_libdir) + + if test -r $dbusqt_libdir/libdbus-qt-1.so ; then + DBUSQT_LIBS="-L$dbusqt_libdir -ldbus-qt-1" + dbusqt_lib=FOUND + fi + + fi + + + if test $dbusqt_inc = FOUND && test $dbusqt_lib = FOUND ; then + AC_MSG_RESULT(headers $dbusqt_incdir libraries $dbusqt_libdir) + dbusqt=FOUND + else + AC_MSG_RESULT(searched but not found) + fi + + AC_SUBST(DBUSQT_INCS) + AC_SUBST(DBUSQT_LIBS) +fi + +########### Check if media HAL backend sould be compiled + +AC_MSG_CHECKING(if the HAL backend for media:/ should be compiled) + +HALBACKEND=no +if test "x$hal" = "xFOUND" && test "x$dbus" = "xFOUND" && test "x$dbusqt" = "xFOUND" ; then + AC_DEFINE_UNQUOTED([COMPILE_HALBACKEND],1, [media HAL backend compilation]) + HALBACKEND=yes + AC_SUBST(HALBACKEND) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +AM_CONDITIONAL(include_media_linuxcdpolling, test "$LINUXCDPOLLING" = "yes") +AM_CONDITIONAL(include_media_halbackend, test "$HALBACKEND" = yes) + +AC_CHECK_FUNCS(statvfs) + diff --git a/tdeioslave/media/contrib/README b/tdeioslave/media/contrib/README new file mode 100644 index 000000000..8f6041578 --- /dev/null +++ b/tdeioslave/media/contrib/README @@ -0,0 +1,18 @@ +Those scripts are an example on how to allow media:/ to use +hotplugging events if you don't use HAL. They're targeting +"Linux 2.6 + hotplug + udev" platforms, but we can surely make +something equivalent for Linux 2.4, FreeBSD... + +They are just examples, the packagers will surely develop their +own version (I'm currently using them on Debian Sid, Linux 2.6.9 +though). + +1) mediamanager_usbstorage.dev +This file only needs to be copied to /etc/dev.d/default + +2) usbcam +This one is a bit more complicated to install. +The file must be copied into /etc/hotplug/usb and the file +/etc/hotplug/usb/usbcam.usermap must exists (you can use +libgphoto2's print-usb-usermap command to create it) + diff --git a/tdeioslave/media/contrib/mediamanager_usbstorage.dev b/tdeioslave/media/contrib/mediamanager_usbstorage.dev new file mode 100755 index 000000000..d12a3e687 --- /dev/null +++ b/tdeioslave/media/contrib/mediamanager_usbstorage.dev @@ -0,0 +1,108 @@ +#!/bin/sh +# /etc/dev.d/default/mediamanager_usbstorage.dev +# Notify all KDE sessions (thanks to the mediamanager) that a new +# usb_storage device appeared or disappeared +# + +# to debug this script, uncomment the next line and see /tmp/mediamanager_usbstorage.debug after execution +#DEBUG=1 + +# exit immediately if /usr/bin/ is not yet available (during boot if /usr is a separate partition) +/bin/ls -d /usr/bin/ >/dev/null 2>&1 || exit + +DEBUGOUT=/tmp/mediamanager_usbstorage.debug.$$ +if [ "$DEBUG" = "1" -a -z "$2" ]; then + echo "executing $0 $@" > $DEBUGOUT + echo "with the following environment variables:" >> $DEBUGOUT + env >> $DEBUGOUT + echo "----" >> $DEBUGOUT + sh -x $0 $@ debug >> $DEBUGOUT 2>&1 + exit +fi + +# we only manage block devices +if [ "$1" != "block" ]; then exit; fi + +# we only manage usb_storage devices +if [ "$ACTION" = "add" ]; then + device="`ls /sys$DEVPATH/../device/../../../ 2> /dev/NULL | grep ':' | head -1`" + if [ -z "$device" -o ! -e /sys/bus/usb/drivers/usb-storage/$device ]; then + # The behavior is not the same for every kernel it seems. + # Testing the driver/ directory just in case. + device="`ls /sys$DEVPATH/../device/../../../driver 2> /dev/NULL | grep ':' | head -1`" + if [ -z "$device" -o ! -e /sys/bus/usb/drivers/usb-storage/$device ]; then + exit + fi + fi +fi + +# functions for syslog +LOGGER="logger -t `basename $0`[$$] -p user.notice" +write_syslog () { + echo ${@} | $LOGGER +} + +# be sure the drivers are loaded +/sbin/modprobe -q usb_storage +/sbin/modprobe -q vfat + +# create the FSH required /media directory +# See: http://www.pathname.com/fhs/pub/fhs-2.3.html#MEDIAMOUNTPOINT +MNT=media +if [ ! -d /$MNT ]; then + mkdir /$MNT + write_syslog "Created the /$MNT directory" +fi + +# we need DEVPATH, DEVNAME and ACTION, so we warn the user that executes this script by hand +if [ -z "$DEVPATH" -a -z "$DEVNAME" -a -z "$ACTION" ]; then + echo + echo "This script must be called by udevd because it needs the following environment variables: DEVPATH, DEVNAME, ACTION" + echo "So you must copy this script as /etc/dev.d/default/updfstab-2.6.dev and set it executable" + echo "See: http://www.kernel.org/pub/linux/utils/kernel/hotplug/RFC-dev.d" + echo + exit +fi + +# if $DEVPATH/device exists, we are a device, not a partition, so exit +if [ -d /sys${DEVPATH}/device ]; then exit; fi + +dcop_users="`ps aux | grep dcopserver | grep -v grep | awk '{print $1}' | sort | uniq`" + +# if the current device is being added +if [ "$ACTION" = "add" ]; then + # get partition information + partition="/sys${DEVPATH}/../device/../../.." + # We check twice again... marvelous random kernel behaviour changes... + if [ -e $partition/product ]; then + product="`cat $partition/product`" + else + product="`cat $partition/../product`" + fi + if [ -e $partition/manufacturer ]; then + manufacturer="`cat $partition/manufacturer`" + else + manufacturer="`cat $partition/../manufacturer`" + fi + + write_syslog "Invoking dcop..." + write_syslog "kded mediamanager removablePlug $DEVNAME \"$manufacturer $product\"" + + method="kded mediamanager removablePlug" + for user in $dcop_users ; do + dcop --user $user --all-sessions $method $DEVNAME "$manufacturer $product" + done + +elif [ "$ACTION" = "remove" ]; then + write_syslog "Invoking dcop..." + write_syslog "kded mediamanager removableUnplug $DEVNAME" + + method="kded mediamanager removableUnplug" + for user in $dcop_users ; do + dcop --user $user --all-sessions $method $DEVNAME + done + + umount $DEVNAME +fi + + diff --git a/tdeioslave/media/contrib/usbcam b/tdeioslave/media/contrib/usbcam new file mode 100755 index 000000000..85158d96b --- /dev/null +++ b/tdeioslave/media/contrib/usbcam @@ -0,0 +1,82 @@ +#!/bin/sh +# +# /etc/hotplug/usb/usbcam +# +# Set up newly plugged in USB camera +# Notify all KDE sessions (thanks to the mediamanager) that a +# new camera appeared or disappeared + +# to debug this script, uncomment the next line and see /tmp/usbcam.debug after execution +#DEBUG=1 + +# exit immediately if /usr/bin/ is not yet available (during boot if /usr is a separate partition) +/bin/ls -d /usr/bin/ >/dev/null 2>&1 || exit + +GROUP=camera + +if [ "${ACTION}" = "add" ] && [ -f "${DEVICE}" ] +then + chmod a-rwx "${DEVICE}" + chgrp "${GROUP}" "${DEVICE}" + chmod ug+rw "${DEVICE}" +fi + + +DEBUGOUT=/tmp/usbcam.debug.$$ +if [ "$DEBUG" = "1" -a -z "$2" ]; then + echo "executing $0 $@" > $DEBUGOUT + echo "with the following environment variables:" >> $DEBUGOUT + env >> $DEBUGOUT + echo "----" >> $DEBUGOUT + sh -x $0 $@ debug >> $DEBUGOUT 2>&1 + exit +fi + +# functions for syslog +LOGGER="logger -t `basename $0`[$$] -p user.notice" +write_syslog () { + echo ${@} | $LOGGER +} + +if [ -z "$REMOVER" ]; then + write_syslog "No remover found" + exit +fi + +dcop_users="`ps aux | grep dcopserver | grep -v grep | awk '{print $1}' | sort | uniq`" + +# if the current device is being added +if [ "$ACTION" = "add" ]; then + write_syslog "Copying remover..." + cp /etc/hotplug/usb/usbcam $REMOVER + chmod +x $REMOVER + # get camera information + camera="/sys${DEVPATH}/.." + if [ -e $camera/product ]; then product="`cat $camera/product`"; fi + if [ -e $camera/manufacturer ]; then manufacturer="`cat $camera/manufacturer`"; fi + + write_syslog "Invoking dcop..." + write_syslog "kded mediamanager removableCamera $DEVICE \"$manufacturer $product\"" + + method="kded mediamanager removablePlug" + for user in $dcop_users ; do + dcop --user $user --all-sessions $method $DEVICE "$manufacturer $product" + done + + method="kded mediamanager removableCamera" + for user in $dcop_users ; do + dcop --user $user --all-sessions $method $DEVICE + done + +elif [ "$ACTION" = "remove" ]; then + write_syslog "Invoking dcop..." + write_syslog "kded mediamanager removableUnplug $DEVICE" + + method="kded mediamanager removableUnplug" + for user in $dcop_users ; do + dcop --user $user --all-sessions $method $DEVICE + done + +fi + + diff --git a/tdeioslave/media/dummy.cpp b/tdeioslave/media/dummy.cpp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tdeioslave/media/dummy.cpp @@ -0,0 +1 @@ + diff --git a/tdeioslave/media/kio_media.cpp b/tdeioslave/media/kio_media.cpp new file mode 100644 index 000000000..d1647c6fc --- /dev/null +++ b/tdeioslave/media/kio_media.cpp @@ -0,0 +1,276 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens <ervin ipsquad net> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <stdlib.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kapplication.h> +#include <dcopclient.h> +#include <kcmdlineargs.h> + +#include <tqeventloop.h> + +#include "mediaimpl.h" +#include "kio_media.h" + + +static const KCmdLineOptions options[] = +{ + { "+protocol", I18N_NOOP( "Protocol name" ), 0 }, + { "+pool", I18N_NOOP( "Socket name" ), 0 }, + { "+app", I18N_NOOP( "Socket name" ), 0 }, + KCmdLineLastOption +}; + +extern "C" { + int KDE_EXPORT kdemain( int argc, char **argv ) + { + // TDEApplication is necessary to use other ioslaves + putenv(strdup("SESSION_MANAGER=")); + TDECmdLineArgs::init(argc, argv, "kio_media", 0, 0, 0, 0); + TDECmdLineArgs::addCmdLineOptions( options ); + TDEApplication app( false, false ); + // We want to be anonymous even if we use DCOP + app.dcopClient()->attach(); + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + MediaProtocol slave( args->arg(0), args->arg(1), args->arg(2) ); + slave.dispatchLoop(); + return 0; + } +} + + +MediaProtocol::MediaProtocol(const TQCString &protocol, + const TQCString &pool, const TQCString &app) + : ForwardingSlaveBase(protocol, pool, app) +{ + connect( &m_impl, TQT_SIGNAL( warning( const TQString & ) ), + this, TQT_SLOT( slotWarning( const TQString & ) ) ); +} + +MediaProtocol::~MediaProtocol() +{ +} + +bool MediaProtocol::rewriteURL(const KURL &url, KURL &newUrl) +{ + TQString name, path; + + if ( !m_impl.parseURL(url, name, path) ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return false; + } + + + if ( !m_impl.realURL(name, path, newUrl) ) + { + error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); + return false; + } + + return true; +} + +void MediaProtocol::put(const KURL &url, int permissions, + bool overwrite, bool resume) +{ + kdDebug(1219) << "MediaProtocol::put: " << url << endl; + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( ok && path.isEmpty() ) + { + error(TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, url.prettyURL()); + } + else + { + ForwardingSlaveBase::put(url, permissions, overwrite, resume); + } +} + +void MediaProtocol::rename(const KURL &src, const KURL &dest, bool overwrite) +{ + kdDebug(1219) << "MediaProtocol::rename: " << src << ", " << dest << ", " + << overwrite << endl; + + TQString src_name, src_path; + bool ok = m_impl.parseURL(src, src_name, src_path); + TQString dest_name, dest_path; + ok &= m_impl.parseURL(dest, dest_name, dest_path); + + if ( ok && src_path.isEmpty() && dest_path.isEmpty() + && src.protocol() == "media" && dest.protocol() == "media" ) + { + if (!m_impl.setUserLabel(src_name, dest_name)) + { + error(m_impl.lastErrorCode(), m_impl.lastErrorMessage()); + } + else + { + finished(); + } + } + else + { + ForwardingSlaveBase::rename(src, dest, overwrite); + } +} + +void MediaProtocol::mkdir(const KURL &url, int permissions) +{ + kdDebug(1219) << "MediaProtocol::mkdir: " << url << endl; + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( ok && path.isEmpty() ) + { + error(TDEIO::ERR_COULD_NOT_MKDIR, url.prettyURL()); + } + else + { + ForwardingSlaveBase::mkdir(url, permissions); + } +} + +void MediaProtocol::del(const KURL &url, bool isFile) +{ + kdDebug(1219) << "MediaProtocol::del: " << url << endl; + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( ok && path.isEmpty() ) + { + error(TDEIO::ERR_CANNOT_DELETE, url.prettyURL()); + } + else + { + ForwardingSlaveBase::del(url, isFile); + } +} + +void MediaProtocol::stat(const KURL &url) +{ + kdDebug(1219) << "MediaProtocol::stat: " << url << endl; + TQString path = url.path(); + if( path.isEmpty() || path == "/" ) + { + // The root is "virtual" - it's not a single physical directory + TDEIO::UDSEntry entry; + m_impl.createTopLevelEntry( entry ); + statEntry( entry ); + finished(); + return; + } + + TQString name; + bool ok = m_impl.parseURL(url, name, path); + + if ( !ok ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; + } + + if( path.isEmpty() ) + { + TDEIO::UDSEntry entry; + + if ( m_impl.statMedium(name, entry) + || m_impl.statMediumByLabel(name, entry) ) + { + statEntry(entry); + finished(); + } + else + { + error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); + } + } + else + { + ForwardingSlaveBase::stat(url); + } +} + +void MediaProtocol::listDir(const KURL &url) +{ + kdDebug(1219) << "MediaProtocol::listDir: " << url << endl; + + if ( url.path().length() <= 1 ) + { + listRoot(); + return; + } + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( !ok ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; + } + + ForwardingSlaveBase::listDir(url); +} + +void MediaProtocol::listRoot() +{ + TDEIO::UDSEntry entry; + + TDEIO::UDSEntryList media_entries; + bool ok = m_impl.listMedia(media_entries); + + if (!ok) + { + error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); + return; + } + + totalSize(media_entries.count()+1); + + m_impl.createTopLevelEntry(entry); + listEntry(entry, false); + + TDEIO::UDSEntryListIterator it = media_entries.begin(); + TDEIO::UDSEntryListIterator end = media_entries.end(); + + for(; it!=end; ++it) + { + listEntry(*it, false); + } + + entry.clear(); + listEntry(entry, true); + + finished(); +} + +void MediaProtocol::slotWarning( const TQString &msg ) +{ + warning( msg ); +} + +#include "kio_media.moc" diff --git a/tdeioslave/media/kio_media.h b/tdeioslave/media/kio_media.h new file mode 100644 index 000000000..bf1325475 --- /dev/null +++ b/tdeioslave/media/kio_media.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens <ervin ipsquad net> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _KIO_MEDIA_H_ +#define _KIO_MEDIA_H_ + +#include <tdeio/forwardingslavebase.h> + +#include "mediaimpl.h" + +class MediaProtocol : public TDEIO::ForwardingSlaveBase +{ +Q_OBJECT +public: + MediaProtocol(const TQCString &protocol, const TQCString &pool, + const TQCString &app); + virtual ~MediaProtocol(); + + virtual bool rewriteURL(const KURL &url, KURL &newUrl); + + virtual void put(const KURL &url, int permissions, + bool overwrite, bool resume); + virtual void rename(const KURL &src, const KURL &dest, bool overwrite); + virtual void mkdir(const KURL &url, int permissions); + virtual void del(const KURL &url, bool isFile); + virtual void stat(const KURL &url); + virtual void listDir(const KURL &url); + +private slots: + void slotWarning( const TQString &msg ); + +private: + void listRoot(); + + MediaImpl m_impl; +}; + +#endif diff --git a/tdeioslave/media/libmediacommon/CMakeLists.txt b/tdeioslave/media/libmediacommon/CMakeLists.txt new file mode 100644 index 000000000..2059e35a8 --- /dev/null +++ b/tdeioslave/media/libmediacommon/CMakeLists.txt @@ -0,0 +1,41 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES mediamanagersettings.kcfg DESTINATION ${KCFG_INSTALL_DIR} ) + + +##### mediacommon (static) ###################### + +set( target mediacommon ) + +set( ${target}_SRCS + medium.cpp actionlistboxitem.cpp notifieraction.cpp + notifierserviceaction.cpp notifiernothingaction.cpp + notifieropenaction.cpp notifiersettings.cpp + mediamanagersettings.kcfgc +) + +tde_add_library( ${target} STATIC_PIC AUTOMOC + SOURCES ${${target}_SRCS} +) diff --git a/tdeioslave/media/libmediacommon/Makefile.am b/tdeioslave/media/libmediacommon/Makefile.am new file mode 100644 index 000000000..dd27d265a --- /dev/null +++ b/tdeioslave/media/libmediacommon/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = $(all_includes) +METASOURCES = AUTO + +noinst_LTLIBRARIES = libmediacommon.la +libmediacommon_la_SOURCES = medium.cpp actionlistboxitem.cpp \ + notifieraction.cpp notifierserviceaction.cpp \ + notifiernothingaction.cpp notifieropenaction.cpp \ + notifiersettings.cpp mediamanagersettings.kcfgc + +kde_kcfg_DATA = mediamanagersettings.kcfg + diff --git a/tdeioslave/media/libmediacommon/actionlistboxitem.cpp b/tdeioslave/media/libmediacommon/actionlistboxitem.cpp new file mode 100644 index 000000000..271d2e487 --- /dev/null +++ b/tdeioslave/media/libmediacommon/actionlistboxitem.cpp @@ -0,0 +1,47 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "actionlistboxitem.h" + +#include <klocale.h> + +#include <tqpixmap.h> + +ActionListBoxItem::ActionListBoxItem(NotifierAction *action, TQString mimetype, TQListBox *parent) + : TQListBoxPixmap(parent, action->pixmap()), + m_action(action) +{ + TQString text = m_action->label(); + + if ( m_action->autoMimetypes().contains( mimetype ) ) + { + text += " (" + i18n( "Auto Action" ) + ")"; + } + + setText( text ); +} + +ActionListBoxItem::~ActionListBoxItem() +{ +} + +NotifierAction *ActionListBoxItem::action() const +{ + return m_action; +} diff --git a/tdeioslave/media/libmediacommon/actionlistboxitem.h b/tdeioslave/media/libmediacommon/actionlistboxitem.h new file mode 100644 index 000000000..254f065de --- /dev/null +++ b/tdeioslave/media/libmediacommon/actionlistboxitem.h @@ -0,0 +1,40 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 K�vin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _ACTIONLISTBOXITEM_H_ +#define _ACTIONLISTBOXITEM_H_ + +#include <tqlistbox.h> +#include <tqstring.h> + +#include "notifieraction.h" + +class ActionListBoxItem : public TQListBoxPixmap +{ +public: + ActionListBoxItem(NotifierAction *action, TQString mimetype, TQListBox *parent); + ~ActionListBoxItem(); + + NotifierAction *action() const; + +private: + NotifierAction *m_action; +}; + +#endif diff --git a/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg b/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg new file mode 100644 index 000000000..2994680cd --- /dev/null +++ b/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd"> + +<kcfg> + <kcfgfile name="mediamanagerrc"/> + <group name="Global"> + <entry name="HalBackendEnabled" type="Bool"> + <label>Enable HAL backend</label> + <whatsthis>When HAL (Hardware Abstraction Layer) support is enabled, TDE will use it to gather information on the storage media available in your system.</whatsthis> + <default>true</default> + </entry> + <entry name="TdeHardwareBackendEnabled" type="Bool"> + <label>Enable TDE hardware library backend</label> + <whatsthis>When TDE hardware library support is enabled, TDE will use it to gather information on the storage media available in your system.</whatsthis> + <default>true</default> + </entry> + <entry name="CdPollingEnabled" type="Bool"> + <label>Enable CD polling</label> + <whatsthis>Allows TDE to poll CD-Rom or DVD-Rom drives itself in order to detect medium insert.</whatsthis> + <default>true</default> + </entry> + <entry name="AutostartEnabled" type="Bool"> + <label>Enable medium application autostart after mount</label> + <whatsthis>Allows TDE to autostart application after a medium mount if it contains an Autostart or an Autoopen file.</whatsthis> + <default>true</default> + </entry> + </group> +</kcfg> diff --git a/tdeioslave/media/libmediacommon/mediamanagersettings.kcfgc b/tdeioslave/media/libmediacommon/mediamanagersettings.kcfgc new file mode 100644 index 000000000..bbc58d92e --- /dev/null +++ b/tdeioslave/media/libmediacommon/mediamanagersettings.kcfgc @@ -0,0 +1,4 @@ +File=mediamanagersettings.kcfg +ClassName=MediaManagerSettings +Singleton=true +Mutators=true diff --git a/tdeioslave/media/libmediacommon/medium.cpp b/tdeioslave/media/libmediacommon/medium.cpp new file mode 100644 index 000000000..7b97fb1a0 --- /dev/null +++ b/tdeioslave/media/libmediacommon/medium.cpp @@ -0,0 +1,268 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "medium.h" + +#include <tdeconfig.h> +#include <klocale.h> + +const TQString Medium::SEPARATOR = "---"; + +Medium::Medium(const TQString id, TQString uuid, const TQString name) +{ + m_properties+= id; /* ID */ + m_properties+= uuid; /* UUID */ + m_properties+= name; /* NAME */ + m_properties+= name; /* LABEL */ + m_properties+= TQString::null; /* USER_LABEL */ + + m_properties+= "false"; /* MOUNTABLE */ + m_properties+= TQString::null; /* DEVICE_NODE */ + m_properties+= TQString::null; /* MOUNT_POINT */ + m_properties+= TQString::null; /* FS_TYPE */ + m_properties+= "false"; /* MOUNTED */ + m_properties+= TQString::null; /* BASE_URL */ + m_properties+= TQString::null; /* MIME_TYPE */ + m_properties+= TQString::null; /* ICON_NAME */ + m_properties+= "false"; /* ENCRYPTED */ + m_properties+= TQString::null; /* CLEAR_DEVICE_UDI */ + m_properties+= "false"; /* HIDDEN */ + + loadUserLabel(); + + m_halmounted = false; +} + +Medium::Medium() +{ + m_properties+= TQString::null; /* ID */ + m_properties+= TQString::null; /* UUID */ + m_properties+= TQString::null; /* NAME */ + m_properties+= TQString::null; /* LABEL */ + m_properties+= TQString::null; /* USER_LABEL */ + + m_properties+= TQString::null; /* MOUNTABLE */ + m_properties+= TQString::null; /* DEVICE_NODE */ + m_properties+= TQString::null; /* MOUNT_POINT */ + m_properties+= TQString::null; /* FS_TYPE */ + m_properties+= TQString::null; /* MOUNTED */ + m_properties+= TQString::null; /* BASE_URL */ + m_properties+= TQString::null; /* MIME_TYPE */ + m_properties+= TQString::null; /* ICON_NAME */ + m_properties+= TQString::null; /* ENCRYPTED */ + m_properties+= TQString::null; /* CLEAR_DEVICE_UDI */ + m_properties+= "false"; /* HIDDEN */ + + m_halmounted = false; +} + +const Medium Medium::create(const TQStringList &properties) +{ + Medium m; + + if ( properties.size() >= PROPERTIES_COUNT ) + { + m.m_properties[ID] = properties[ID]; + m.m_properties[UUID] = properties[UUID]; + m.m_properties[NAME] = properties[NAME]; + m.m_properties[LABEL] = properties[LABEL]; + m.m_properties[USER_LABEL] = properties[USER_LABEL]; + + m.m_properties[MOUNTABLE] = properties[MOUNTABLE]; + m.m_properties[DEVICE_NODE] = properties[DEVICE_NODE]; + m.m_properties[MOUNT_POINT] = properties[MOUNT_POINT]; + m.m_properties[FS_TYPE] = properties[FS_TYPE]; + m.m_properties[MOUNTED] = properties[MOUNTED]; + m.m_properties[BASE_URL] = properties[BASE_URL]; + m.m_properties[MIME_TYPE] = properties[MIME_TYPE]; + m.m_properties[ICON_NAME] = properties[ICON_NAME]; + m.m_properties[ENCRYPTED] = properties[ENCRYPTED]; + m.m_properties[CLEAR_DEVICE_UDI] = properties[CLEAR_DEVICE_UDI]; + m.m_properties[HIDDEN] = properties[HIDDEN]; + } + + return m; +} + +Medium::MList Medium::createList(const TQStringList &properties) +{ + MList l; + + if ( properties.size() % (PROPERTIES_COUNT+1) == 0) + { + int media_count = properties.size()/(PROPERTIES_COUNT+1); + + TQStringList props = properties; + + for(int i=0; i<media_count; i++) + { + const Medium m = create(props); + l.append(m); + + TQStringList::iterator first = props.begin(); + TQStringList::iterator last = props.find(SEPARATOR); + ++last; + props.erase(first, last); + } + } + + return l; +} + + +void Medium::setName(const TQString &name) +{ + m_properties[NAME] = name; +} + +void Medium::setLabel(const TQString &label) +{ + m_properties[LABEL] = label; +} + +void Medium::setEncrypted(bool state) +{ + m_properties[ENCRYPTED] = ( state ? "true" : "false" ); +} + +void Medium::setHidden(bool state) +{ + m_properties[HIDDEN] = ( state ? "true" : "false" ); +} + +void Medium::setUserLabel(const TQString &label) +{ + TDEConfig cfg("mediamanagerrc"); + cfg.setGroup("UserLabels"); + + TQString entry_name = m_properties[UUID]; + + if ( label.isNull() ) + { + cfg.deleteEntry(entry_name); + } + else + { + cfg.writeEntry(entry_name, label); + } + + m_properties[USER_LABEL] = label; +} + +void Medium::loadUserLabel() +{ + TDEConfig cfg("mediamanagerrc"); + cfg.setGroup("UserLabels"); + + TQString entry_name = m_properties[UUID]; + + if ( cfg.hasKey(entry_name) ) + { + m_properties[USER_LABEL] = cfg.readEntry(entry_name); + } + else + { + m_properties[USER_LABEL] = TQString::null; + } +} + + +bool Medium::mountableState(bool mounted) +{ + if ( m_properties[DEVICE_NODE].isEmpty() + || ( mounted && m_properties[MOUNT_POINT].isEmpty() ) ) + { + return false; + } + + m_properties[MOUNTABLE] = "true"; + m_properties[MOUNTED] = ( mounted ? "true" : "false" ); + + return true; +} + +void Medium::mountableState(const TQString &deviceNode, + const TQString &mountPoint, + const TQString &fsType, bool mounted) +{ + m_properties[MOUNTABLE] = "true"; + m_properties[DEVICE_NODE] = deviceNode; + m_properties[MOUNT_POINT] = mountPoint; + m_properties[FS_TYPE] = fsType; + m_properties[MOUNTED] = ( mounted ? "true" : "false" ); +} + +void Medium::mountableState(const TQString &deviceNode, + const TQString &clearDeviceUdi, + const TQString &mountPoint, + const TQString &fsType, bool mounted) +{ + m_properties[MOUNTABLE] = "true"; + m_properties[DEVICE_NODE] = deviceNode; + m_properties[CLEAR_DEVICE_UDI] = clearDeviceUdi; + m_properties[MOUNT_POINT] = mountPoint; + m_properties[FS_TYPE] = fsType; + m_properties[MOUNTED] = ( mounted ? "true" : "false" ); +} + +void Medium::unmountableState(const TQString &baseURL) +{ + m_properties[MOUNTABLE] = "false"; + m_properties[BASE_URL] = baseURL; +} + +void Medium::setMimeType(const TQString &mimeType) +{ + m_properties[MIME_TYPE] = mimeType; +} + +void Medium::setIconName(const TQString &iconName) +{ + m_properties[ICON_NAME] = iconName; +} + +bool Medium::needMounting() const +{ + return isMountable() && !isMounted(); +} + +bool Medium::needDecryption() const +{ + return isEncrypted() && clearDeviceUdi().isEmpty(); +} + +KURL Medium::prettyBaseURL() const +{ + if ( !baseURL().isEmpty() ) + return baseURL(); + + return KURL( mountPoint() ); +} + +TQString Medium::prettyLabel() const +{ + if ( !userLabel().isEmpty() ) + { + return userLabel(); + } + else + { + return label(); + } +} + diff --git a/tdeioslave/media/libmediacommon/medium.h b/tdeioslave/media/libmediacommon/medium.h new file mode 100644 index 000000000..e45dccbfd --- /dev/null +++ b/tdeioslave/media/libmediacommon/medium.h @@ -0,0 +1,127 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 K�vin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _MEDIUM_H_ +#define _MEDIUM_H_ + +#include <tqstring.h> +#include <tqstringlist.h> +#include <kurl.h> +#include <tqmap.h> + +class Medium +{ +public: + typedef TQValueList<Medium> MList; + + static const uint ID = 0; + static const uint UUID = 1; + static const uint NAME = 2; + static const uint LABEL = 3; + static const uint USER_LABEL = 4; + static const uint MOUNTABLE = 5; + static const uint DEVICE_NODE = 6; + static const uint MOUNT_POINT = 7; + static const uint FS_TYPE = 8; + static const uint MOUNTED = 9; + static const uint BASE_URL = 10; + static const uint MIME_TYPE = 11; + static const uint ICON_NAME = 12; + static const uint ENCRYPTED = 13; + static const uint CLEAR_DEVICE_UDI = 14; + static const uint HIDDEN = 15; + static const uint PROPERTIES_COUNT = 16; + static const TQString SEPARATOR; + + Medium(const TQString id, TQString uuid, const TQString name); + static const Medium create(const TQStringList &properties); + static MList createList(const TQStringList &properties); + + const TQStringList &properties() const { return m_properties; } + + TQString id() const { return m_properties[ID]; } + TQString uuid() const { return m_properties[UUID]; } + TQString name() const { return m_properties[NAME]; } + TQString label() const { return m_properties[LABEL]; } + TQString userLabel() const { return m_properties[USER_LABEL]; } + bool isMountable() const { return m_properties[MOUNTABLE]=="true"; } + TQString deviceNode() const { return m_properties[DEVICE_NODE]; } + TQString mountPoint() const { return m_properties[MOUNT_POINT]; } + TQString fsType() const { return m_properties[FS_TYPE]; } + bool isMounted() const { return m_properties[MOUNTED]=="true"; } + TQString baseURL() const { return m_properties[BASE_URL]; } + TQString mimeType() const { return m_properties[MIME_TYPE]; } + TQString iconName() const { return m_properties[ICON_NAME]; } + bool isEncrypted() const { return m_properties[ENCRYPTED]=="true"; }; + TQString clearDeviceUdi() const { return m_properties[CLEAR_DEVICE_UDI]; }; + bool hidden() const { return m_properties[HIDDEN]=="true"; }; + + bool needMounting() const; + bool needDecryption() const; + KURL prettyBaseURL() const; + TQString prettyLabel() const; + + void setName(const TQString &name); + void setLabel(const TQString &label); + void setUserLabel(const TQString &label); + void setEncrypted(bool state); + void setHidden(bool state); + + bool mountableState(bool mounted); + void mountableState(const TQString &deviceNode, + const TQString &mountPoint, + const TQString &fsType, bool mounted); + void mountableState(const TQString &deviceNode, + const TQString &clearDeviceUdi, + const TQString &mountPoint, + const TQString &fsType, bool mounted); + void unmountableState(const TQString &baseURL = TQString::null); + + void setMimeType(const TQString &mimeType); + void setIconName(const TQString &iconName); + void setHalMounted(bool flag) const { m_halmounted = flag; } + bool halMounted() const { return m_halmounted; } + +//private: + Medium(); + +private: + void loadUserLabel(); + + TQStringList m_properties; + mutable bool m_halmounted; + +friend class TQValueListNode<const Medium>; +}; + +namespace MediaManagerUtils { + static inline TQMap<TQString,TQString> splitOptions(const TQStringList & options) + { + TQMap<TQString,TQString> valids; + + for (TQStringList::ConstIterator it = options.begin(); it != options.end(); ++it) + { + TQString key = (*it).left((*it).find('=')); + TQString value = (*it).mid((*it).find('=') + 1); + valids[key] = value; + } + return valids; + } +} + +#endif diff --git a/tdeioslave/media/libmediacommon/notifieraction.cpp b/tdeioslave/media/libmediacommon/notifieraction.cpp new file mode 100644 index 000000000..0dfc4110e --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifieraction.cpp @@ -0,0 +1,97 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "notifieraction.h" + +#include <tqfile.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kicontheme.h> + +NotifierAction::NotifierAction() +{ +} + +NotifierAction::~NotifierAction() +{ +} + +void NotifierAction::setIconName(const TQString &iconName) +{ + m_iconName = iconName; +} + +void NotifierAction::setLabel(const TQString &label) +{ + m_label = label; +} + +TQString NotifierAction::iconName() const +{ + return m_iconName; +} + +TQPixmap NotifierAction::pixmap() const +{ + TQFile f( m_iconName ); + + if ( f.exists() ) + { + return TQPixmap( m_iconName ); + } + else + { + TQString path = TDEGlobal::iconLoader()->iconPath( m_iconName, -32 ); + return TQPixmap( path ); + } +} + +TQString NotifierAction::label() const +{ + return m_label; +} + +void NotifierAction::addAutoMimetype( const TQString &mimetype ) +{ + if ( !m_autoMimetypes.contains( mimetype ) ) + { + m_autoMimetypes.append( mimetype ); + } +} + +void NotifierAction::removeAutoMimetype( const TQString &mimetype ) +{ + m_autoMimetypes.remove( mimetype ); +} + +TQStringList NotifierAction::autoMimetypes() +{ + return m_autoMimetypes; +} + +bool NotifierAction::isWritable() const +{ + return false; +} + +bool NotifierAction::supportsMimetype(const TQString &/*mimetype*/) const +{ + return true; +} + diff --git a/tdeioslave/media/libmediacommon/notifieraction.h b/tdeioslave/media/libmediacommon/notifieraction.h new file mode 100644 index 000000000..0b8a87cac --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifieraction.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _NOTIFIERACTION_H_ +#define _NOTIFIERACTION_H_ + +#include <tdefileitem.h> +#include <tqstring.h> +#include <tqpixmap.h> + +class NotifierSettings; + +class NotifierAction +{ +public: + NotifierAction(); + virtual ~NotifierAction(); + + virtual TQString label() const; + virtual TQString iconName() const; + virtual void setLabel( const TQString &label ); + virtual void setIconName( const TQString &icon ); + + TQPixmap pixmap() const; + + TQStringList autoMimetypes(); + + virtual TQString id() const = 0; + virtual bool isWritable() const; + virtual bool supportsMimetype( const TQString &mimetype ) const; + virtual void execute( KFileItem &medium ) = 0; + +private: + void addAutoMimetype( const TQString &mimetype ); + void removeAutoMimetype( const TQString &mimetype ); + + TQString m_label; + TQString m_iconName; + TQStringList m_autoMimetypes; + + friend class NotifierSettings; +}; + +#endif diff --git a/tdeioslave/media/libmediacommon/notifiernothingaction.cpp b/tdeioslave/media/libmediacommon/notifiernothingaction.cpp new file mode 100644 index 000000000..6a86ad92f --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifiernothingaction.cpp @@ -0,0 +1,39 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "notifiernothingaction.h" + +#include <klocale.h> + +NotifierNothingAction::NotifierNothingAction() + : NotifierAction() +{ + setIconName("button_cancel"); + setLabel(i18n("Do Nothing")); +} + +TQString NotifierNothingAction::id() const +{ + return "#NothinAction"; +} + +void NotifierNothingAction::execute(KFileItem &/*medium*/) +{ +} + diff --git a/tdeioslave/media/libmediacommon/notifiernothingaction.h b/tdeioslave/media/libmediacommon/notifiernothingaction.h new file mode 100644 index 000000000..2c0d22cfb --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifiernothingaction.h @@ -0,0 +1,34 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _NOTIFIERNOTHINGACTION_H_ +#define _NOTIFIERNOTHINGACTION_H_ + +#include "notifieraction.h" + +class NotifierNothingAction : public NotifierAction +{ +public: + NotifierNothingAction(); + virtual TQString id() const; + virtual void execute(KFileItem &medium); +}; + +#endif + diff --git a/tdeioslave/media/libmediacommon/notifieropenaction.cpp b/tdeioslave/media/libmediacommon/notifieropenaction.cpp new file mode 100644 index 000000000..4d6d8025c --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifieropenaction.cpp @@ -0,0 +1,45 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "notifieropenaction.h" + +#include <klocale.h> + +NotifierOpenAction::NotifierOpenAction() + : NotifierAction() +{ + setIconName("window_new"); + setLabel(i18n("Open in New Window")); +} + +TQString NotifierOpenAction::id() const +{ + return "#OpenAction"; +} + +void NotifierOpenAction::execute(KFileItem &medium) +{ + medium.run(); +} + +bool NotifierOpenAction::supportsMimetype( const TQString &mimetype ) const +{ + return !mimetype.contains( "blank" ) && !mimetype.contains( "encrypted" ); +} + diff --git a/tdeioslave/media/libmediacommon/notifieropenaction.h b/tdeioslave/media/libmediacommon/notifieropenaction.h new file mode 100644 index 000000000..4fe8a614e --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifieropenaction.h @@ -0,0 +1,34 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _NOTIFIEROPENACTION_H_ +#define _NOTIFIEROPENACTION_H_ + +#include "notifieraction.h" + +class NotifierOpenAction : public NotifierAction +{ +public: + NotifierOpenAction(); + virtual TQString id() const; + virtual void execute(KFileItem &medium); + bool supportsMimetype( const TQString &mimetype ) const; +}; + +#endif diff --git a/tdeioslave/media/libmediacommon/notifierserviceaction.cpp b/tdeioslave/media/libmediacommon/notifierserviceaction.cpp new file mode 100644 index 000000000..c7bece4f8 --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifierserviceaction.cpp @@ -0,0 +1,166 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "notifierserviceaction.h" + +#include <tqdir.h> +#include <tqfile.h> +#include <tqfileinfo.h> +#include <kstddirs.h> +#include <kdesktopfile.h> +#include <klocale.h> + +NotifierServiceAction::NotifierServiceAction() + : NotifierAction() +{ + NotifierAction::setIconName("button_cancel"); + NotifierAction::setLabel(i18n("Unknown")); + + m_service.m_strName = "New Service"; + m_service.m_strIcon = "button_cancel"; + m_service.m_strExec = "konqueror %u"; +} + +TQString NotifierServiceAction::id() const +{ + if (m_filePath.isEmpty() || m_service.m_strName.isEmpty()) + { + return TQString(); + } + else + { + return "#Service:"+m_filePath; + } +} + +void NotifierServiceAction::setIconName( const TQString &icon ) +{ + m_service.m_strIcon = icon; + NotifierAction::setIconName( icon ); +} + +void NotifierServiceAction::setLabel( const TQString &label ) +{ + m_service.m_strName = label; + NotifierAction::setLabel( label ); + + updateFilePath(); +} + +void NotifierServiceAction::execute(KFileItem &medium) +{ + KURL::List urls = KURL::List( medium.url() ); + KDEDesktopMimeType::executeService( urls, m_service ); +} + +void NotifierServiceAction::setService(KDEDesktopMimeType::Service service) +{ + NotifierAction::setIconName( service.m_strIcon ); + NotifierAction::setLabel( service.m_strName ); + + m_service = service; + + updateFilePath(); +} + +KDEDesktopMimeType::Service NotifierServiceAction::service() const +{ + return m_service; +} + +void NotifierServiceAction::setFilePath(const TQString &filePath) +{ + m_filePath = filePath; +} + +TQString NotifierServiceAction::filePath() const +{ + return m_filePath; +} + +void NotifierServiceAction::updateFilePath() +{ + if ( !m_filePath.isEmpty() ) return; + + TQString action_name = m_service.m_strName; + action_name.replace( " ", "_" ); + + TQDir actions_dir( locateLocal( "data", "konqueror/servicemenus/", true ) ); + + TQString filename = actions_dir.absFilePath( action_name + ".desktop" ); + + int counter = 1; + while ( TQFile::exists( filename ) ) + { + filename = actions_dir.absFilePath( action_name + + TQString::number( counter ) + + ".desktop" ); + counter++; + } + + m_filePath = filename; +} + +void NotifierServiceAction::setMimetypes(const TQStringList &mimetypes) +{ + m_mimetypes = mimetypes; +} + +TQStringList NotifierServiceAction::mimetypes() +{ + return m_mimetypes; +} + +bool NotifierServiceAction::isWritable() const +{ + TQFileInfo info( m_filePath ); + + if ( info.exists() ) + { + return info.isWritable(); + } + else + { + info = TQFileInfo( info.dirPath() ); + return info.isWritable(); + } +} + +bool NotifierServiceAction::supportsMimetype(const TQString &mimetype) const +{ + return m_mimetypes.contains(mimetype); +} + +void NotifierServiceAction::save() const +{ + TQFile::remove( m_filePath ); + KDesktopFile desktopFile(m_filePath); + + desktopFile.setGroup(TQString("Desktop Action ") + m_service.m_strName); + desktopFile.writeEntry(TQString("Icon"), m_service.m_strIcon); + desktopFile.writeEntry(TQString("Name"), m_service.m_strName); + desktopFile.writeEntry(TQString("Exec"), m_service.m_strExec); + + desktopFile.setDesktopGroup(); + + desktopFile.writeEntry(TQString("ServiceTypes"), m_mimetypes, ","); + desktopFile.writeEntry(TQString("Actions"), + TQStringList(m_service.m_strName),";"); +} + diff --git a/tdeioslave/media/libmediacommon/notifierserviceaction.h b/tdeioslave/media/libmediacommon/notifierserviceaction.h new file mode 100644 index 000000000..829193fba --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifierserviceaction.h @@ -0,0 +1,61 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _NOTIFIERSERVICEACTION_H_ +#define _NOTIFIERSERVICEACTION_H_ + +#include <kmimetype.h> +#include <tqstring.h> + +#include "notifieraction.h" + +class NotifierServiceAction : public NotifierAction +{ +public: + NotifierServiceAction(); + virtual TQString id() const; + virtual void execute(KFileItem &item); + + virtual void setIconName( const TQString &icon ); + virtual void setLabel( const TQString &label ); + + void setService(KDEDesktopMimeType::Service service); + KDEDesktopMimeType::Service service() const; + + void setFilePath(const TQString &filePath); + TQString filePath() const; + + void setMimetypes(const TQStringList &mimetypes); + TQStringList mimetypes(); + + virtual bool isWritable() const; + virtual bool supportsMimetype(const TQString &mimetype) const; + + void save() const; + +private: + void updateFilePath(); + + KDEDesktopMimeType::Service m_service; + TQString m_filePath; + TQStringList m_mimetypes; +}; + +#endif + diff --git a/tdeioslave/media/libmediacommon/notifiersettings.cpp b/tdeioslave/media/libmediacommon/notifiersettings.cpp new file mode 100644 index 000000000..254e591cb --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifiersettings.cpp @@ -0,0 +1,391 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "notifiersettings.h" + +#include <kglobal.h> +#include <kdesktopfile.h> +#include <kstandarddirs.h> +#include <tqdir.h> +#include <tqfile.h> + +#include "notifieropenaction.h" +#include "notifiernothingaction.h" + + +NotifierSettings::NotifierSettings() +{ + m_supportedMimetypes.append( "media/removable_unmounted" ); + m_supportedMimetypes.append( "media/removable_unmounted_encrypted" ); + m_supportedMimetypes.append( "media/removable_unmounted_decrypted" ); + m_supportedMimetypes.append( "media/removable_mounted" ); + m_supportedMimetypes.append( "media/removable_mounted_decrypted" ); + m_supportedMimetypes.append( "media/camera_unmounted" ); + m_supportedMimetypes.append( "media/camera_mounted" ); + m_supportedMimetypes.append( "media/gphoto2camera" ); + m_supportedMimetypes.append( "media/cdrom_unmounted" ); + m_supportedMimetypes.append( "media/cdrom_unmounted_encrypted" ); + m_supportedMimetypes.append( "media/cdrom_unmounted_decrypted" ); + m_supportedMimetypes.append( "media/cdrom_mounted" ); + m_supportedMimetypes.append( "media/cdrom_mounted_decrypted" ); + m_supportedMimetypes.append( "media/dvd_unmounted" ); + m_supportedMimetypes.append( "media/dvd_unmounted_encrypted" ); + m_supportedMimetypes.append( "media/dvd_unmounted_decrypted" ); + m_supportedMimetypes.append( "media/dvd_mounted" ); + m_supportedMimetypes.append( "media/dvd_mounted_decrypted" ); + m_supportedMimetypes.append( "media/cdwriter_unmounted" ); + m_supportedMimetypes.append( "media/cdwriter_unmounted_encrypted" ); + m_supportedMimetypes.append( "media/cdwriter_unmounted_decrypted" ); + m_supportedMimetypes.append( "media/cdwriter_mounted" ); + m_supportedMimetypes.append( "media/cdwriter_mounted_decrypted" ); + m_supportedMimetypes.append( "media/blankcd" ); + m_supportedMimetypes.append( "media/blankdvd" ); + m_supportedMimetypes.append( "media/audiocd" ); + m_supportedMimetypes.append( "media/dvdvideo" ); + m_supportedMimetypes.append( "media/vcd" ); + m_supportedMimetypes.append( "media/svcd" ); + + reload(); +} + +NotifierSettings::~NotifierSettings() +{ + while ( !m_actions.isEmpty() ) + { + NotifierAction *a = m_actions.first(); + m_actions.remove( a ); + delete a; + } + + while ( !m_deletedActions.isEmpty() ) + { + NotifierServiceAction *a = m_deletedActions.first(); + m_deletedActions.remove( a ); + delete a; + } +} + +TQValueList<NotifierAction*> NotifierSettings::actions() +{ + return m_actions; +} + +const TQStringList &NotifierSettings::supportedMimetypes() +{ + return m_supportedMimetypes; +} + +TQValueList<NotifierAction*> NotifierSettings::actionsForMimetype( const TQString &mimetype ) +{ + TQValueList<NotifierAction*> result; + + TQValueList<NotifierAction*>::iterator it = m_actions.begin(); + TQValueList<NotifierAction*>::iterator end = m_actions.end(); + + for ( ; it!=end; ++it ) + { + if ( (*it)->supportsMimetype( mimetype ) ) + { + result.append( *it ); + } + } + + return result; +} + +bool NotifierSettings::addAction( NotifierServiceAction *action ) +{ + if ( !m_idMap.contains( action->id() ) ) + { + m_actions.insert( --m_actions.end(), action ); + m_idMap[ action->id() ] = action; + return true; + } + return false; +} + +bool NotifierSettings::deleteAction( NotifierServiceAction *action ) +{ + if ( action->isWritable() ) + { + m_actions.remove( action ); + m_idMap.remove( action->id() ); + m_deletedActions.append( action ); + + TQStringList auto_mimetypes = action->autoMimetypes(); + TQStringList::iterator it = auto_mimetypes.begin(); + TQStringList::iterator end = auto_mimetypes.end(); + + for ( ; it!=end; ++it ) + { + action->removeAutoMimetype( *it ); + m_autoMimetypesMap.remove( *it ); + } + + return true; + } + return false; +} + +void NotifierSettings::setAutoAction( const TQString &mimetype, NotifierAction *action ) +{ + resetAutoAction( mimetype ); + m_autoMimetypesMap[mimetype] = action; + action->addAutoMimetype( mimetype ); +} + + +void NotifierSettings::resetAutoAction( const TQString &mimetype ) +{ + if ( m_autoMimetypesMap.contains( mimetype ) ) + { + NotifierAction *action = m_autoMimetypesMap[mimetype]; + action->removeAutoMimetype( mimetype ); + m_autoMimetypesMap.remove(mimetype); + } +} + +void NotifierSettings::clearAutoActions() +{ + TQMap<TQString,NotifierAction*>::iterator it = m_autoMimetypesMap.begin(); + TQMap<TQString,NotifierAction*>::iterator end = m_autoMimetypesMap.end(); + + for ( ; it!=end; ++it ) + { + NotifierAction *action = it.data(); + TQString mimetype = it.key(); + + if ( action ) + action->removeAutoMimetype( mimetype ); + m_autoMimetypesMap[mimetype] = 0L; + } +} + +NotifierAction *NotifierSettings::autoActionForMimetype( const TQString &mimetype ) +{ + if ( m_autoMimetypesMap.contains( mimetype ) ) + { + return m_autoMimetypesMap[mimetype]; + } + else + { + return 0L; + } +} + +void NotifierSettings::reload() +{ + while ( !m_actions.isEmpty() ) + { + NotifierAction *a = m_actions.first(); + m_actions.remove( a ); + delete a; + } + + while ( !m_deletedActions.isEmpty() ) + { + NotifierServiceAction *a = m_deletedActions.first(); + m_deletedActions.remove( a ); + delete a; + } + + m_idMap.clear(); + m_autoMimetypesMap.clear(); + + NotifierOpenAction *open = new NotifierOpenAction(); + m_actions.append( open ); + m_idMap[ open->id() ] = open; + + TQValueList<NotifierServiceAction*> services = listServices(); + + TQValueList<NotifierServiceAction*>::iterator serv_it = services.begin(); + TQValueList<NotifierServiceAction*>::iterator serv_end = services.end(); + + for ( ; serv_it!=serv_end; ++serv_it ) + { + m_actions.append( *serv_it ); + m_idMap[ (*serv_it)->id() ] = *serv_it; + } + + NotifierNothingAction *nothing = new NotifierNothingAction(); + m_actions.append( nothing ); + m_idMap[ nothing->id() ] = nothing; + + TDEConfig config( "medianotifierrc", true ); + TQMap<TQString,TQString> auto_actions_map = config.entryMap( "Auto Actions" ); + + TQMap<TQString,TQString>::iterator auto_it = auto_actions_map.begin(); + TQMap<TQString,TQString>::iterator auto_end = auto_actions_map.end(); + + for ( ; auto_it!=auto_end; ++auto_it ) + { + TQString mime = auto_it.key(); + TQString action_id = auto_it.data(); + + if ( m_idMap.contains( action_id ) ) + { + setAutoAction( mime, m_idMap[action_id] ); + } + else + { + config.deleteEntry( mime ); + } + } +} +void NotifierSettings::save() +{ + TQValueList<NotifierAction*>::iterator act_it = m_actions.begin(); + TQValueList<NotifierAction*>::iterator act_end = m_actions.end(); + + for ( ; act_it!=act_end; ++act_it ) + { + NotifierServiceAction *service; + if ( ( service=dynamic_cast<NotifierServiceAction*>( *act_it ) ) + && service->isWritable() ) + { + service->save(); + } + } + + while ( !m_deletedActions.isEmpty() ) + { + NotifierServiceAction *a = m_deletedActions.first(); + m_deletedActions.remove( a ); + TQFile::remove( a->filePath() ); + delete a; + } + + KSimpleConfig config( "medianotifierrc" ); + config.setGroup( "Auto Actions" ); + + TQMap<TQString,NotifierAction*>::iterator auto_it = m_autoMimetypesMap.begin(); + TQMap<TQString,NotifierAction*>::iterator auto_end = m_autoMimetypesMap.end(); + + for ( ; auto_it!=auto_end; ++auto_it ) + { + if ( auto_it.data()!=0L ) + { + config.writeEntry( auto_it.key(), auto_it.data()->id() ); + } + else + { + config.deleteEntry( auto_it.key() ); + } + } +} + +TQValueList<NotifierServiceAction*> NotifierSettings::loadActions( KDesktopFile &desktop ) const +{ + desktop.setDesktopGroup(); + + TQValueList<NotifierServiceAction*> services; + + const TQString filename = desktop.fileName(); + const TQStringList mimetypes = desktop.readListEntry( "ServiceTypes" ); + + TQValueList<KDEDesktopMimeType::Service> type_services + = KDEDesktopMimeType::userDefinedServices(filename, true); + + TQValueList<KDEDesktopMimeType::Service>::iterator service_it = type_services.begin(); + TQValueList<KDEDesktopMimeType::Service>::iterator service_end = type_services.end(); + for (; service_it!=service_end; ++service_it) + { + NotifierServiceAction *service_action + = new NotifierServiceAction(); + + service_action->setService( *service_it ); + service_action->setFilePath( filename ); + service_action->setMimetypes( mimetypes ); + + services += service_action; + } + + return services; +} + + +bool NotifierSettings::shouldLoadActions( KDesktopFile &desktop, const TQString &mimetype ) const +{ + desktop.setDesktopGroup(); + + if ( desktop.hasKey( "Actions" ) + && desktop.hasKey( "ServiceTypes" ) + && !desktop.readBoolEntry( "X-TDE-MediaNotifierHide", false ) ) + { + const TQStringList actions = desktop.readListEntry( "Actions" ); + + if ( actions.size()!=1 ) + { + return false; + } + + const TQStringList types = desktop.readListEntry( "ServiceTypes" ); + + if ( mimetype.isEmpty() ) + { + TQStringList::ConstIterator type_it = types.begin(); + TQStringList::ConstIterator type_end = types.end(); + for (; type_it != type_end; ++type_it) + { + if ( (*type_it).startsWith( "media/" ) ) + { + return true; + } + } + } + else if ( types.contains(mimetype) ) + { + return true; + } + } + + return false; +} + +TQValueList<NotifierServiceAction*> NotifierSettings::listServices( const TQString &mimetype ) const +{ + TQValueList<NotifierServiceAction*> services; + TQStringList dirs = TDEGlobal::dirs()->findDirs("data", "konqueror/servicemenus/"); + + TQStringList::ConstIterator dir_it = dirs.begin(); + TQStringList::ConstIterator dir_end = dirs.end(); + for (; dir_it != dir_end; ++dir_it) + { + TQDir dir( *dir_it ); + + TQStringList entries = dir.entryList( "*.desktop", TQDir::Files ); + + TQStringList::ConstIterator entry_it = entries.begin(); + TQStringList::ConstIterator entry_end = entries.end(); + + for (; entry_it != entry_end; ++entry_it ) + { + TQString filename = *dir_it + *entry_it; + + KDesktopFile desktop( filename, true ); + + if ( shouldLoadActions(desktop, mimetype) ) + { + services+=loadActions(desktop); + } + } + } + + return services; +} diff --git a/tdeioslave/media/libmediacommon/notifiersettings.h b/tdeioslave/media/libmediacommon/notifiersettings.h new file mode 100644 index 000000000..dee5c440b --- /dev/null +++ b/tdeioslave/media/libmediacommon/notifiersettings.h @@ -0,0 +1,63 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _NOTIFIERSETTINGS_H_ +#define _NOTIFIERSETTINGS_H_ + +#include <tqvaluelist.h> +#include <tqmap.h> + +#include "notifieraction.h" +#include "notifierserviceaction.h" + + +class NotifierSettings +{ +public: + NotifierSettings(); + ~NotifierSettings(); + + TQValueList<NotifierAction*> actions(); + TQValueList<NotifierAction*> actionsForMimetype( const TQString &mimetype ); + + bool addAction( NotifierServiceAction *action ); + bool deleteAction( NotifierServiceAction *action ); + + void setAutoAction( const TQString &mimetype, NotifierAction *action ); + void resetAutoAction( const TQString &mimetype ); + void clearAutoActions(); + NotifierAction *autoActionForMimetype( const TQString &mimetype ); + + const TQStringList &supportedMimetypes(); + + void reload(); + void save(); + +private: + TQValueList<NotifierServiceAction*> listServices( const TQString &mimetype = TQString() ) const; + bool shouldLoadActions( KDesktopFile &desktop, const TQString &mimetype ) const; + TQValueList<NotifierServiceAction*> loadActions( KDesktopFile &desktop ) const; + + TQStringList m_supportedMimetypes; + TQValueList<NotifierAction*> m_actions; + TQValueList<NotifierServiceAction*> m_deletedActions; + TQMap<TQString,NotifierAction*> m_idMap; + TQMap<TQString,NotifierAction*> m_autoMimetypesMap; +}; +#endif diff --git a/tdeioslave/media/media.protocol b/tdeioslave/media/media.protocol new file mode 100644 index 000000000..f535e1a41 --- /dev/null +++ b/tdeioslave/media/media.protocol @@ -0,0 +1,18 @@ +[Protocol] +exec=kio_media +protocol=media +input=none +output=filesystem +listing=Name,Type,Size,Date,AccessDate,Access,Owner,Group,Link +reading=true +writing=true +makedir=true +deleting=true +linking=true +moving=true +Icon=system +maxInstances=4 +#TODO DocPath=tdeioslave/file.html +Class=:local +deleteRecursive=true +fileNameUsedForCopying=Name diff --git a/tdeioslave/media/mediaimpl.cpp b/tdeioslave/media/mediaimpl.cpp new file mode 100644 index 000000000..a6ed957ae --- /dev/null +++ b/tdeioslave/media/mediaimpl.cpp @@ -0,0 +1,449 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens <ervin ipsquad net> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "mediaimpl.h" + +#include <klocale.h> +#include <kdebug.h> +#include <dcopclient.h> +#include <dcopref.h> +#include <tdeio/netaccess.h> + +#include <kmimetype.h> + +#include <kapplication.h> +#include <tqeventloop.h> + +#include <sys/stat.h> + +#include "medium.h" + +#include <config.h> + +MediaImpl::MediaImpl() : TQObject(), DCOPObject("mediaimpl"), mp_mounting(0L) +{ + +} + +bool MediaImpl::parseURL(const KURL &url, TQString &name, TQString &path) const +{ + TQString url_path = url.path(); + + int i = url_path.find('/', 1); + if (i > 0) + { + name = url_path.mid(1, i-1); + path = url_path.mid(i+1); + } + else + { + name = url_path.mid(1); + path = TQString::null; + } + + return name != TQString::null; +} + +bool MediaImpl::realURL(const TQString &name, const TQString &path, KURL &url) +{ + bool ok; + Medium m = findMediumByName(name, ok); + if ( !ok ) return false; + + ok = ensureMediumMounted(m); + if ( !ok ) return false; + + url = m.prettyBaseURL(); + url.addPath(path); + return true; +} + + +bool MediaImpl::statMedium(const TQString &name, TDEIO::UDSEntry &entry) +{ + kdDebug(1219) << "MediaImpl::statMedium: " << name << endl; + + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "properties", name ); + + if ( !reply.isValid() ) + { + m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; + m_lastErrorMessage = i18n("The TDE mediamanager is not running."); + return false; + } + + Medium m = Medium::create(reply); + + if (m.id().isEmpty()) + { + entry.clear(); + return false; + } + + createMediumEntry(entry, m); + + return true; +} + +bool MediaImpl::statMediumByLabel(const TQString &label, TDEIO::UDSEntry &entry) +{ + kdDebug(1219) << "MediaImpl::statMediumByLabel: " << label << endl; + + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "nameForLabel", label ); + + if ( !reply.isValid() ) + { + m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; + m_lastErrorMessage = i18n("The TDE mediamanager is not running."); + return false; + } + + TQString name = reply; + + if (name.isEmpty()) + { + entry.clear(); + return false; + } + + return statMedium(name, entry); +} + + +bool MediaImpl::listMedia(TQValueList<TDEIO::UDSEntry> &list) +{ + kdDebug(1219) << "MediaImpl::listMedia" << endl; + + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "fullList" ); + + if ( !reply.isValid() ) + { + m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; + m_lastErrorMessage = i18n("The TDE mediamanager is not running."); + return false; + } + + const Medium::MList media = Medium::createList(reply); + + TDEIO::UDSEntry entry; + + Medium::MList::const_iterator it = media.begin(); + Medium::MList::const_iterator end = media.end(); + + for(; it!=end; ++it) + { + if (!(*it).hidden()) { + entry.clear(); + + createMediumEntry(entry, *it); + + list.append(entry); + } + } + + return true; +} + +bool MediaImpl::setUserLabel(const TQString &name, const TQString &label) +{ + kdDebug(1219) << "MediaImpl::setUserLabel: " << name << ", " << label << endl; + + + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "nameForLabel", label ); + + if ( !reply.isValid() ) + { + m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; + m_lastErrorMessage = i18n("The TDE mediamanager is not running."); + return false; + } + else + { + TQString returned_name = reply; + if (!returned_name.isEmpty() + && returned_name!=name) + { + m_lastErrorCode = TDEIO::ERR_DIR_ALREADY_EXIST; + m_lastErrorMessage = i18n("This media name already exists."); + return false; + } + } + + reply = mediamanager.call( "setUserLabel", name, label ); + + if ( !reply.isValid() ) + { + m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; + m_lastErrorMessage = i18n("The TDE mediamanager is not running."); + return false; + } + else + { + return true; + } +} + +const Medium MediaImpl::findMediumByName(const TQString &name, bool &ok) +{ + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "properties", name ); + + if ( reply.isValid() ) + { + ok = true; + } + else + { + m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; + m_lastErrorMessage = i18n("The TDE mediamanager is not running."); + ok = false; + } + + return Medium::create(reply); +} + +bool MediaImpl::ensureMediumMounted(Medium &medium) +{ + if (medium.id().isEmpty()) + { + m_lastErrorCode = TDEIO::ERR_COULD_NOT_MOUNT; + m_lastErrorMessage = i18n("No such medium."); + return false; + } + +#ifdef COMPILE_HALBACKEND + if ( medium.isEncrypted() && medium.clearDeviceUdi().isEmpty() ) + { + m_lastErrorCode = TDEIO::ERR_COULD_NOT_MOUNT; + m_lastErrorMessage = i18n("The drive is encrypted."); + return false; + } +#endif // COMPILE_HALBACKEND + + if ( medium.needMounting() ) + { + m_lastErrorCode = 0; + + mp_mounting = &medium; + + + /* + TDEIO::Job* job = TDEIO::mount(false, 0, + medium.deviceNode(), + medium.mountPoint()); + job->setAutoWarningHandlingEnabled(false); + connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), + this, TQT_SLOT( slotMountResult( TDEIO::Job * ) ) ); + connect( job, TQT_SIGNAL( warning( TDEIO::Job *, const TQString & ) ), + this, TQT_SLOT( slotWarning( TDEIO::Job *, const TQString & ) ) ); + */ + kapp->dcopClient() + ->connectDCOPSignal("kded", "mediamanager", + "mediumChanged(TQString, bool)", + "mediaimpl", + "slotMediumChanged(TQString)", + false); + + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "mount", medium.id()); + if (reply.isValid()) + reply.get(m_lastErrorMessage); + else + m_lastErrorMessage = i18n("Internal Error"); + if (!m_lastErrorMessage.isEmpty()) + m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; + else { + tqApp->eventLoop()->enterLoop(); + } + + mp_mounting = 0L; + + kapp->dcopClient() + ->disconnectDCOPSignal("kded", "mediamanager", + "mediumChanged(TQString, bool)", + "mediaimpl", + "slotMediumChanged(TQString)"); + + return m_lastErrorCode==0; + } + + if (medium.id().isEmpty()) + { + m_lastErrorCode = TDEIO::ERR_COULD_NOT_MOUNT; + m_lastErrorMessage = i18n("No such medium."); + return false; + } + + return true; +} + +void MediaImpl::slotWarning( TDEIO::Job * /*job*/, const TQString &msg ) +{ + emit warning( msg ); +} + +void MediaImpl::slotMountResult(TDEIO::Job *job) +{ + kdDebug(1219) << "MediaImpl::slotMountResult" << endl; + + if ( job->error() != 0) + { + m_lastErrorCode = job->error(); + m_lastErrorMessage = job->errorText(); + tqApp->eventLoop()->exitLoop(); + } +} + +void MediaImpl::slotMediumChanged(const TQString &name) +{ + kdDebug(1219) << "MediaImpl::slotMediumChanged:" << name << endl; + + if (mp_mounting->name()==name) + { + kdDebug(1219) << "MediaImpl::slotMediumChanged: updating mp_mounting" << endl; + bool ok; + *mp_mounting = findMediumByName(name, ok); + tqApp->eventLoop()->exitLoop(); + } +} + +static void addAtom(TDEIO::UDSEntry &entry, unsigned int ID, long l, + const TQString &s = TQString::null) +{ + TDEIO::UDSAtom atom; + atom.m_uds = ID; + atom.m_long = l; + atom.m_str = s; + entry.append(atom); +} + + +void MediaImpl::createTopLevelEntry(TDEIO::UDSEntry& entry) const +{ + entry.clear(); + addAtom(entry, TDEIO::UDS_URL, 0, "media:/"); + addAtom(entry, TDEIO::UDS_NAME, 0, "."); + addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFDIR); + addAtom(entry, TDEIO::UDS_ACCESS, 0555); + addAtom(entry, TDEIO::UDS_MIME_TYPE, 0, "inode/directory"); + addAtom(entry, TDEIO::UDS_ICON_NAME, 0, "blockdevice"); +} + +void MediaImpl::slotStatResult(TDEIO::Job *job) +{ + if ( job->error() == 0) + { + TDEIO::StatJob *stat_job = static_cast<TDEIO::StatJob *>(job); + m_entryBuffer = stat_job->statResult(); + } + + tqApp->eventLoop()->exitLoop(); +} + +TDEIO::UDSEntry MediaImpl::extractUrlInfos(const KURL &url) +{ + m_entryBuffer.clear(); + + TDEIO::StatJob *job = TDEIO::stat(url, false); + job->setAutoWarningHandlingEnabled( false ); + connect( job, TQT_SIGNAL( result(TDEIO::Job *) ), + this, TQT_SLOT( slotStatResult(TDEIO::Job *) ) ); + connect( job, TQT_SIGNAL( warning( TDEIO::Job *, const TQString & ) ), + this, TQT_SLOT( slotWarning( TDEIO::Job *, const TQString & ) ) ); + tqApp->eventLoop()->enterLoop(); + + TDEIO::UDSEntry::iterator it = m_entryBuffer.begin(); + TDEIO::UDSEntry::iterator end = m_entryBuffer.end(); + + TDEIO::UDSEntry infos; + + for(; it!=end; ++it) + { + switch( (*it).m_uds ) + { + case TDEIO::UDS_ACCESS: + case TDEIO::UDS_USER: + case TDEIO::UDS_GROUP: + case TDEIO::UDS_CREATION_TIME: + case TDEIO::UDS_MODIFICATION_TIME: + case TDEIO::UDS_ACCESS_TIME: + infos.append(*it); + break; + default: + break; + } + } + + if (url.isLocalFile()) + { + addAtom(infos, TDEIO::UDS_LOCAL_PATH, 0, url.path()); + } + + return infos; +} + + +void MediaImpl::createMediumEntry(TDEIO::UDSEntry& entry, + const Medium &medium) +{ + kdDebug(1219) << "MediaProtocol::createMedium" << endl; + + TQString url = "media:/"+medium.name(); + + kdDebug(1219) << "url = " << url << ", mime = " << medium.mimeType() << endl; + + entry.clear(); + + addAtom(entry, TDEIO::UDS_URL, 0, url); + + TQString label = TDEIO::encodeFileName( medium.prettyLabel() ); + addAtom(entry, TDEIO::UDS_NAME, 0, label); + + addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFDIR); + + addAtom(entry, TDEIO::UDS_MIME_TYPE, 0, medium.mimeType()); + addAtom(entry, TDEIO::UDS_GUESSED_MIME_TYPE, 0, "inode/directory"); + + if (!medium.iconName().isEmpty()) + { + addAtom(entry, TDEIO::UDS_ICON_NAME, 0, medium.iconName()); + } + else + { + TQString mime = medium.mimeType(); + TQString icon = KMimeType::mimeType(mime)->icon(mime, false); + addAtom(entry, TDEIO::UDS_ICON_NAME, 0, icon); + } + + if (medium.needMounting()) + { + addAtom(entry, TDEIO::UDS_ACCESS, 0400); + } + else + { + KURL url = medium.prettyBaseURL(); + entry+= extractUrlInfos(url); + } +} + +#include "mediaimpl.moc" diff --git a/tdeioslave/media/mediaimpl.h b/tdeioslave/media/mediaimpl.h new file mode 100644 index 000000000..1080d6783 --- /dev/null +++ b/tdeioslave/media/mediaimpl.h @@ -0,0 +1,81 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens <ervin ipsquad net> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _MEDIAIMPL_H_ +#define _MEDIAIMPL_H_ + +#include <tdeio/global.h> +#include <tdeio/job.h> +#include <kurl.h> +#include <dcopobject.h> + +#include <tqobject.h> +#include <tqstring.h> + +#include "medium.h" + +class MediaImpl : public TQObject, public DCOPObject +{ +Q_OBJECT +K_DCOP +public: + MediaImpl(); + bool parseURL(const KURL &url, TQString &name, TQString &path) const; + bool realURL(const TQString &name, const TQString &path, KURL &url); + + bool statMedium(const TQString &name, TDEIO::UDSEntry &entry); + bool statMediumByLabel(const TQString &label, TDEIO::UDSEntry &entry); + bool listMedia(TQValueList<TDEIO::UDSEntry> &list); + bool setUserLabel(const TQString &name, const TQString &label); + + void createTopLevelEntry(TDEIO::UDSEntry& entry) const; + + int lastErrorCode() const { return m_lastErrorCode; } + TQString lastErrorMessage() const { return m_lastErrorMessage; } + +k_dcop: + void slotMediumChanged(const TQString &name); + +signals: + void warning(const TQString &msg); + +private slots: + void slotWarning(TDEIO::Job *job, const TQString &msg); + void slotMountResult(TDEIO::Job *job); + void slotStatResult(TDEIO::Job *job); + +private: + const Medium findMediumByName(const TQString &name, bool &ok); + bool ensureMediumMounted(Medium &medium); + + TDEIO::UDSEntry extractUrlInfos(const KURL &url); + TDEIO::UDSEntry m_entryBuffer; + + void createMediumEntry(TDEIO::UDSEntry& entry, + const Medium &medium); + + Medium *mp_mounting; + + /// Last error code stored in class to simplify API. + /// Note that this means almost no method can be const. + int m_lastErrorCode; + TQString m_lastErrorMessage; +}; + +#endif diff --git a/tdeioslave/media/mediamanager/CMakeLists.txt b/tdeioslave/media/mediamanager/CMakeLists.txt new file mode 100644 index 000000000..5a73f3708 --- /dev/null +++ b/tdeioslave/media/mediamanager/CMakeLists.txt @@ -0,0 +1,65 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdeioslave/media/libmediacommon + ${CMAKE_SOURCE_DIR}/tdeioslave/media/libmediacommon + ${CMAKE_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} + ${HAL_INCLUDE_DIRS} + ${DBUS_TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} + ${DBUS_TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES mediamanager.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded ) + + +##### kded_mediamanager (module) ################ + +set( target kded_mediamanager ) + +if( WITH_HAL ) + set( ${target}_SRCS + mediamanager.cpp mediamanager.skel medialist.cpp + backendbase.cpp fstabbackend.cpp removablebackend.cpp + mediadirnotify.cpp mediadirnotify.skel + decryptdialog.ui dialog.cpp + halbackend.cpp linuxcdpolling.cpp tdehardwarebackend.cpp + ) + + tde_add_kpart( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK mediacommon-static tdeinit_kded-shared ${HAL_LIBRARIES} -lhal-storage ${DBUS_TQT_LIBRARIES} + DESTINATION ${PLUGIN_INSTALL_DIR} + ) +else( ) + set( ${target}_SRCS + mediamanager.cpp mediamanager.skel medialist.cpp + backendbase.cpp fstabbackend.cpp removablebackend.cpp + decryptdialog.ui dialog.cpp + mediadirnotify.cpp mediadirnotify.skel tdehardwarebackend.cpp + ) + + tde_add_kpart( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK mediacommon-static tdeinit_kded-shared + DESTINATION ${PLUGIN_INSTALL_DIR} + ) +endif( ) diff --git a/tdeioslave/media/mediamanager/Makefile.am b/tdeioslave/media/mediamanager/Makefile.am new file mode 100644 index 000000000..45289a9eb --- /dev/null +++ b/tdeioslave/media/mediamanager/Makefile.am @@ -0,0 +1,32 @@ +kde_module_LTLIBRARIES = kded_mediamanager.la + +if include_media_halbackend +HALBACKEND_INCS = $(HAL_INCS) $(DBUS_INCS) $(DBUSQT_INCS) +endif + +METASOURCES = AUTO +INCLUDES = -I$(srcdir)/../libmediacommon -I../libmediacommon $(HALBACKEND_INCS) $(all_includes) + +if include_media_halbackend +HALBACKEND_LIB = libhalbackend.la +libhalbackend_la_SOURCES = halbackend.cpp +libhalbackend_la_LDFLAGS = -avoid-version $(all_libraries) -no-undefined +libhalbackend_la_LIBADD = $(HAL_LIBS) $(DBUS_LIBS) $(DBUSQT_LIBS) +endif + +if include_media_linuxcdpolling +LINUXCDPOLLING_LIB = liblinuxcdpolling.la +liblinuxcdpolling_la_SOURCES = linuxcdpolling.cpp +liblinuxcdpolling_la_LDFLAGS = -avoid-version $(all_libraries) -no-undefined +endif + +noinst_LTLIBRARIES = $(LINUXCDPOLLING_LIB) $(HALBACKEND_LIB) + +kded_mediamanager_la_SOURCES = mediamanager.cpp mediamanager.skel medialist.cpp backendbase.cpp fstabbackend.cpp removablebackend.cpp mediadirnotify.cpp mediadirnotify.skel +kded_mediamanager_la_LDFLAGS = $(all_libraries) -module -avoid-version +kded_mediamanager_la_LIBADD = $(LIB_KSYCOCA) ../libmediacommon/libmediacommon.la $(HALBACKEND_LIB) $(LINUXCDPOLLING_LIB) + + +servicesdir = $(kde_servicesdir)/kded +services_DATA = mediamanager.desktop + diff --git a/tdeioslave/media/mediamanager/backendbase.cpp b/tdeioslave/media/mediamanager/backendbase.cpp new file mode 100644 index 000000000..157acfca5 --- /dev/null +++ b/tdeioslave/media/mediamanager/backendbase.cpp @@ -0,0 +1,26 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "backendbase.h" + +BackendBase::BackendBase(MediaList &list) + : m_mediaList(list) +{ + +} + diff --git a/tdeioslave/media/mediamanager/backendbase.h b/tdeioslave/media/mediamanager/backendbase.h new file mode 100644 index 000000000..689522d1f --- /dev/null +++ b/tdeioslave/media/mediamanager/backendbase.h @@ -0,0 +1,35 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _BACKENDBASE_H_ +#define _BACKENDBASE_H_ + +#include "medialist.h" + +class BackendBase +{ +protected: + BackendBase(MediaList &list); +public: + virtual ~BackendBase() { } + +protected: + MediaList &m_mediaList; +}; + +#endif diff --git a/tdeioslave/media/mediamanager/decryptdialog.ui b/tdeioslave/media/mediamanager/decryptdialog.ui new file mode 100644 index 000000000..939f0a36a --- /dev/null +++ b/tdeioslave/media/mediamanager/decryptdialog.ui @@ -0,0 +1,201 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>DecryptDialog</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>DecryptDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>207</width> + <height>172</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Decrypting Storage Device</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>encryptedIcon</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + <property name="alignment"> + <set>AlignTop</set> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>31</width> + <height>41</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>descLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><p><b>%1</b> is an encrypted storage device.</p> +<p>Please enter the password to decrypt the storage device.</p></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Password:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>passwordEdit</cstring> + </property> + </widget> + <widget class="TQLineEdit"> + <property name="name"> + <cstring>passwordEdit</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + </hbox> + </widget> + <widget class="TQGroupBox" row="2" column="0"> + <property name="name"> + <cstring>errorBox</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Error</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>errorLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/tdeioslave/media/mediamanager/dialog.cpp b/tdeioslave/media/mediamanager/dialog.cpp new file mode 100644 index 000000000..40e99a84d --- /dev/null +++ b/tdeioslave/media/mediamanager/dialog.cpp @@ -0,0 +1,68 @@ +/* This file is part of the KDE project + * Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de> + * + * Based on kryptomedia- Another KDE cryto media application. + * Copyright (C) 2006 Daniel Gollub <dgollub@suse.de> + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "dialog.h" + +Dialog::Dialog(TQString url, TQString iconName) : + KDialogBase(NULL, "Dialog", true, "Decrypt Storage Device", (Cancel|User1), User1, false, KGuiItem(i18n("Decrypt"), "decrypted" )) +{ + decryptDialog = new DecryptDialog(this); + + decryptDialog->errorBox->hide(); + decryptDialog->descLabel->setText(decryptDialog->descLabel->text().arg(url)); + decryptDialog->descLabel->adjustSize(); + decryptDialog->adjustSize(); + + enableButton( User1, false ); + + TQPixmap pixmap = TDEGlobal::iconLoader()->loadIcon(iconName, KIcon::NoGroup, KIcon::SizeLarge); + decryptDialog->encryptedIcon->setPixmap( pixmap ); + + connect(decryptDialog->passwordEdit, TQT_SIGNAL (textChanged(const TQString &)), this, TQT_SLOT (slotPasswordChanged(const TQString &))); + + setMainWidget(decryptDialog); +} + +Dialog::~Dialog() +{ + delete decryptDialog; +} + +TQString Dialog::getPassword() +{ + return decryptDialog->passwordEdit->text(); +} + +void Dialog::slotDialogError(TQString errorMsg) +{ + kdDebug() << __func__ << "(" << errorMsg << " )" << endl; + + decryptDialog->errorLabel->setText(TQString("<b>%1</b>").arg(errorMsg)); + decryptDialog->errorBox->show(); +} + +void Dialog::slotPasswordChanged(const TQString &text) +{ + enableButton( User1, !text.isEmpty() ); +} + +#include "dialog.moc" diff --git a/tdeioslave/media/mediamanager/dialog.h b/tdeioslave/media/mediamanager/dialog.h new file mode 100644 index 000000000..dc1d552d8 --- /dev/null +++ b/tdeioslave/media/mediamanager/dialog.h @@ -0,0 +1,61 @@ +/* This file is part of the KDE project + * Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de> + * + * Based on kryptomedia- Another KDE cryto media application. + * Copyright (C) 2006 Daniel Gollub <dgollub@suse.de> + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef DIALOG_H_ +#define DIALOG_H_ + +#include <kmessagebox.h> +#include <klocale.h> +#include <tdeconfig.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <kiconloader.h> + +#include <tqlineedit.h> +#include <tqlabel.h> +#include <tqgroupbox.h> + +#include "decryptdialog.h" + +class KryptoMedia; + +class Dialog : public KDialogBase +{ + +Q_OBJECT + +public: + Dialog(TQString url, TQString iconName); + ~Dialog(); + + TQString getPassword(); + +public slots: + void slotDialogError(TQString errorMsg); + void slotPasswordChanged(const TQString &text); + +private: + DecryptDialog *decryptDialog; +}; + +#endif // DIALOG_H_ + diff --git a/tdeioslave/media/mediamanager/fstabbackend.cpp b/tdeioslave/media/mediamanager/fstabbackend.cpp new file mode 100644 index 000000000..0069a8e8e --- /dev/null +++ b/tdeioslave/media/mediamanager/fstabbackend.cpp @@ -0,0 +1,483 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + Linux CD/DVD detection + Copyright (c) 2005 Bernhard Rosenkraenzer <bero arklinux org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "fstabbackend.h" + +#ifdef __linux__ +// For CD/DVD drive detection +#include <fcntl.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdint.h> +#define CDROM_GET_CAPABILITY 0x5331 +#define CDSL_CURRENT ((int) (~0U>>1)) +#define CDC_DVD_R 0x10000 /* drive can write DVD-R */ +#define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */ +#define CDC_CD_R 0x2000 /* drive is a CD-R */ +#define CDC_CD_RW 0x4000 /* drive is a CD-RW */ +#define CDC_DVD 0x8000 /* drive is a DVD */ +#include <tqfile.h> +#endif + +#include <klocale.h> +#include <tdeio/job.h> +#include <tdeio/netaccess.h> +#include <kdebug.h> +#include <kdirwatch.h> +#include <kurl.h> +#include <kmountpoint.h> +#include <kstandarddirs.h> + +#ifdef _OS_SOLARIS_ +#define FSTAB "/etc/vfstab" +#define MTAB "/etc/mnttab" +#else +#define FSTAB "/etc/fstab" +#define MTAB "/etc/mtab" +#endif + + + +FstabBackend::FstabBackend(MediaList &list, bool networkSharesOnly) + : TQObject(), BackendBase(list), m_networkSharesOnly(networkSharesOnly) +{ + KDirWatch::self()->addFile(MTAB); + KDirWatch::self()->addFile(FSTAB); + + connect( KDirWatch::self(), TQT_SIGNAL( dirty(const TQString&) ), + this, TQT_SLOT( slotDirty(const TQString&) ) ); + + handleFstabChange(false); + handleMtabChange(false); + + KDirWatch::self()->startScan(); + +#ifdef Q_OS_FREEBSD + connect( &m_mtabTimer, TQT_SIGNAL( timeout() ), + this, TQT_SLOT( handleMtabChange() ) ); + m_mtabTimer.start(250); +#endif +} + +FstabBackend::~FstabBackend() +{ + TQStringList::iterator it = m_mtabIds.begin(); + TQStringList::iterator end = m_mtabIds.end(); + + for (; it!=end; ++it) + { + m_mediaList.removeMedium(*it, false); + } + + it = m_fstabIds.begin(); + end = m_fstabIds.end(); + + for (; it!=end; ++it) + { + m_mediaList.removeMedium(*it, false); + } + KDirWatch::self()->removeFile(FSTAB); + KDirWatch::self()->removeFile(MTAB); +} + +TQString FstabBackend::mount( const TQString &_udi ) +{ + const Medium* medium = m_mediaList.findById(_udi); + if (!medium) + return i18n("No such medium: %1").arg(_udi); + TDEIO::Job* job = TDEIO::mount( false, 0, medium->deviceNode(), medium->mountPoint()); + TDEIO::NetAccess::synchronousRun( job, 0 ); + return TQString::null; +} + +TQString FstabBackend::unmount( const TQString &_udi ) +{ + const Medium* medium = m_mediaList.findById(_udi); + if (!medium) + return i18n("No such medium: %1").arg(_udi); + TDEIO::Job* job = TDEIO::unmount( medium->mountPoint(), false); + TDEIO::NetAccess::synchronousRun( job, 0 ); + return TQString::null; +} + +void FstabBackend::slotDirty(const TQString &path) +{ + if (path==MTAB) + { + handleMtabChange(); + } + else if (path==FSTAB) + { + handleFstabChange(); + } +} + +bool inExclusionPattern(KMountPoint *mount, bool networkSharesOnly) +{ + if ( mount->mountType() == "swap" + || mount->mountType() == "tmpfs" + || mount->mountType() == "sysfs" + || mount->mountType() == "fdescfs" + || mount->mountType() == "kernfs" + || mount->mountType() == "usbfs" + || mount->mountType().contains( "proc" ) + || mount->mountType() == "unknown" + || mount->mountType() == "none" + || mount->mountType() == "sunrpc" + || mount->mountedFrom() == "none" + || mount->mountedFrom() == "tmpfs" + || mount->mountedFrom().find("shm") != -1 + || mount->mountPoint() == "/dev/swap" + || mount->mountPoint() == "/dev/pts" + || mount->mountPoint().find("/proc") == 0 + || mount->mountPoint().find("/sys") == 0 + + // We might want to display only network shares + // since HAL doesn't handle them + || ( networkSharesOnly + && mount->mountType().find( "smb" ) == -1 + && mount->mountType().find( "cifs" ) == -1 + && mount->mountType().find( "nfs" ) == -1 + ) + ) + { + return true; + } + else + { + return false; + } +} + + +void FstabBackend::handleMtabChange(bool allowNotification) +{ + TQStringList new_mtabIds; + KMountPoint::List mtab = KMountPoint::currentMountPoints(); + + KMountPoint::List::iterator it = mtab.begin(); + KMountPoint::List::iterator end = mtab.end(); + + for (; it!=end; ++it) + { + TQString dev = (*it)->mountedFrom(); + TQString mp = (*it)->mountPoint(); + TQString fs = (*it)->mountType(); + + if ( ::inExclusionPattern(*it, m_networkSharesOnly) ) continue; + + /* Did we know this already before ? If yes, then + nothing has changed, do not stat the mount point. Avoids + hang if network shares are stalling */ + TQString mtabEntry = dev + "*" + mp + "*" + fs; + if(m_mtabEntries.contains(mtabEntry)) { + new_mtabIds += m_mtabEntries[mtabEntry]; + continue; + } + + TQString id = generateId(dev, mp); + new_mtabIds+=id; + m_mtabEntries[mtabEntry] = id; + + if ( !m_mtabIds.contains(id) && m_fstabIds.contains(id) ) + { + TQString mime, icon, label; + guess(dev, mp, fs, true, mime, icon, label); + m_mediaList.changeMediumState(id, true, false, + mime, icon, label); + } +#if 0 + else if ( !m_mtabIds.contains(id) ) + { + TQString name = generateName(dev, fs); + + Medium *m = new Medium(id, name); + + m->mountableState(dev, mp, fs, true); + + TQString mime, icon, label; + guess(dev, mp, fs, true, mime, icon, label); + + m->setMimeType(mime); + m->setIconName(icon); + m->setLabel(label); + + m_mediaList.addMedium(m, notificationAllowed); + } +#endif + } + + TQStringList::iterator it2 = m_mtabIds.begin(); + TQStringList::iterator end2 = m_mtabIds.end(); + + for (; it2!=end2; ++it2) + { + if ( !new_mtabIds.contains(*it2) && m_fstabIds.contains(*it2) ) + { + const Medium *medium = m_mediaList.findById(*it2); + + TQString dev = medium->deviceNode(); + TQString mp = medium->mountPoint(); + TQString fs = medium->fsType(); + + + TQString mtabEntry = dev + "*" + mp + "*" + fs; + m_mtabEntries.remove(mtabEntry); + + TQString mime, icon, label; + guess(dev, mp, fs, false, mime, icon, label); + + m_mediaList.changeMediumState(*it2, false, false, + mime, icon, label); + } +#if 0 + else if ( !new_mtabIds.contains(*it2) ) + { + m_mediaList.removeMedium(*it2, allowNotification); + } +#endif + } + + m_mtabIds = new_mtabIds; +} + +void FstabBackend::handleFstabChange(bool allowNotification) +{ + TQStringList new_fstabIds; + KMountPoint::List fstab = KMountPoint::possibleMountPoints(); + + KMountPoint::List::iterator it = fstab.begin(); + KMountPoint::List::iterator end = fstab.end(); + + for (; it!=end; ++it) + { + TQString dev = (*it)->mountedFrom(); + TQString mp = (*it)->mountPoint(); + TQString fs = (*it)->mountType(); + + if ( ::inExclusionPattern(*it, m_networkSharesOnly) ) continue; + + TQString id = generateId(dev, mp); + new_fstabIds+=id; + + if ( !m_fstabIds.contains(id) ) + { + TQString name = generateName(dev, fs); + + Medium *m = new Medium(id, id, name); + + m->mountableState(dev, mp, fs, false); + + TQString mime, icon, label; + guess(dev, mp, fs, false, mime, icon, label); + + m->setMimeType(mime); + m->setIconName(icon); + m->setLabel(label); + + m_mediaList.addMedium(m, allowNotification); + } + } + + TQStringList::iterator it2 = m_fstabIds.begin(); + TQStringList::iterator end2 = m_fstabIds.end(); + + for (; it2!=end2; ++it2) + { + if ( !new_fstabIds.contains(*it2) ) + { + m_mediaList.removeMedium(*it2, allowNotification); + } + } + + m_fstabIds = new_fstabIds; +} + +TQString FstabBackend::generateId(const TQString &devNode, + const TQString &mountPoint) +{ + TQString d = KStandardDirs::realFilePath(devNode); + TQString m = KStandardDirs::realPath(mountPoint); + + return "/org/kde/mediamanager/fstab/" + +d.replace("/", "") + +m.replace("/", ""); +} + +TQString FstabBackend::generateName(const TQString &devNode, const TQString &fsType) +{ + KURL url( devNode ); + + if ( url.isValid() ) + { + return url.fileName(); + } + else // surely something nfs or samba based + { + return fsType; + } +} + +void FstabBackend::guess(const TQString &devNode, const TQString &mountPoint, + const TQString &fsType, bool mounted, + TQString &mimeType, TQString &iconName, TQString &label) +{ + enum { UNKNOWN, CD, CDWRITER, DVD, DVDWRITER } devType = UNKNOWN; +#ifdef __linux__ + // Guessing device types by mount point is not exactly accurate... + // Do something accurate first, and fall back if necessary. + int device=open(TQFile::encodeName(devNode), O_RDONLY|O_NONBLOCK); + if(device>=0) + { + bool isCd=false; + TQString devname=devNode.section('/', -1); + if(devname.startsWith("scd") || devname.startsWith("sr")) + { + // SCSI CD/DVD drive + isCd=true; + } + else if(devname.startsWith("hd")) + { + // IDE device -- we can't tell if this is a + // CD/DVD drive or harddisk by just looking at the + // filename + TQFile m(TQString("/proc/ide/") + devname + "/media"); + if(m.open(IO_ReadOnly)) + { + TQString buf; + m.readLine(buf, 1024); + if(buf.contains("cdrom")) + isCd=true; + m.close(); + } + } + if(isCd) + { + int drv=ioctl(device, CDROM_GET_CAPABILITY, CDSL_CURRENT); + if(drv>=0) + { + if((drv & CDC_DVD_R) || (drv & CDC_DVD_RAM)) + devType = DVDWRITER; + else if((drv & CDC_CD_R) || (drv & CDC_CD_RW)) + devType = CDWRITER; + else if(drv & CDC_DVD) + devType = DVD; + else + devType = CD; + } + } + close(device); + } +#endif + if ( devType == CDWRITER + || devNode.find("cdwriter")!=-1 || mountPoint.find("cdwriter")!=-1 + || devNode.find("cdrecorder")!=-1 || mountPoint.find("cdrecorder")!=-1 + || devNode.find("cdburner")!=-1 || mountPoint.find("cdburner")!=-1 + || devNode.find("cdrw")!=-1 || mountPoint.find("cdrw")!=-1 + || devNode.find("graveur")!=-1 + ) + { + mimeType = "media/cdwriter"; + label = i18n("CD Recorder"); + } + else if ( devType == DVD || devType == DVDWRITER + || devNode.find("dvd")!=-1 || mountPoint.find("dvd")!=-1 ) + { + mimeType = "media/dvd"; + label = i18n("DVD"); + } + else if ( devType == CD + || devNode.find("cdrom")!=-1 || mountPoint.find("cdrom")!=-1 + // LINUX SPECIFIC + || devNode.find("/dev/scd")!=-1 || devNode.find("/dev/sr")!=-1 + // FREEBSD SPECIFIC + || devNode.find("/acd")!=-1 || devNode.find("/scd")!=-1 + ) + { + mimeType = "media/cdrom"; + label = i18n("CD-ROM"); + } + else if ( devNode.find("fd")!=-1 || mountPoint.find("fd")!=-1 + || devNode.find("floppy")!=-1 || mountPoint.find("floppy")!=-1 ) + { + if ( devNode.find("360")!=-1 || devNode.find("1200")!=-1 ) + { + mimeType = "media/floppy5"; + } + else + { + mimeType = "media/floppy"; + } + label = i18n("Floppy"); + } + else if ( mountPoint.find("zip")!=-1 + // FREEBSD SPECIFIC + || devNode.find("/afd")!=-1 + ) + { + mimeType = "media/zip"; + label = i18n("Zip Disk"); + } + else if ( mountPoint.find("removable")!=-1 + || mountPoint.find("hotplug")!=-1 + || mountPoint.find("usb")!=-1 + || mountPoint.find("firewire")!=-1 + || mountPoint.find("ieee1394")!=-1 + || devNode.find("/usb/")!= -1 + ) + { + mimeType = "media/removable"; + label = i18n("Removable Device"); + } + else if ( fsType.find("nfs")!=-1 ) + { + mimeType = "media/nfs"; + label = i18n("Remote Share"); + } + else if ( fsType.find("smb")!=-1 || fsType.find("cifs")!=-1 + || devNode.find("//")!=-1 ) + { + mimeType = "media/smb"; + label = i18n("Remote Share"); + } + else + { + mimeType = "media/hdd"; + label = i18n("Hard Disk"); + } + + if ( mimeType=="media/nfs" || mimeType=="media/smb" ) + { + label+= " (" + devNode + ")"; + } + else + { + TQString tmp = devNode; + if ( tmp.startsWith("/dev/") ) + { + tmp = tmp.mid(5); + } + label+= " (" + tmp + ")"; + } + mimeType+= (mounted ? "_mounted" : "_unmounted"); + iconName = TQString::null; +} + +#include "fstabbackend.moc" diff --git a/tdeioslave/media/mediamanager/fstabbackend.h b/tdeioslave/media/mediamanager/fstabbackend.h new file mode 100644 index 000000000..e43ed48c0 --- /dev/null +++ b/tdeioslave/media/mediamanager/fstabbackend.h @@ -0,0 +1,68 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _FSTABBACKEND_H_ +#define _FSTABBACKEND_H_ + +#include "backendbase.h" + +#include <tqobject.h> +#include <tqstringlist.h> +#include <tqmap.h> + +#ifdef Q_OS_FREEBSD +#include <tqtimer.h> +#endif + +class FstabBackend : public TQObject, public BackendBase +{ +Q_OBJECT + +public: + FstabBackend(MediaList &list, bool networkSharesOnly = false); + virtual ~FstabBackend(); + + static void guess(const TQString &devNode, const TQString &mountPoint, + const TQString &fsType, bool mounted, + TQString &mimeType, TQString &iconName, + TQString &label); + + TQString mount(const TQString &id); + TQString unmount(const TQString &id); + +private slots: + void slotDirty(const TQString &path); + void handleFstabChange(bool allowNotification = true); + void handleMtabChange(bool allowNotification = true); + +private: + static TQString generateId(const TQString &devNode, + const TQString &mountPoint); + static TQString generateName(const TQString &devNode, + const TQString &fsType); + + bool m_networkSharesOnly; + TQStringList m_mtabIds; + TQMap<TQString, TQString> m_mtabEntries; + TQStringList m_fstabIds; +#ifdef Q_OS_FREEBSD + TQTimer m_mtabTimer; +#endif +}; + +#endif diff --git a/tdeioslave/media/mediamanager/halbackend.cpp b/tdeioslave/media/mediamanager/halbackend.cpp new file mode 100644 index 000000000..aba2b0175 --- /dev/null +++ b/tdeioslave/media/mediamanager/halbackend.cpp @@ -0,0 +1,1858 @@ +/* This file is part of the KDE Project + Copyright (c) 2004-2005 Jérôme Lodewyck <jerome dot lodewyck at normalesup dot org> + Copyright (c) 2006 Valentine Sinitsyn <e_val@inbox.ru> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "halbackend.h" +#include "linuxcdpolling.h" + +#include <stdlib.h> +#include <locale.h> + +#include <kapplication.h> +#include <kmessagebox.h> +#include <tqeventloop.h> +#include <tqfile.h> +#include <klocale.h> +#include <kurl.h> +#include <kdebug.h> +#include <kprocess.h> +#include <tdeconfig.h> +#include <tqstylesheet.h> +#include <kmountpoint.h> +#include <kmessagebox.h> +#include <tdeio/job.h> +#include <kprotocolinfo.h> +#include <kstandarddirs.h> +#include <kprocess.h> + +#define MOUNT_SUFFIX ( \ + (medium->isMounted() ? TQString("_mounted") : TQString("_unmounted")) + \ + (medium->isEncrypted() ? (halClearVolume ? "_decrypted" : "_encrypted") : "" ) \ + ) +#define MOUNT_ICON_SUFFIX ( \ + (medium->isMounted() ? TQString("_mount") : TQString("_unmount")) + \ + (medium->isEncrypted() ? (halClearVolume ? "_decrypt" : "_encrypt") : "" ) \ + ) + +/* Static instance of this class, for static HAL callbacks */ +static HALBackend* s_HALBackend; + +/* A macro function to convert HAL string properties to TQString */ +TQString libhal_device_get_property_QString(LibHalContext *ctx, const char* udi, const char *key) +{ + char* _ppt_string; + TQString _ppt_QString; + _ppt_string = libhal_device_get_property_string(ctx, udi, key, NULL); + if ( _ppt_string ) + _ppt_QString = _ppt_string; + libhal_free_string(_ppt_string); + return _ppt_QString; +} + +/* Constructor */ +HALBackend::HALBackend(MediaList &list, TQObject* parent) + : TQObject() + , BackendBase(list) + , m_halContext(NULL) + , m_halStoragePolicy(NULL) + , m_parent(parent) +{ + s_HALBackend = this; +} + +/* Destructor */ +HALBackend::~HALBackend() +{ + /* Close HAL connection */ + if (m_halContext) + { + const TQPtrList<Medium> medlist = m_mediaList.list(); + TQPtrListIterator<Medium> it (medlist); + for ( const Medium *current_medium = it.current(); current_medium; current_medium = ++it) + { + if( !current_medium->id().startsWith( "/org/kde" )) + unmount(current_medium->id()); + } + + + /* Remove all the registered media first */ + int numDevices; + char** halDeviceList = libhal_get_all_devices( m_halContext, &numDevices, NULL ); + + if ( halDeviceList ) + { + for ( int i = 0; i < numDevices; i++ ) + { + m_mediaList.removeMedium( halDeviceList[i], false ); + } + } + + libhal_free_string_array( halDeviceList ); + + DBusError error; + dbus_error_init(&error); + libhal_ctx_shutdown(m_halContext, &error); + libhal_ctx_free(m_halContext); + } + + if (m_halStoragePolicy) + libhal_storage_policy_free(m_halStoragePolicy); +} + +/* Connect to the HAL */ +bool HALBackend::InitHal() +{ + kdDebug(1219) << "Context new" << endl; + m_halContext = libhal_ctx_new(); + if (!m_halContext) + { + kdDebug(1219) << "Failed to initialize HAL!" << endl; + return false; + } + + // Main loop integration + kdDebug(1219) << "Main loop integration" << endl; + DBusError error; + dbus_error_init(&error); + dbus_connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + + if (!dbus_connection || dbus_error_is_set(&error)) { + dbus_error_free(&error); + libhal_ctx_free(m_halContext); + m_halContext = NULL; + return false; + } + + dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE); + + MainLoopIntegration(dbus_connection); + libhal_ctx_set_dbus_connection(m_halContext, dbus_connection); + + // HAL callback functions + kdDebug(1219) << "Callback functions" << endl; + libhal_ctx_set_device_added(m_halContext, HALBackend::hal_device_added); + libhal_ctx_set_device_removed(m_halContext, HALBackend::hal_device_removed); + libhal_ctx_set_device_new_capability (m_halContext, NULL); + libhal_ctx_set_device_lost_capability (m_halContext, NULL); + libhal_ctx_set_device_property_modified (m_halContext, HALBackend::hal_device_property_modified); + libhal_ctx_set_device_condition(m_halContext, HALBackend::hal_device_condition); + + kdDebug(1219) << "Context Init" << endl; + if (!libhal_ctx_init(m_halContext, &error)) + { + if (dbus_error_is_set(&error)) + dbus_error_free(&error); + libhal_ctx_free(m_halContext); + m_halContext = NULL; + kdDebug(1219) << "Failed to init HAL context!" << endl; + return false; + } + + /** @todo customize watch policy */ + kdDebug(1219) << "Watch properties" << endl; + if (!libhal_device_property_watch_all(m_halContext, &error)) + { + kdDebug(1219) << "Failed to watch HAL properties!" << endl; + return false; + } + + /* libhal-storage initialization */ + kdDebug(1219) << "Storage Policy" << endl; + m_halStoragePolicy = libhal_storage_policy_new(); + /** @todo define libhal-storage icon policy */ + + /* List devices at startup */ + return ListDevices(); +} + +/* List devices (at startup)*/ +bool HALBackend::ListDevices() +{ + kdDebug(1219) << "ListDevices" << endl; + + int numDevices; + char** halDeviceList = libhal_get_all_devices(m_halContext, &numDevices, NULL); + + if (!halDeviceList) + return false; + + kdDebug(1219) << "HALBackend::ListDevices : " << numDevices << " devices found" << endl; + for (int i = 0; i < numDevices; i++) + AddDevice(halDeviceList[i], false); + + libhal_free_string_array( halDeviceList ); + + return true; +} + +/* Create a media instance for the HAL device "udi". + This functions checks whether the device is worth listing */ +void HALBackend::AddDevice(const char *udi, bool allowNotification) +{ + /* We don't deal with devices that do not expose their capabilities. + If we don't check this, we will get a lot of warning messages from libhal */ + if (!libhal_device_property_exists(m_halContext, udi, "info.capabilities", NULL)) + return; + + /* If the device is already listed, do not process. + This should not happen, but who knows... */ + /** @todo : refresh properties instead ? */ + if (m_mediaList.findById(udi)) + return; + + if (libhal_device_get_property_bool(m_halContext, "/org/freedesktop/Hal/devices/computer", "storage.disable_volume_handling", NULL)) + allowNotification=false; + + /* Add volume block devices */ + if (libhal_device_query_capability(m_halContext, udi, "volume", NULL)) + { + /* We only list volumes that... + * - are encrypted with LUKS or + * - have a filesystem or + * - have an audio track + */ + if ( ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "crypto" || + libhal_device_get_property_QString(m_halContext, udi, "volume.fstype") != "crypto_LUKS" + ) && + libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "filesystem" && + !libhal_device_get_property_bool(m_halContext, udi, "volume.disc.has_audio", NULL) && + !libhal_device_get_property_bool(m_halContext, udi, "volume.disc.is_blank", NULL) ) + return; + + /* Query drive udi */ + TQString driveUdi = libhal_device_get_property_QString(m_halContext, udi, "block.storage_device"); + if ( driveUdi.isNull() ) // no storage - no fun + return; + + // if the device is locked do not act upon it + if (libhal_device_get_property_bool(m_halContext, driveUdi.ascii(), "info.locked", NULL)) + allowNotification=false; + + // if the device is locked do not act upon it + if (libhal_device_get_property_bool(m_halContext, driveUdi.ascii(), "storage.partition_table_changed", NULL)) + allowNotification=false; + + /** @todo check exclusion list **/ + + /* Special handling for clear crypto volumes */ + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi); + if (!halVolume) + return; + const char* backingVolumeUdi = libhal_volume_crypto_get_backing_volume_udi(halVolume); + if ( backingVolumeUdi != NULL ) + { + /* The crypto drive was unlocked and may now be mounted... */ + kdDebug(1219) << "HALBackend::AddDevice : ClearVolume appeared for " << backingVolumeUdi << endl; + ResetProperties(backingVolumeUdi, allowNotification); + libhal_volume_free(halVolume); + return; + } + libhal_volume_free(halVolume); + + /* Create medium */ + Medium* medium = new Medium(udi, udi, ""); + setVolumeProperties(medium); + + if ( isInFstab( medium ).isNull() ) + { + // if it's not mountable by user and not by HAL, don't show it at all + if ( ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") == "filesystem" && + !libhal_device_get_property_bool(m_halContext, udi, "volume.is_mounted", NULL ) ) && + ( libhal_device_get_property_bool(m_halContext, udi, "volume.ignore", NULL ) ) ) + { + delete medium; + return; + } + } + + // instert medium into list + m_mediaList.addMedium(medium, allowNotification); + + // finally check for automount + TQMap<TQString,TQString> options = MediaManagerUtils::splitOptions(mountoptions(udi)); + kdDebug() << "automount " << options["automount"] << endl; + if (options["automount"] == "true" && allowNotification ) { + TQString error = mount(medium); + if (!error.isEmpty()) + kdDebug() << "error " << error << endl; + } + + return; + } + + /* Floppy & zip drives */ + if (libhal_device_query_capability(m_halContext, udi, "storage", NULL)) + if ((libhal_device_get_property_QString(m_halContext, udi, "storage.drive_type") == "floppy") || + (libhal_device_get_property_QString(m_halContext, udi, "storage.drive_type") == "zip") || + (libhal_device_get_property_QString(m_halContext, udi, "storage.drive_type") == "jaz")) + { + if (! libhal_device_get_property_bool(m_halContext, udi, "storage.removable.media_available", NULL) ) + allowNotification = false; + /* Create medium */ + Medium* medium = new Medium(udi, udi, ""); + // if the storage has a volume, we ignore it + if ( setFloppyProperties(medium) ) + m_mediaList.addMedium(medium, allowNotification); + else + delete medium; + return; + } + + /* Camera handled by gphoto2*/ + if (libhal_device_query_capability(m_halContext, udi, "camera", NULL) && + ((libhal_device_get_property_QString(m_halContext, udi, "camera.access_method")=="ptp") || + + (libhal_device_property_exists(m_halContext, udi, "camera.libgphoto2.support", NULL) && + libhal_device_get_property_bool(m_halContext, udi, "camera.libgphoto2.support", NULL))) + ) + { + /* Create medium */ + Medium* medium = new Medium(udi, udi, ""); + setCameraProperties(medium); + m_mediaList.addMedium(medium, allowNotification); + return; + } +} + +void HALBackend::RemoveDevice(const char *udi) +{ + const Medium *medium = m_mediaList.findByClearUdi(udi); + if (medium) { + ResetProperties(medium->id().ascii()); + } else { + m_mediaList.removeMedium(udi, true); + } +} + +void HALBackend::ModifyDevice(const char *udi, const char* key) +{ + kdDebug(1219) << "HALBackend::ModifyDevice for '" << udi << "' on '" << key << "'\n"; + + const char* mediumUdi = findMediumUdiFromUdi(udi); + if (!mediumUdi) + return; + bool allowNotification = false; + if (strcmp(key, "storage.removable.media_available") == 0) + allowNotification = libhal_device_get_property_bool(m_halContext, udi, key, NULL); + ResetProperties(mediumUdi, allowNotification); +} + +void HALBackend::DeviceCondition(const char* udi, const char* condition) +{ + TQString conditionName = TQString(condition); + kdDebug(1219) << "Processing device condition " << conditionName << " for " << udi << endl; + + if (conditionName == "EjectPressed") { + const Medium* medium = m_mediaList.findById(udi); + if (!medium) { + /* the ejectpressed appears on the drive and we need to find the volume */ + const TQPtrList<Medium> medlist = m_mediaList.list(); + TQPtrListIterator<Medium> it (medlist); + for ( const Medium *current_medium = it.current(); current_medium; current_medium = ++it) + { + if( current_medium->id().startsWith( "/org/kde" )) + continue; + TQString driveUdi = libhal_device_get_property_QString(m_halContext, current_medium->id().latin1(), "block.storage_device"); + if (driveUdi == udi) + { + medium = current_medium; + break; + } + } + } + if (medium) { + TDEProcess p; + p << "kio_media_mounthelper" << "-e" << medium->name(); + p.start(TDEProcess::DontCare); + } + } + + const char* mediumUdi = findMediumUdiFromUdi(udi); + kdDebug() << "findMedumUdiFromUdi " << udi << " returned " << mediumUdi << endl; + if (!mediumUdi) + return; + + /* TODO: Warn the user that (s)he should unmount devices before unplugging */ + if (conditionName == "VolumeUnmountForced") + ResetProperties(mediumUdi); + + /* Reset properties after mounting */ + if (conditionName == "VolumeMount") + ResetProperties(mediumUdi); + + /* Reset properties after unmounting */ + if (conditionName == "VolumeUnmount") + ResetProperties(mediumUdi); + +} + +void HALBackend::MainLoopIntegration(DBusConnection *dbusConnection) +{ + m_dBusQtConnection = new DBusQt::Connection(m_parent); + m_dBusQtConnection->dbus_connection_setup_with_qt_main(dbusConnection); +} + +/****************************************** + ** Properties attribution ** + ******************************************/ + +/* Return the medium udi that should be updated when recieving a call for + device udi */ +const char* HALBackend::findMediumUdiFromUdi(const char* udi) +{ + /* Easy part : this Udi is already registered as a device */ + const Medium* medium = m_mediaList.findById(udi); + if (medium) + return medium->id().ascii(); + + /* Hard part : this is a volume whose drive is registered */ + if (libhal_device_property_exists(m_halContext, udi, "info.capabilities", NULL)) + if (libhal_device_query_capability(m_halContext, udi, "volume", NULL)) + { + /* check if this belongs to an encrypted volume */ + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi); + if (!halVolume) return NULL; + const char* backingUdi = libhal_volume_crypto_get_backing_volume_udi(halVolume); + if (backingUdi != NULL) { + const char* result = findMediumUdiFromUdi(backingUdi); + libhal_volume_free(halVolume); + return result; + } + libhal_volume_free(halVolume); + + /* this is a volume whose drive is registered */ + TQString driveUdi = libhal_device_get_property_QString(m_halContext, udi, "block.storage_device"); + return findMediumUdiFromUdi(driveUdi.ascii()); + } + + return NULL; +} + +void HALBackend::ResetProperties(const char* mediumUdi, bool allowNotification) +{ + kdDebug(1219) << "HALBackend::setProperties" << endl; + if ( TQString::fromLatin1( mediumUdi ).startsWith( "/org/kde/" ) ) + { + const Medium *cmedium = m_mediaList.findById(mediumUdi); + if ( cmedium ) + { + Medium m( *cmedium ); + if ( setFstabProperties( &m ) ) { + kdDebug() << "setFstabProperties worked" << endl; + m_mediaList.changeMediumState(m, allowNotification); + } + return; + } + } + + Medium* m = new Medium(mediumUdi, mediumUdi, ""); + + if (libhal_device_query_capability(m_halContext, mediumUdi, "volume", NULL)) + setVolumeProperties(m); + if (libhal_device_query_capability(m_halContext, mediumUdi, "storage", NULL)) + setFloppyProperties(m); + if (libhal_device_query_capability(m_halContext, mediumUdi, "camera", NULL)) + setCameraProperties(m); + + m_mediaList.changeMediumState(*m, allowNotification); + + delete m; +} + +void HALBackend::setVolumeProperties(Medium* medium) +{ + kdDebug(1219) << "HALBackend::setVolumeProperties for " << medium->id() << endl; + + const char* udi = medium->id().ascii(); + /* Check if the device still exists */ + if (!libhal_device_exists(m_halContext, udi, NULL)) + return; + + /* Get device information from libhal-storage */ + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi); + if (!halVolume) + return; + TQString driveUdi = libhal_volume_get_storage_device_udi(halVolume); + LibHalDrive* halDrive = 0; + if ( !driveUdi.isNull() ) + halDrive = libhal_drive_from_udi(m_halContext, driveUdi.ascii()); + if (!halDrive) { + // at times HAL sends an UnmountForced event before the device is removed + libhal_volume_free(halVolume); + return; + } + + medium->setName( + generateName(libhal_volume_get_device_file(halVolume)) ); + + LibHalVolume* halClearVolume = NULL; + if ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") == "crypto" ) + { + kdDebug(1219) << "HALBackend::setVolumeProperties : crypto volume" << endl; + + medium->setEncrypted(true); + char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); + TQString clearUdiString; + if (clearUdi != NULL) { + kdDebug(1219) << "HALBackend::setVolumeProperties : crypto clear volume avail - " << clearUdi << endl; + halClearVolume = libhal_volume_from_udi(m_halContext, clearUdi); + // ignore if halClearVolume is NULL -> just not decrypted in this case + clearUdiString = clearUdi; + libhal_free_string(clearUdi); + } + + if (halClearVolume) + medium->mountableState( + libhal_volume_get_device_file(halVolume), /* Device node */ + clearUdiString, + libhal_volume_get_mount_point(halClearVolume), /* Mount point */ + libhal_volume_get_fstype(halClearVolume), /* Filesystem type */ + libhal_volume_is_mounted(halClearVolume) ); /* Mounted ? */ + else + medium->mountableState( + libhal_volume_get_device_file(halVolume), /* Device node */ + TQString::null, + TQString::null, /* Mount point */ + TQString::null, /* Filesystem type */ + false ); /* Mounted ? */ + } + else + { + kdDebug(1219) << "HALBackend::setVolumeProperties : normal volume" << endl; + medium->mountableState( + libhal_volume_get_device_file(halVolume), /* Device node */ + libhal_volume_get_mount_point(halVolume), /* Mount point */ + libhal_volume_get_fstype(halVolume), /* Filesystem type */ + libhal_volume_is_mounted(halVolume) ); /* Mounted ? */ + } + + + char* name = libhal_volume_policy_compute_display_name(halDrive, halVolume, m_halStoragePolicy); + TQString volume_name = TQString::fromUtf8(name); + TQString media_name = volume_name; + medium->setLabel(media_name); + free(name); + + TQString mimeType; + if (libhal_volume_is_disc(halVolume)) + { + mimeType = "media/cdrom" + MOUNT_SUFFIX; + + LibHalVolumeDiscType discType = libhal_volume_get_disc_type(halVolume); + if ((discType == LIBHAL_VOLUME_DISC_TYPE_CDROM) || + (discType == LIBHAL_VOLUME_DISC_TYPE_CDR) || + (discType == LIBHAL_VOLUME_DISC_TYPE_CDRW)) + if (libhal_volume_disc_is_blank(halVolume)) + { + mimeType = "media/blankcd"; + medium->unmountableState(""); + } + else + mimeType = "media/cdwriter" + MOUNT_SUFFIX; + + if ((discType == LIBHAL_VOLUME_DISC_TYPE_DVDROM) || (discType == LIBHAL_VOLUME_DISC_TYPE_DVDRAM) || + (discType == LIBHAL_VOLUME_DISC_TYPE_DVDR) || (discType == LIBHAL_VOLUME_DISC_TYPE_DVDRW) || + (discType == LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR) || (discType == LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW) ) + if (libhal_volume_disc_is_blank(halVolume)) + { + mimeType = "media/blankdvd"; + medium->unmountableState(""); + } + else + mimeType = "media/dvd" + MOUNT_SUFFIX; + + if (libhal_volume_disc_has_audio(halVolume) && !libhal_volume_disc_has_data(halVolume)) + { + mimeType = "media/audiocd"; + medium->unmountableState( "audiocd:/?device=" + TQString(libhal_volume_get_device_file(halVolume)) ); + } + + medium->setIconName(TQString::null); + + /* check if the disc id a vcd or a video dvd */ + DiscType type = LinuxCDPolling::identifyDiscType(libhal_volume_get_device_file(halVolume)); + switch (type) + { + case DiscType::VCD: + mimeType = "media/vcd"; + break; + case DiscType::SVCD: + mimeType = "media/svcd"; + break; + case DiscType::DVD: + mimeType = "media/dvdvideo"; + break; + } + } + else + { + mimeType = "media/hdd" + MOUNT_SUFFIX; + medium->setIconName(TQString::null); // reset icon + if (libhal_drive_is_hotpluggable(halDrive)) + { + mimeType = "media/removable" + MOUNT_SUFFIX; + medium->needMounting(); + switch (libhal_drive_get_type(halDrive)) { + case LIBHAL_DRIVE_TYPE_COMPACT_FLASH: + medium->setIconName("compact_flash" + MOUNT_ICON_SUFFIX); + break; + case LIBHAL_DRIVE_TYPE_MEMORY_STICK: + medium->setIconName("memory_stick" + MOUNT_ICON_SUFFIX); + break; + case LIBHAL_DRIVE_TYPE_SMART_MEDIA: + medium->setIconName("smart_media" + MOUNT_ICON_SUFFIX); + break; + case LIBHAL_DRIVE_TYPE_SD_MMC: + medium->setIconName("sd_mmc" + MOUNT_ICON_SUFFIX); + break; + case LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER: + { + medium->setIconName("ipod" + MOUNT_ICON_SUFFIX); + + if (libhal_device_get_property_QString(m_halContext, driveUdi.latin1(), "info.product") == "iPod" && + KProtocolInfo::isKnownProtocol( TQString("ipod") ) ) + { + medium->unmountableState( "ipod:/" ); + medium->mountableState( libhal_volume_is_mounted(halVolume) ); + } + break; + } + case LIBHAL_DRIVE_TYPE_CAMERA: + { + mimeType = "media/camera" + MOUNT_SUFFIX; + const char *physdev = libhal_drive_get_physical_device_udi(halDrive); + // get model from camera + if (physdev && libhal_device_query_capability(m_halContext, physdev, "camera", NULL)) + { + if (libhal_device_property_exists(m_halContext, physdev, "usb_device.product", NULL)) + medium->setLabel(libhal_device_get_property_QString(m_halContext, physdev, "usb_device.product")); + else if (libhal_device_property_exists(m_halContext, physdev, "usb.product", NULL)) + medium->setLabel(libhal_device_get_property_QString(m_halContext, physdev, "usb.product")); + } + break; + } + case LIBHAL_DRIVE_TYPE_TAPE: + medium->setIconName(TQString::null); //FIXME need icon + break; + default: + medium->setIconName(TQString::null); + } + + if (medium->isMounted() && TQFile::exists(medium->mountPoint() + "/dcim")) + { + mimeType = "media/camera" + MOUNT_SUFFIX; + } + } + } + medium->setMimeType(mimeType); + + libhal_drive_free(halDrive); + libhal_volume_free(halVolume); +} + +bool HALBackend::setFstabProperties( Medium *medium ) +{ + TQString mp = isInFstab(medium); + + if (!mp.isNull() && !medium->id().startsWith( "/org/kde" ) ) + { + // now that we know it's in fstab, we have to find out if it's mounted + KMountPoint::List mtab = KMountPoint::currentMountPoints(); + + KMountPoint::List::iterator it = mtab.begin(); + KMountPoint::List::iterator end = mtab.end(); + + bool mounted = false; + + for (; it!=end; ++it) + { + if ((*it)->mountedFrom() == medium->deviceNode() && (*it)->mountPoint() == mp ) + { + mounted = true; + break; + } + } + + kdDebug() << mp << " " << mounted << " " << medium->deviceNode() << " " << endl; + TQString fstype = medium->fsType(); + if ( fstype.isNull() ) + fstype = "auto"; + + medium->mountableState( + medium->deviceNode(), + mp, /* Mount point */ + fstype, /* Filesystem type */ + mounted ); /* Mounted ? */ + + return true; + } + + return false; + +} + +// Handle floppies and zip drives +bool HALBackend::setFloppyProperties(Medium* medium) +{ + kdDebug(1219) << "HALBackend::setFloppyProperties for " << medium->id() << endl; + + const char* udi = medium->id().ascii(); + /* Check if the device still exists */ + if (!libhal_device_exists(m_halContext, udi, NULL)) + return false; + + LibHalDrive* halDrive = libhal_drive_from_udi(m_halContext, udi); + if (!halDrive) + return false; + + TQString drive_type = libhal_device_get_property_QString(m_halContext, udi, "storage.drive_type"); + + if (drive_type == "zip") { + int numVolumes; + char** volumes = libhal_drive_find_all_volumes(m_halContext, halDrive, &numVolumes); + libhal_free_string_array(volumes); + kdDebug(1219) << " found " << numVolumes << " volumes" << endl; + if (numVolumes) + { + libhal_drive_free(halDrive); + return false; + } + } + + medium->setName( generateName(libhal_drive_get_device_file(halDrive)) ); + medium->setLabel(i18n("Unknown Drive")); + + // HAL hates floppies - so we have to do it twice ;( + medium->mountableState(libhal_drive_get_device_file(halDrive), TQString::null, TQString::null, false); + setFloppyMountState(medium); + + if (drive_type == "floppy") + { + if (medium->isMounted()) // don't use _SUFFIX here as it accesses the volume + medium->setMimeType("media/floppy_mounted" ); + else + medium->setMimeType("media/floppy_unmounted"); + medium->setLabel(i18n("Floppy Drive")); + } + else if (drive_type == "zip") + { + if (medium->isMounted()) + medium->setMimeType("media/zip_mounted" ); + else + medium->setMimeType("media/zip_unmounted"); + medium->setLabel(i18n("Zip Drive")); + } + + /** @todo And mimtype for JAZ drives ? */ + + medium->setIconName(TQString::null); + + libhal_drive_free(halDrive); + + return true; +} + +void HALBackend::setFloppyMountState( Medium *medium ) +{ + if ( !medium->id().startsWith( "/org/kde" ) ) + { + KMountPoint::List mtab = KMountPoint::currentMountPoints(); + KMountPoint::List::iterator it = mtab.begin(); + KMountPoint::List::iterator end = mtab.end(); + + TQString fstype; + TQString mountpoint; + for (; it!=end; ++it) + { + if ((*it)->mountedFrom() == medium->deviceNode() ) + { + fstype = (*it)->mountType().isNull() ? (*it)->mountType() : "auto"; + mountpoint = (*it)->mountPoint(); + medium->mountableState( medium->deviceNode(), mountpoint, fstype, true ); + return; + } + } + } +} + +void HALBackend::setCameraProperties(Medium* medium) +{ + kdDebug(1219) << "HALBackend::setCameraProperties for " << medium->id() << endl; + + const char* udi = medium->id().ascii(); + /* Check if the device still exists */ + if (!libhal_device_exists(m_halContext, udi, NULL)) + return; + + /** @todo find name */ + medium->setName("camera"); + + TQString device = "camera:/"; + + char *cam = libhal_device_get_property_string(m_halContext, udi, "camera.libgphoto2.name", NULL); + DBusError error; + dbus_error_init(&error); + if (cam && + libhal_device_property_exists(m_halContext, udi, "usb.linux.device_number", NULL) && + libhal_device_property_exists(m_halContext, udi, "usb.bus_number", NULL)) + device.sprintf("camera://%s@[usb:%03d,%03d]/", cam, + libhal_device_get_property_int(m_halContext, udi, "usb.bus_number", &error), + libhal_device_get_property_int(m_halContext, udi, "usb.linux.device_number", &error)); + + libhal_free_string(cam); + + /** @todo find the rest of this URL */ + medium->unmountableState(device); + medium->setMimeType("media/gphoto2camera"); + medium->setIconName(TQString::null); + if (libhal_device_property_exists(m_halContext, udi, "usb_device.product", NULL)) + medium->setLabel(libhal_device_get_property_QString(m_halContext, udi, "usb_device.product")); + else if (libhal_device_property_exists(m_halContext, udi, "usb.product", NULL)) + medium->setLabel(libhal_device_get_property_QString(m_halContext, udi, "usb.product")); + else + medium->setLabel(i18n("Camera")); +} + +TQString HALBackend::generateName(const TQString &devNode) +{ + return KURL(devNode).fileName(); +} + +/****************************************** + ** HAL CALL-BACKS ** + ******************************************/ + +void HALBackend::hal_device_added(LibHalContext *ctx, const char *udi) +{ + kdDebug(1219) << "HALBackend::hal_device_added " << udi << endl; + Q_UNUSED(ctx); + s_HALBackend->AddDevice(udi); +} + +void HALBackend::hal_device_removed(LibHalContext *ctx, const char *udi) +{ + kdDebug(1219) << "HALBackend::hal_device_removed " << udi << endl; + Q_UNUSED(ctx); + s_HALBackend->RemoveDevice(udi); +} + +void HALBackend::hal_device_property_modified(LibHalContext *ctx, const char *udi, + const char *key, dbus_bool_t is_removed, dbus_bool_t is_added) +{ + kdDebug(1219) << "HALBackend::hal_property_modified " << udi << " -- " << key << endl; + Q_UNUSED(ctx); + Q_UNUSED(is_removed); + Q_UNUSED(is_added); + s_HALBackend->ModifyDevice(udi, key); +} + +void HALBackend::hal_device_condition(LibHalContext *ctx, const char *udi, + const char *condition_name, + const char* message + ) +{ + kdDebug(1219) << "HALBackend::hal_device_condition " << udi << " -- " << condition_name << endl; + Q_UNUSED(ctx); + Q_UNUSED(message); + s_HALBackend->DeviceCondition(udi, condition_name); +} + +TQStringList HALBackend::getHALmountoptions(TQString udi) +{ + const char* _ppt_string; + LibHalVolume* volume; + LibHalDrive* drive; + + TQString _ppt_TQString; + + volume = libhal_volume_from_udi( m_halContext, udi.latin1() ); + if( volume ) + drive = libhal_drive_from_udi( m_halContext, libhal_volume_get_storage_device_udi( volume ) ); + else + drive = libhal_drive_from_udi( m_halContext, udi.latin1() ); + + if( !drive ) + return TQString::null; + + if( volume ) + _ppt_string = libhal_volume_policy_get_mount_options ( drive, volume, NULL ); + else + _ppt_string = libhal_drive_policy_get_mount_options ( drive, NULL ); + + _ppt_TQString = TQString(_ppt_string ? _ppt_string : ""); + + return TQStringList::split(",",_ppt_TQString); +} + +TQStringList HALBackend::mountoptions(const TQString &name) +{ + const Medium* medium = m_mediaList.findById(name); + if (!medium) + return TQStringList(); // we don't know about that one + if (!isInFstab(medium).isNull()) + return TQStringList(); // not handled by HAL - fstab entry + + TQString volume_udi = name; + if (medium->isEncrypted()) { + // see if we have a clear volume + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1()); + if (halVolume) { + char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); + if (clearUdi != NULL) { + volume_udi = clearUdi; + libhal_free_string(clearUdi); + } else { + // if not decrypted yet then no mountoptions + return TQStringList(); + } + libhal_volume_free(halVolume); + } else { + // strange... + return TQStringList(); + } + } + + TDEConfig config("mediamanagerrc"); + + bool use_defaults = true; + if (config.hasGroup(name)) + { + config.setGroup(name); + use_defaults = config.readBoolEntry("use_defaults", false); + } + + if (use_defaults) + config.setGroup("DefaultOptions"); + + char ** array = libhal_device_get_property_strlist(m_halContext, volume_udi.latin1(), "volume.mount.valid_options", NULL); + TQMap<TQString,bool> valids; + + for (int index = 0; array && array[index]; ++index) { + TQString t = array[index]; + if (t.endsWith("=")) + t = t.left(t.length() - 1); + valids[t] = true; + kdDebug() << "valid " << t << endl; + } + libhal_free_string_array(array); + TQStringList result; + TQString tmp; + + result << TQString("use_defaults=%1").arg(use_defaults ? "true" : "false"); + + TQString fstype = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.fstype"); + if (fstype.isNull()) + fstype = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.policy.mount_filesystem"); + + TQString drive_udi = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "block.storage_device"); + + bool removable = false; + if ( !drive_udi.isNull() ) + removable = libhal_device_get_property_bool(m_halContext, drive_udi.latin1(), "storage.removable", NULL) + || libhal_device_get_property_bool(m_halContext, drive_udi.latin1(), "storage.hotpluggable", NULL); + + bool value; + if (use_defaults) + { + value = config.readBoolEntry("automount", false); + } + else + { + QString current_group = config.group(); + config.setGroup(drive_udi); + value = config.readBoolEntry("automount", false); + config.setGroup(current_group); + } + + if (libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_blank", NULL) + || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_vcd", NULL) + || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_svcd", NULL) + || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_videodvd", NULL) + || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.has_audio", NULL)) + value = false; + + result << TQString("automount=%1").arg(value ? "true" : "false"); + + if (valids.contains("ro")) + { + value = config.readBoolEntry("ro", false); + tmp = TQString("ro=%1").arg(value ? "true" : "false"); + if (fstype != "iso9660") // makes no sense + result << tmp; + } + + if (valids.contains("quiet")) + { + value = config.readBoolEntry("quiet", false); + tmp = TQString("quiet=%1").arg(value ? "true" : "false"); + if (fstype != "iso9660") // makes no sense + result << tmp; + } + + if (valids.contains("flush")) + { + value = config.readBoolEntry("flush", fstype.endsWith("fat")); + tmp = TQString("flush=%1").arg(value ? "true" : "false"); + result << tmp; + } + + if (valids.contains("uid")) + { + value = config.readBoolEntry("uid", true); + tmp = TQString("uid=%1").arg(value ? "true" : "false"); + result << tmp; + } + + if (valids.contains("utf8")) + { + value = config.readBoolEntry("utf8", true); + tmp = TQString("utf8=%1").arg(value ? "true" : "false"); + result << tmp; + } + + if (valids.contains("shortname")) + { + TQString svalue = config.readEntry("shortname", "lower").lower(); + if (svalue == "winnt") + result << "shortname=winnt"; + else if (svalue == "win95") + result << "shortname=win95"; + else if (svalue == "mixed") + result << "shortname=mixed"; + else + result << "shortname=lower"; + } + + // pass our locale to the ntfs-3g driver so it can translate local characters + if (valids.contains("locale") && fstype == "ntfs-3g") + { + // 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")) ) { + result << TQString("locale=%1").arg(cType); + } + } + + if (valids.contains("sync")) + { + value = config.readBoolEntry("sync", ( valids.contains("flush") && !fstype.endsWith("fat") ) && removable); + tmp = TQString("sync=%1").arg(value ? "true" : "false"); + if (fstype != "iso9660") // makes no sense + result << tmp; + } + + if (valids.contains("noatime")) + { + value = config.readBoolEntry("atime", !fstype.endsWith("fat")); + tmp = TQString("atime=%1").arg(value ? "true" : "false"); + if (fstype != "iso9660") // makes no sense + result << tmp; + } + + TQString mount_point = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.mount_point"); + if (mount_point.isEmpty()) + mount_point = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.policy.desired_mount_point"); + + mount_point = config.readEntry("mountpoint", mount_point); + + if (!mount_point.startsWith("/")) + mount_point = "/media/" + mount_point; + + result << TQString("mountpoint=%1").arg(mount_point); + result << TQString("filesystem=%1").arg(fstype); + + if (valids.contains("data")) + { + TQString svalue = config.readEntry("journaling").lower(); + if (svalue == "ordered") + result << "journaling=ordered"; + else if (svalue == "writeback") + result << "journaling=writeback"; + else if (svalue == "data") + result << "journaling=data"; + else + result << "journaling=ordered"; + } + + return result; +} + +bool HALBackend::setMountoptions(const TQString &name, const TQStringList &options ) +{ + kdDebug() << "setMountoptions " << name << " " << options << endl; + + TDEConfig config("mediamanagerrc"); + config.setGroup(name); + + TQMap<TQString,TQString> valids = MediaManagerUtils::splitOptions(options); + + const char *names[] = { "use_defaults", "ro", "quiet", "atime", "uid", "utf8", "flush", "sync", 0 }; + for (int index = 0; names[index]; ++index) + if (valids.contains(names[index])) + config.writeEntry(names[index], valids[names[index]] == "true"); + + if (valids.contains("shortname")) + config.writeEntry("shortname", valids["shortname"]); + + if (valids.contains("journaling")) + config.writeEntry("journaling", valids["journaling"]); + + if (!mountoptions(name).contains(TQString("mountpoint=%1").arg(valids["mountpoint"]))) + config.writeEntry("mountpoint", valids["mountpoint"]); + + if (valids.contains("automount")) { + TQString drive_udi = libhal_device_get_property_QString(m_halContext, name.latin1(), "block.storage_device"); + config.setGroup(drive_udi); + config.writeEntry("automount", valids["automount"]); + } + + return true; +} + +TQString startKdeSudoProcess(const TQString& tdesudoPath, const TQString& command, + const TQString& dialogCaption, const TQString& dialogComment) +{ + TDEProcess tdesudoProcess; + + tdesudoProcess << tdesudoPath + << "-d" + << "--noignorebutton" + << "--caption" << dialogCaption + << "--comment" << dialogComment + << "-c" << command; + + // @todo handle tdesudo output + tdesudoProcess.start(TDEProcess::Block); + + return TQString(); +} + +TQString startKdeSuProcess(const TQString& tdesuPath, const TQString& command, + const TQString& dialogCaption) +{ + TDEProcess tdesuProcess; + + tdesuProcess << tdesuPath + << "-d" + << "--noignorebutton" + << "--caption" << dialogCaption + << "-c" << command; + + // @todo handle tdesu output + tdesuProcess.start(TDEProcess::Block); + + return TQString(); +} + +TQString startPrivilegedProcess(const TQString& command, const TQString& dialogCaption, const TQString& dialogComment) +{ + TQString error; + + TQString tdesudoPath = KStandardDirs::findExe("tdesudo"); + + if (!tdesudoPath.isEmpty()) + error = startKdeSudoProcess(tdesudoPath, command, dialogCaption, dialogComment); + else { + TQString tdesuPath = KStandardDirs::findExe("tdesu"); + + if (!tdesuPath.isEmpty()) + error = startKdeSuProcess(tdesuPath, command, dialogCaption); + } + + return error; +} + +TQString privilegedMount(const char* udi, const char* mountPoint, const char** options, int numberOfOptions) +{ + TQString error; + + kdDebug() << "run privileged mount for " << udi << endl; + + TQString dbusSendPath = KStandardDirs::findExe("dbus-send"); + + // @todo return error message + if (dbusSendPath.isEmpty()) + return TQString(); + + TQString mountOptions; + TQTextOStream optionsStream(&mountOptions); + for (int optionIndex = 0; optionIndex < numberOfOptions; optionIndex++) { + optionsStream << options[optionIndex]; + if (optionIndex < numberOfOptions - 1) + optionsStream << ","; + } + + TQString command; + TQTextOStream(&command) << dbusSendPath + << " --system --print-reply --dest=org.freedesktop.Hal " << udi + << " org.freedesktop.Hal.Device.Volume.Mount string:" << mountPoint + << " string: array:string:" << mountOptions; + + kdDebug() << "command: " << command << endl; + + error = startPrivilegedProcess(command, + i18n("Authenticate"), + i18n("<big><b>System policy prevents mounting internal media</b></big><br/>Authentication is required to perform this action. Please enter your password to verify.")); + + return error; +} + +TQString privilegedUnmount(const char* udi) +{ + TQString error; + + kdDebug() << "run privileged unmount for " << udi << endl; + + TQString dbusSendPath = KStandardDirs::findExe("dbus-send"); + + // @todo return error message + if (dbusSendPath.isEmpty()) + return TQString(); + + TQString command; + TQTextOStream(&command) << dbusSendPath + << " --system --print-reply --dest=org.freedesktop.Hal " << udi + << " org.freedesktop.Hal.Device.Volume.Unmount array:string:force"; + + kdDebug() << "command: " << command << endl; + + error = startPrivilegedProcess(command, + i18n("Authenticate"), + i18n("<big><b>System policy prevents unmounting media mounted by other users</b></big><br/>Authentication is required to perform this action. Please enter your password to verify.")); + + return error; +} + +static TQString mount_priv(const char *udi, const char *mount_point, const char **poptions, int noptions, + DBusConnection *dbus_connection) +{ + DBusMessage *dmesg, *reply; + DBusError error; + + const char *fstype = ""; + if (!(dmesg = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume", + "Mount"))) { + kdDebug() << "mount failed for " << udi << ": could not create dbus message\n"; + return i18n("Internal Error"); + } + + if (!dbus_message_append_args (dmesg, DBUS_TYPE_STRING, &mount_point, DBUS_TYPE_STRING, &fstype, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &poptions, noptions, + DBUS_TYPE_INVALID)) + { + kdDebug() << "mount failed for " << udi << ": could not append args to dbus message\n"; + dbus_message_unref (dmesg); + return i18n("Internal Error"); + } + + TQString qerror; + + dbus_error_init (&error); + if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, dmesg, -1, &error))) + { + TQString qerror = error.message; + kdError() << "mount failed for " << udi << ": " << error.name << " - " << qerror << endl; + if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.UnknownFilesystemType")) + qerror = i18n("Invalid filesystem type"); + else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.PermissionDenied")) + qerror = i18n("Permission denied<p>Please ensure that:<br>1. You have permission to access this device.<br>2. This device node is not listed in /etc/fstab.</p>"); + else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy")) + qerror = privilegedMount(udi, mount_point, poptions, noptions); + else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.AlreadyMounted")) + qerror = i18n("Device is already mounted."); + else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.InvalidMountpoint") && strlen(mount_point)) { + dbus_message_unref (dmesg); + dbus_error_free (&error); + return mount_priv(udi, "", poptions, noptions, dbus_connection); + } + dbus_message_unref (dmesg); + dbus_error_free (&error); + return qerror; + } + + kdDebug() << "mount queued for " << udi << endl; + + dbus_message_unref (dmesg); + dbus_message_unref (reply); + + return qerror; + +} + +TQString HALBackend::listUsingProcesses(const Medium* medium) +{ + TQString proclist, fullmsg; + TQString cmdline = TQString("/usr/bin/env fuser -vm %1 2>&1").arg(TDEProcess::quote(medium->mountPoint())); + FILE *fuser = popen(cmdline.latin1(), "r"); + + uint counter = 0; + if (fuser) { + proclist += "<pre>"; + TQTextIStream is(fuser); + TQString tmp; + while (!is.atEnd()) { + tmp = is.readLine(); + tmp = TQStyleSheet::escape(tmp) + "\n"; + + proclist += tmp; + if (counter++ > 10) + { + proclist += "..."; + break; + } + } + proclist += "</pre>"; + (void)pclose( fuser ); + } + if (counter) { + fullmsg = i18n("Moreover, programs still using the device " + "have been detected. They are listed below. You have to " + "close them or change their working directory before " + "attempting to unmount the device again."); + fullmsg += "<br>" + proclist; + return fullmsg; + } else { + return TQString::null; + } +} + +TQString HALBackend::killUsingProcesses(const Medium* medium) +{ + TQString proclist, fullmsg; + TQString cmdline = TQString("/usr/bin/env fuser -vmk %1 2>&1").arg(TDEProcess::quote(medium->mountPoint())); + FILE *fuser = popen(cmdline.latin1(), "r"); + + uint counter = 0; + if (fuser) { + proclist += "<pre>"; + TQTextIStream is(fuser); + TQString tmp; + while (!is.atEnd()) { + tmp = is.readLine(); + tmp = TQStyleSheet::escape(tmp) + "\n"; + + proclist += tmp; + if (counter++ > 10) + { + proclist += "..."; + break; + } + } + proclist += "</pre>"; + (void)pclose( fuser ); + } + if (counter) { + fullmsg = i18n("Programs that were still using the device " + "have been forcibly terminated. They are listed below."); + fullmsg += "<br>" + proclist; + return fullmsg; + } else { + return TQString::null; + } +} + +void HALBackend::slotResult(TDEIO::Job *job) +{ + kdDebug() << "slotResult " << mount_jobs[job] << endl; + + struct mount_job_data *data = mount_jobs[job]; + TQString& qerror = data->errorMessage; + const Medium* medium = data->medium; + + if (job->error() == TDEIO::ERR_COULD_NOT_UNMOUNT) { + TQString proclist(listUsingProcesses(medium)); + + qerror = "<qt>"; + qerror += "<p>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and " + "currently mounted at <b>%4</b> could not be unmounted. ").arg( + "system:/media/" + medium->name(), + medium->deviceNode(), + medium->prettyLabel(), + medium->prettyBaseURL().pathOrURL()) + "</p>"; + qerror += "<p>" + i18n("The following error was returned by umount command:"); + qerror += "</p><pre>" + job->errorText() + "</pre>"; + + if (!proclist.isEmpty()) { + qerror += proclist; + } + qerror += "</qt>"; + } else if (job->error()) { + qerror = job->errorText(); + } + + ResetProperties( medium->id().latin1() ); + mount_jobs.remove(job); + + /* Job completed. Notify the caller */ + data->error = job->error(); + data->completed = true; + kapp->eventLoop()->exitLoop(); +} + +TQString HALBackend::isInFstab(const Medium *medium) +{ + KMountPoint::List fstab = KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions|KMountPoint::NeedRealDeviceName); + + KMountPoint::List::iterator it = fstab.begin(); + KMountPoint::List::iterator end = fstab.end(); + + for (; it!=end; ++it) + { + TQString reald = (*it)->realDeviceName(); + if ( reald.endsWith( "/" ) ) + reald = reald.left( reald.length() - 1 ); + kdDebug() << "isInFstab -" << medium->deviceNode() << "- -" << reald << "- -" << (*it)->mountedFrom() << "-" << endl; + if ((*it)->mountedFrom() == medium->deviceNode() || ( !medium->deviceNode().isEmpty() && reald == medium->deviceNode() ) ) + { + TQStringList opts = (*it)->mountOptions(); + if (opts.contains("user") || opts.contains("users")) + return (*it)->mountPoint(); + } + } + + return TQString::null; +} + +TQString HALBackend::mount(const Medium *medium) +{ + if (medium->isMounted()) + return TQString(); // that was easy + + TQString mountPoint = isInFstab(medium); + if (!mountPoint.isNull()) + { + struct mount_job_data data; + data.completed = false; + data.medium = medium; + + kdDebug() << "triggering user mount " << medium->deviceNode() << " " << mountPoint << " " << medium->id() << endl; + TDEIO::Job *job = TDEIO::mount( false, 0, medium->deviceNode(), mountPoint ); + connect(job, TQT_SIGNAL( result (TDEIO::Job *)), + TQT_SLOT( slotResult( TDEIO::Job *))); + mount_jobs[job] = &data; + // The caller expects the device to be mounted when the function + // completes. Thus block until the job completes. + while (!data.completed) { + kapp->eventLoop()->enterLoop(); + } + // Return the error message (if any) to the caller + return (data.error) ? data.errorMessage : TQString::null; + + } else if (medium->id().startsWith("/org/kde/") ) + return i18n("Permission denied"); + + TQStringList soptions; + + kdDebug() << "mounting " << medium->id() << "..." << endl; + + TQMap<TQString,TQString> valids = MediaManagerUtils::splitOptions(mountoptions(medium->id())); + if (valids["flush"] == "true") + soptions << "flush"; + + if ((valids["uid"] == "true") && (medium->fsType() != "ntfs")) + { + soptions << TQString("uid=%1").arg(getuid()); + } + + if (valids["ro"] == "true") + soptions << "ro"; + + if (valids["atime"] != "true") + soptions << "noatime"; + + if (valids["quiet"] == "true") + soptions << "quiet"; + + if (valids["utf8"] == "true") + soptions << "utf8"; + + if (valids["sync"] == "true") + soptions << "sync"; + + if (medium->fsType() == "ntfs") { + TQString fsLocale("locale="); + fsLocale += setlocale(LC_ALL, ""); + + soptions << fsLocale; + } + + TQString mount_point = valids["mountpoint"]; + if (mount_point.startsWith("/media/")) + mount_point = mount_point.mid(7); + + if (valids.contains("shortname")) + { + soptions << TQString("shortname=%1").arg(valids["shortname"]); + } + + if (valids.contains("locale")) + { + soptions << TQString("locale=%1").arg(valids["locale"]); + } + + if (valids.contains("journaling")) + { + TQString option = valids["journaling"]; + if (option == "data") + soptions << TQString("data=journal"); + else if (option == "writeback") + soptions << TQString("data=writeback"); + else + soptions << TQString("data=ordered"); + } + + TQStringList hal_mount_options = getHALmountoptions(medium->id()); + for (TQValueListIterator<TQString> it=hal_mount_options.begin();it!=hal_mount_options.end();it++) + { + soptions << *it; + kdDebug()<<"HALOption: "<<*it<<endl; + if ((*it).startsWith("iocharset=")) + { + soptions.remove("utf8"); + kdDebug()<<"\"iocharset=\" found. Removing \"utf8\" from options."<<endl; + } + } + + + const char **options = new const char*[soptions.size() + 1]; + uint noptions = 0; + for (TQStringList::ConstIterator it = soptions.begin(); it != soptions.end(); ++it, ++noptions) + { + options[noptions] = (*it).latin1(); + kdDebug()<<"Option: "<<*it<<endl; + } + options[noptions] = NULL; + + TQString qerror = i18n("Cannot mount encrypted drives!"); + + if (!medium->isEncrypted()) { + // normal volume + qerror = mount_priv(medium->id().latin1(), mount_point.utf8(), options, noptions, dbus_connection); + } else { + // see if we have a clear volume + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1()); + if (halVolume) { + char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); + if (clearUdi != NULL) { + qerror = mount_priv(clearUdi, mount_point.utf8(), options, noptions, dbus_connection); + libhal_free_string(clearUdi); + } + libhal_volume_free(halVolume); + } + } + + if (!qerror.isEmpty()) { + kdError() << "mounting " << medium->id() << " returned " << qerror << endl; + return qerror; + } + + medium->setHalMounted(true); + ResetProperties(medium->id().latin1()); + + return TQString(); +} + +TQString HALBackend::mount(const TQString &_udi) +{ + const Medium* medium = m_mediaList.findById(_udi); + if (!medium) + return i18n("No such medium: %1").arg(_udi); + + return mount(medium); +} + +TQString HALBackend::unmount(const TQString &_udi) +{ + const Medium* medium = m_mediaList.findById(_udi); + if (!medium) + { // now we get fancy: if the udi is no volume, it _might_ be a device with only one + // volume on it (think CDs) - so we're so nice to the caller to unmount that volume + LibHalDrive* halDrive = libhal_drive_from_udi(m_halContext, _udi.latin1()); + if (halDrive) + { + int numVolumes; + char** volumes = libhal_drive_find_all_volumes(m_halContext, halDrive, &numVolumes); + if (numVolumes == 1) + medium = m_mediaList.findById( volumes[0] ); + } + } + + if ( !medium ) + return i18n("No such medium: %1").arg(_udi); + + if (!medium->isMounted()) + return TQString(); // that was easy + + TQString mountPoint = isInFstab(medium); + if (!mountPoint.isNull()) + { + struct mount_job_data data; + data.completed = false; + data.medium = medium; + + kdDebug() << "triggering user unmount " << medium->deviceNode() << " " << mountPoint << endl; + TDEIO::Job *job = TDEIO::unmount( medium->mountPoint(), false ); + connect(job, TQT_SIGNAL( result (TDEIO::Job *)), + TQT_SLOT( slotResult( TDEIO::Job *))); + mount_jobs[job] = &data; + // The caller expects the device to be unmounted when the function + // completes. Thus block until the job completes. + while (!data.completed) { + kapp->eventLoop()->enterLoop(); + } + // Return the error message (if any) to the caller + return (data.error) ? data.errorMessage : TQString::null; + } + + DBusMessage *dmesg, *reply; + DBusError error; + const char *options[2]; + TQString udi = TQString::null; + + if (!medium->isEncrypted()) { + // normal volume + udi = medium->id(); + } else { + // see if we have a clear volume + LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1()); + if (halVolume) { + char *clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); + udi = clearUdi; + libhal_free_string(clearUdi); + libhal_volume_free(halVolume); + } + } + if (udi.isNull()) { + kdDebug() << "unmount failed: no udi" << endl; + return i18n("Internal Error"); + } + + kdDebug() << "unmounting " << udi << "..." << endl; + + dbus_error_init(&error); + DBusConnection *dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (dbus_error_is_set(&error)) + { + dbus_error_free(&error); + return false; + } + + if (!(dmesg = dbus_message_new_method_call ("org.freedesktop.Hal", udi.latin1(), + "org.freedesktop.Hal.Device.Volume", + "Unmount"))) { + kdDebug() << "unmount failed for " << udi << ": could not create dbus message\n"; + return i18n("Internal Error"); + } + + options[0] = "force"; + options[1] = 0; + + if (!dbus_message_append_args (dmesg, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, 0, + DBUS_TYPE_INVALID)) + { + kdDebug() << "unmount failed for " << udi << ": could not append args to dbus message\n"; + dbus_message_unref (dmesg); + return i18n("Internal Error"); + } + + char thisunmounthasfailed = 0; + dbus_error_init (&error); + if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, dmesg, -1, &error))) + { + thisunmounthasfailed = 1; + TQString qerror, reason, origqerror; + + if (!strcmp(error.name, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy")) { + qerror = privilegedUnmount(udi.latin1()); + + if (qerror.isEmpty()) { + dbus_message_unref(dmesg); + dbus_error_free(&error); + return TQString(); + } + + // @todo handle unmount error message + } + + kdDebug() << "unmount failed for " << udi << ": " << error.name << " " << error.message << endl; + qerror = "<qt>"; + qerror += "<p>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and " + "currently mounted at <b>%4</b> could not be unmounted. ").arg( + "system:/media/" + medium->name(), + medium->deviceNode(), + medium->prettyLabel(), + medium->prettyBaseURL().pathOrURL()) + "</p>"; + qerror += "<p>" + i18n("Unmounting failed due to the following error:") + "</p>"; + if (!strcmp(error.name, "org.freedesktop.Hal.Device.Volume.Busy")) { + reason = i18n("Device is Busy:"); + thisunmounthasfailed = 2; + } else if (!strcmp(error.name, "org.freedesktop.Hal.Device.Volume.NotMounted")) { + // this is faking. The error is that the device wasn't mounted by hal (but by the system) + reason = i18n("Permission denied<p>Please ensure that:<br>1. You have permission to access this device.<br>2. This device was originally mounted using TDE.</p>"); + } else { + reason = error.message; + } + qerror += "<p><b>" + reason + "</b></p>"; + origqerror = qerror; + + // Include list of processes (if any) using the device in the error message + reason = listUsingProcesses(medium); + if (!reason.isEmpty()) { + qerror += reason; + if (thisunmounthasfailed == 2) { // Failed as BUSY + if (KMessageBox::warningYesNo(0, i18n("%1<p><b>Would you like to forcibly terminate these processes?</b><br><i>All unsaved data would be lost</i>").arg(qerror)) == KMessageBox::Yes) { + qerror = origqerror; + reason = killUsingProcesses(medium); + qerror = HALBackend::unmount(udi); + if (qerror.isNull()) { + thisunmounthasfailed = 0; + } + } + } + } + + if (thisunmounthasfailed != 0) { + dbus_message_unref (dmesg); + dbus_error_free (&error); + return qerror; + } + } + + kdDebug() << "unmount queued for " << udi << endl; + + dbus_message_unref (dmesg); + dbus_message_unref (reply); + + medium->setHalMounted(false); + ResetProperties(medium->id().latin1()); + + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + + return TQString(); +} + +TQString HALBackend::decrypt(const TQString &_udi, const TQString &password) +{ + const Medium* medium = m_mediaList.findById(_udi); + if (!medium) + return i18n("No such medium: %1").arg(_udi); + + if (!medium->isEncrypted() || !medium->clearDeviceUdi().isNull()) + return TQString(); + + const char *udi = medium->id().latin1(); + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + DBusError error; + + kdDebug() << "Setting up " << udi << " for crypto\n" <<endl; + + msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume.Crypto", + "Setup"); + if (msg == NULL) { + kdDebug() << "decrypt failed for " << udi << ": could not create dbus message\n"; + return i18n("Internal Error"); + } + + TQCString pwdUtf8 = password.utf8(); + const char *pwd_utf8 = pwdUtf8; + if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &pwd_utf8, DBUS_TYPE_INVALID)) { + kdDebug() << "decrypt failed for " << udi << ": could not append args to dbus message\n"; + dbus_message_unref (msg); + return i18n("Internal Error"); + } + + dbus_error_init (&error); + if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error)) || + dbus_error_is_set (&error)) + { + TQString qerror = i18n("Internal Error"); + kdDebug() << "decrypt failed for " << udi << ": " << error.name << " " << error.message << endl; + if (strcmp (error.name, "org.freedesktop.Hal.Device.Volume.Crypto.SetupPasswordError") == 0) { + qerror = i18n("Wrong password"); + } + dbus_error_free (&error); + dbus_message_unref (msg); + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + return qerror; + } + + dbus_message_unref (msg); + dbus_message_unref (reply); + + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + + return TQString(); +} + +TQString HALBackend::undecrypt(const TQString &_udi) +{ + const Medium* medium = m_mediaList.findById(_udi); + if (!medium) + return i18n("No such medium: %1").arg(_udi); + + if (!medium->isEncrypted() || medium->clearDeviceUdi().isNull()) + return TQString(); + + const char *udi = medium->id().latin1(); + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + DBusError error; + + kdDebug() << "Tear down " << udi << "\n" <<endl; + + msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi, + "org.freedesktop.Hal.Device.Volume.Crypto", + "Teardown"); + if (msg == NULL) { + kdDebug() << "teardown failed for " << udi << ": could not create dbus message\n"; + return i18n("Internal Error"); + } + + if (!dbus_message_append_args (msg, DBUS_TYPE_INVALID)) { + kdDebug() << "teardown failed for " << udi << ": could not append args to dbus message\n"; + dbus_message_unref (msg); + return i18n("Internal Error"); + } + + dbus_error_init (&error); + if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error)) || + dbus_error_is_set (&error)) + { + TQString qerror = i18n("Internal Error"); + kdDebug() << "teardown failed for " << udi << ": " << error.name << " " << error.message << endl; + dbus_error_free (&error); + dbus_message_unref (msg); + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + return qerror; + } + + dbus_message_unref (msg); + dbus_message_unref (reply); + + ResetProperties(udi); + + while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; + + return TQString(); +} + +#include "halbackend.moc" diff --git a/tdeioslave/media/mediamanager/halbackend.h b/tdeioslave/media/mediamanager/halbackend.h new file mode 100644 index 000000000..8c8bbfce6 --- /dev/null +++ b/tdeioslave/media/mediamanager/halbackend.h @@ -0,0 +1,232 @@ +/* This file is part of the KDE Project + Copyright (c) 2004-2005 Jérôme Lodewyck <jerome dot lodewyck at normalesup dot org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/** +* This is a media:/ backend for the freedesktop Hardware Abstraction Layer +* Usage : create an instance of HALBackend, then call InitHal(). A false +* result from the later function means that something went wrong and that +* the backend shall not be used. +* +* @author Jérôme Lodewyck <jerome dot lodewyck at normalesup dot org> +* @short media:/ backend for the HAL +*/ + +#ifndef _HALBACKEND_H_ +#define _HALBACKEND_H_ + +#include "backendbase.h" + +#include <tqobject.h> +#include <tqstringlist.h> +#include <tqstring.h> + +#include <config.h> + +/* We acknowledge the the dbus API is unstable */ +#define DBUS_API_SUBJECT_TO_CHANGE +/* DBus-Qt bindings */ +#include <dbus/connection.h> +/* HAL libraries */ +#include <libhal.h> +#include <libhal-storage.h> + +namespace TDEIO { + class Job; +} + +class HALBackend : public TQObject, public BackendBase +{ +Q_OBJECT + +public: + /** + * Constructor + */ + HALBackend(MediaList &list, TQObject* parent); + + /** + * Destructor + */ + ~HALBackend(); + + /** + * Perform HAL initialization. + * + * @return true if succeded. If not, rely on some other backend + */ + bool InitHal(); + + /** + * List all devices and append them to the media device list (called only once, at startup). + * + * @return true if succeded, false otherwise + */ + bool ListDevices(); + + TQStringList mountoptions(const TQString &id); + + bool setMountoptions(const TQString &id, const TQStringList &options); + + TQString mount(const TQString &id); + TQString mount(const Medium *medium); + TQString unmount(const TQString &id); + TQString decrypt(const TQString &id, const TQString &password); + TQString undecrypt(const TQString &id); + +private: + /** + * Append a device in the media list. This function will check if the device + * is worth listing. + * + * @param udi Universal Device Id + * @param allowNotification Indicates if this event will be notified to the user + */ + void AddDevice(const char* udi, bool allowNotification=true); + + /** + * Remove a device from the device list + * + * @param udi Universal Device Id + */ + void RemoveDevice(const char* udi); + + /** + * A device has changed, update it + * + * @param udi Universal Device Id + */ + void ModifyDevice(const char *udi, const char* key); + + /** + * HAL informed that a special action has occured + * (e.g. device unplugged without unmounting) + * + * @param udi Universal Device Id + */ + void DeviceCondition(const char *udi, const char *condition); + + /** + * Integrate the DBus connection within qt main loop + */ + void MainLoopIntegration(DBusConnection *dbusConnection); + +/* Set media properties */ +private: + /** + * Reset properties for the given medium + */ + void ResetProperties(const char* MediumUdi, bool allowNotification=false); + + /** + * Find the medium that is concerned with device udi + */ + const char* findMediumUdiFromUdi(const char* udi); + + void setVolumeProperties(Medium* medium); + bool setFloppyProperties(Medium* medium); + void setFloppyMountState( Medium* medium ); + bool setFstabProperties(Medium* medium); + void setCameraProperties(Medium* medium); + TQString generateName(const TQString &devNode); + static TQString isInFstab(const Medium *medium); + static TQString listUsingProcesses(const Medium *medium); + static TQString killUsingProcesses(const Medium *medium); + +private slots: + void slotResult(TDEIO::Job *job); + +/* Hal call-backs -- from gvm*/ +public: + /** Invoked when a device is added to the Global Device List. + * + * @param ctx LibHal context + * @param udi Universal Device Id + */ + static void hal_device_added(LibHalContext *ctx, const char *udi); + + /** Invoked when a device is removed from the Global Device List. + * + * @param ctx LibHal context + * @param udi Universal Device Id + */ + static void hal_device_removed(LibHalContext *ctx, const char *udi); + + /** Invoked when a property of a device in the Global Device List is + * changed, and we have we have subscribed to changes for that device. + * + * @param ctx LibHal context + * @param udi Univerisal Device Id + * @param key Key of property + */ + static void hal_device_property_modified(LibHalContext *ctx, const char *udi, const char *key, + dbus_bool_t is_removed, dbus_bool_t is_added); + + /** Type for callback when a non-continuos condition occurs on a device + * + * @param udi Univerisal Device Id + * @param condition_name Name of the condition + * @param message D-BUS message with variable parameters depending on condition + */ + static void hal_device_condition(LibHalContext *ctx, const char *udi, + const char *condition_name, + const char* message + ); + + TQStringList getHALmountoptions(TQString udi); +/* HAL and DBus structures */ +private: + /** + * The HAL context connecting the whole application to the HAL + */ + LibHalContext* m_halContext; + + /** + * libhal-storage HAL policy, e.g. for icon names + */ + LibHalStoragePolicy* m_halStoragePolicy; + + /** + * The DBus-Qt bindings connection for mainloop integration + */ + DBusQt::Connection* m_dBusQtConnection; + + /** + * Object for the kded module + */ + TQObject* m_parent; + + DBusConnection *dbus_connection; + + /** + * Data structure for fstab mount/unmount jobs + */ + struct mount_job_data { + // [in] Medium, which is being mounted/unmounted by the job + const Medium* medium; + // [in,out] Should be set to true when the job completes + bool completed; + // [out] TDEIO::Error if an error occured during operation. Otherwise, 0 + int error; + // [out] Error message to be displayed to the user + TQString errorMessage; + }; + + TQMap<TDEIO::Job *, struct mount_job_data*> mount_jobs; +}; + +#endif /* _HALBACKEND_H_ */ diff --git a/tdeioslave/media/mediamanager/linuxcdpolling.cpp b/tdeioslave/media/mediamanager/linuxcdpolling.cpp new file mode 100644 index 000000000..0fcda8d0f --- /dev/null +++ b/tdeioslave/media/mediamanager/linuxcdpolling.cpp @@ -0,0 +1,585 @@ +/* This file is part of the KDE Project + Copyright (c) 2003 Gav Wood <gav kde org> + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/* Some code of this file comes from kdeautorun */ + +#include "linuxcdpolling.h" + +#include <tqthread.h> +#include <tqmutex.h> +#include <tqfile.h> + +#include <kdebug.h> + +#include "fstabbackend.h" + +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> + +// Never ever include directly a kernel header! +// #include <linux/cdrom.h> +// Instead we redefine the necessary (copied from the header) + +/* This struct is used by the CDROMREADTOCHDR ioctl */ +struct cdrom_tochdr +{ + unsigned char cdth_trk0; /* start track */ + unsigned char cdth_trk1; /* end track */ +}; + +#define CDROMREADTOCHDR 0x5305 /* Read TOC header + (struct cdrom_tochdr) */ +#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ +#define CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */ + +/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ +#define CDS_NO_INFO 0 /* if not implemented */ +#define CDS_NO_DISC 1 +#define CDS_TRAY_OPEN 2 +#define CDS_DRIVE_NOT_READY 3 +#define CDS_DISC_OK 4 + +/* return values for the CDROM_DISC_STATUS ioctl */ +/* can also return CDS_NO_[INFO|DISC], from above */ +#define CDS_AUDIO 100 +#define CDS_DATA_1 101 +#define CDS_DATA_2 102 +#define CDS_XA_2_1 103 +#define CDS_XA_2_2 104 +#define CDS_MIXED 105 + +#define CDSL_CURRENT ((int) (~0U>>1)) + +// ------- + + + +DiscType::DiscType(Type type) + : m_type(type) +{ +} + +bool DiscType::isKnownDisc() const +{ + return m_type != None + && m_type != Unknown + && m_type != UnknownType + && m_type != Broken; +} + +bool DiscType::isDisc() const +{ + return m_type != None + && m_type != Unknown + && m_type != Broken; +} + +bool DiscType::isNotDisc() const +{ + return m_type == None; +} + +bool DiscType::isData() const +{ + return m_type == Data; +} + +DiscType::operator int() const +{ + return (int)m_type; +} + + +class PollingThread : public TQThread +{ +public: + PollingThread(const TQCString &devNode) : m_dev(devNode) + { + kdDebug(1219) << "PollingThread::PollingThread(" + << devNode << ")" << endl; + m_stop = false; + m_currentType = DiscType::None; + m_lastPollType = DiscType::None; + } + + + void stop() + { + TQMutexLocker locker(&m_mutex); + m_stop = true; + } + + bool hasChanged() + { + TQMutexLocker locker(&m_mutex); + + return m_currentType!=m_lastPollType; + } + + DiscType type() + { + TQMutexLocker locker(&m_mutex); + m_currentType = m_lastPollType; + return m_currentType; + } + +protected: + virtual void run() + { + kdDebug(1219) << "PollingThread(" << m_dev << ") start" << endl; + while (!m_stop && m_lastPollType!=DiscType::Broken) + { + m_mutex.lock(); + DiscType type = m_lastPollType; + m_mutex.unlock(); + + type = LinuxCDPolling::identifyDiscType(m_dev, type); + + m_mutex.lock(); + m_lastPollType = type; + m_mutex.unlock(); + + msleep(500); + } + kdDebug(1219) << "PollingThread(" << m_dev << ") stop" << endl; + } + +private: + TQMutex m_mutex; + bool m_stop; + const TQCString m_dev; + DiscType m_currentType; + DiscType m_lastPollType; +}; + + +LinuxCDPolling::LinuxCDPolling(MediaList &list) + : TQObject(), BackendBase(list) +{ + connect(&m_mediaList, TQT_SIGNAL(mediumAdded(const TQString &, + const TQString &, bool)), + this, TQT_SLOT(slotMediumAdded(const TQString &)) ); + + connect(&m_mediaList, TQT_SIGNAL(mediumRemoved(const TQString &, + const TQString &, bool)), + this, TQT_SLOT(slotMediumRemoved(const TQString &)) ); + + connect(&m_mediaList, TQT_SIGNAL(mediumStateChanged(const TQString &, + const TQString &, bool, bool)), + this, TQT_SLOT(slotMediumStateChanged(const TQString &)) ); + + connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotTimeout())); +} + +LinuxCDPolling::~LinuxCDPolling() +{ + TQMap<TQString, PollingThread*>::iterator it = m_threads.begin(); + TQMap<TQString, PollingThread*>::iterator end = m_threads.end(); + + for(; it!=end; ++it) + { + PollingThread *thread = it.data(); + thread->stop(); + thread->wait(); + delete thread; + } +} + +void LinuxCDPolling::slotMediumAdded(const TQString &id) +{ + kdDebug(1219) << "LinuxCDPolling::slotMediumAdded(" << id << ")" << endl; + + if (m_threads.contains(id)) return; + + const Medium *medium = m_mediaList.findById(id); + + TQString mime = medium->mimeType(); + kdDebug(1219) << "mime == " << mime << endl; + + if (mime.find("dvd")==-1 && mime.find("cd")==-1) return; + + if (!medium->isMounted()) + { + m_excludeNotification.append( id ); + + TQCString dev = TQFile::encodeName( medium->deviceNode() ).data(); + PollingThread *thread = new PollingThread(dev); + m_threads[id] = thread; + thread->start(); + m_timer.start(500); + } +} + +void LinuxCDPolling::slotMediumRemoved(const TQString &id) +{ + kdDebug(1219) << "LinuxCDPolling::slotMediumRemoved(" << id << ")" << endl; + + if (!m_threads.contains(id)) return; + + PollingThread *thread = m_threads[id]; + m_threads.remove(id); + thread->stop(); + thread->wait(); + delete thread; + + m_excludeNotification.remove(id); +} + +void LinuxCDPolling::slotMediumStateChanged(const TQString &id) +{ + kdDebug(1219) << "LinuxCDPolling::slotMediumStateChanged(" + << id << ")" << endl; + + const Medium *medium = m_mediaList.findById(id); + + TQString mime = medium->mimeType(); + kdDebug(1219) << "mime == " << mime << endl; + + if (mime.find("dvd")==-1 && mime.find("cd")==-1) return; + + if (!m_threads.contains(id) && !medium->isMounted()) + { + // It is just a mount state change, no need to notify + m_excludeNotification.append( id ); + + TQCString dev = TQFile::encodeName( medium->deviceNode() ).data(); + PollingThread *thread = new PollingThread(dev); + m_threads[id] = thread; + thread->start(); + m_timer.start(500); + } + else if (m_threads.contains(id) && medium->isMounted()) + { + PollingThread *thread = m_threads[id]; + m_threads.remove(id); + thread->stop(); + thread->wait(); + delete thread; + } +} + +void LinuxCDPolling::slotTimeout() +{ + //kdDebug(1219) << "LinuxCDPolling::slotTimeout()" << endl; + + if (m_threads.isEmpty()) + { + m_timer.stop(); + return; + } + + TQMap<TQString, PollingThread*>::iterator it = m_threads.begin(); + TQMap<TQString, PollingThread*>::iterator end = m_threads.end(); + + for(; it!=end; ++it) + { + TQString id = it.key(); + PollingThread *thread = it.data(); + + if (thread->hasChanged()) + { + DiscType type = thread->type(); + const Medium *medium = m_mediaList.findById(id); + applyType(type, medium); + } + } +} + +static TQString baseType(const Medium *medium) +{ + kdDebug(1219) << "baseType(" << medium->id() << ")" << endl; + + TQString devNode = medium->deviceNode(); + TQString mountPoint = medium->mountPoint(); + TQString fsType = medium->fsType(); + bool mounted = medium->isMounted(); + + TQString mimeType, iconName, label; + + FstabBackend::guess(devNode, mountPoint, fsType, mounted, + mimeType, iconName, label); + + if (devNode.find("dvd")!=-1) + { + kdDebug(1219) << "=> dvd" << endl; + return "dvd"; + } + else + { + kdDebug(1219) << "=> cd" << endl; + return "cd"; + } +} + +static void restoreEmptyState(MediaList &list, const Medium *medium, + bool allowNotification) +{ + kdDebug(1219) << "restoreEmptyState(" << medium->id() << ")" << endl; + + TQString id = medium->id(); + TQString devNode = medium->deviceNode(); + TQString mountPoint = medium->mountPoint(); + TQString fsType = medium->fsType(); + bool mounted = medium->isMounted(); + + TQString mimeType, iconName, label; + + FstabBackend::guess(devNode, mountPoint, fsType, mounted, + mimeType, iconName, label); + + list.changeMediumState(id, devNode, mountPoint, fsType, mounted, + allowNotification, mimeType, iconName, label); +} + + +void LinuxCDPolling::applyType(DiscType type, const Medium *medium) +{ + kdDebug(1219) << "LinuxCDPolling::applyType(" << type << ", " + << medium->id() << ")" << endl; + + TQString id = medium->id(); + TQString dev = medium->deviceNode(); + + bool notify = !m_excludeNotification.contains(id); + m_excludeNotification.remove(id); + + switch (type) + { + case DiscType::Data: + restoreEmptyState(m_mediaList, medium, notify); + break; + case DiscType::Audio: + case DiscType::Mixed: + m_mediaList.changeMediumState(id, "audiocd:/?device="+dev, + notify, "media/audiocd"); + break; + case DiscType::VCD: + m_mediaList.changeMediumState(id, false, notify, "media/vcd"); + break; + case DiscType::SVCD: + m_mediaList.changeMediumState(id, false, notify, "media/svcd"); + break; + case DiscType::DVD: + m_mediaList.changeMediumState(id, false, notify, "media/dvdvideo"); + break; + case DiscType::Blank: + if (baseType(medium)=="dvd") + { + m_mediaList.changeMediumState(id, false, + notify, "media/blankdvd"); + } + else + { + m_mediaList.changeMediumState(id, false, + notify, "media/blankcd"); + } + break; + case DiscType::None: + case DiscType::Unknown: + case DiscType::UnknownType: + restoreEmptyState(m_mediaList, medium, false); + break; + } +} + +DiscType LinuxCDPolling::identifyDiscType(const TQCString &devNode, + const DiscType ¤t) +{ + //kdDebug(1219) << "LinuxCDPolling::identifyDiscType(" + // << devNode << ")" << endl; + + int fd; + struct cdrom_tochdr th; + + // open the device + fd = open(devNode, O_RDONLY | O_NONBLOCK); + if (fd < 0) return DiscType::Broken; + + switch (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) + { + case CDS_DISC_OK: + { + if (current.isDisc()) + { + close(fd); + return current; + } + + // see if we can read the disc's table of contents (TOC). + if (ioctl(fd, CDROMREADTOCHDR, &th)) + { + close(fd); + return DiscType::Blank; + } + + // read disc status info + int status = ioctl(fd, CDROM_DISC_STATUS, CDSL_CURRENT); + + // release the device + close(fd); + + switch (status) + { + case CDS_AUDIO: + return DiscType::Audio; + case CDS_DATA_1: + case CDS_DATA_2: + if (hasDirectory(devNode, "video_ts")) + { + return DiscType::DVD; + } + else if (hasDirectory(devNode, "vcd")) + { + return DiscType::VCD; + } + else if (hasDirectory(devNode, "svcd")) + { + return DiscType::SVCD; + } + else + { + return DiscType::Data; + } + case CDS_MIXED: + return DiscType::Mixed; + default: + return DiscType::UnknownType; + } + } + case CDS_NO_INFO: + close(fd); + return DiscType::Unknown; + default: + close(fd); + return DiscType::None; + } +} + +bool LinuxCDPolling::hasDirectory(const TQCString &devNode, const TQCString &dir) +{ + bool ret = false; // return value + int fd = 0; // file descriptor for drive + unsigned short bs; // the discs block size + unsigned short ts; // the path table size + unsigned int tl; // the path table location (in blocks) + unsigned char len_di = 0; // length of the directory name in current path table entry + unsigned int parent = 0; // the number of the parent directory's path table entry + char dirname[256]; // filename for the current path table entry + int pos = 0; // our position into the path table + int curr_record = 1; // the path table record we're on + TQCString fixed_directory = dir.upper(); // the uppercase version of the "directory" parameter + + // open the drive + fd = open(devNode, O_RDONLY | O_NONBLOCK); + if (fd == -1) return false; + + // read the block size + lseek(fd, 0x8080, SEEK_CUR); + if (read(fd, &bs, 2) != 2) + { + close(fd); + return false; + } + if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN) + bs = ((bs << 8) & 0xFF00) | ((bs >> 8) & 0xFF); + + // read in size of path table + lseek(fd, 2, SEEK_CUR); + if (read(fd, &ts, 2) != 2) + { + close(fd); + return false; + } + if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN) + ts = ((ts << 8) & 0xFF00) | ((ts >> 8) & 0xFF); + + // read in which block path table is in + lseek(fd, 6, SEEK_CUR); + if (read(fd, &tl, 4) != 4) + { + close(fd); + return false; + } + if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN) + tl = ((tl << 24) & 0xFF000000) | ((tl << 8) & 0xFF0000) | + ((tl >> 8) & 0xFF00) | ((tl >> 24) & 0xFF); + + // 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) + { + ret = false; + 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) + { + ret = false; + break; + } + if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN) + parent = ((parent << 8) & 0xFF00) | ((parent >> 8) & 0xFF); + + // read the name + if (read(fd, dirname, len_di) != len_di) + { + ret = false; + break; + } + dirname[len_di] = 0; + qstrcpy(dirname, TQCString(dirname).upper()); + + // if we found a folder that has the root as a parent, and the directory name matches + // then return success + if ((parent == 1) && (dirname == fixed_directory)) + { + ret = true; + 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 ret; +} + + +#include "linuxcdpolling.moc" diff --git a/tdeioslave/media/mediamanager/linuxcdpolling.h b/tdeioslave/media/mediamanager/linuxcdpolling.h new file mode 100644 index 000000000..3dec7e3ee --- /dev/null +++ b/tdeioslave/media/mediamanager/linuxcdpolling.h @@ -0,0 +1,86 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _LINUXCDPOLLING_H_ +#define _LINUXCDPOLLING_H_ + +#include "backendbase.h" + +#include <tqobject.h> +#include <tqcstring.h> +#include <tqmap.h> +#include <tqtimer.h> + +class DiscType +{ +public: + enum Type { None, Unknown, Audio, Data, DVD, Mixed, + Blank, VCD, SVCD, UnknownType, Broken }; + + DiscType(Type type = Unknown); + + bool isKnownDisc() const; + bool isDisc() const; + bool isNotDisc() const; + bool isData() const; + + operator int() const; + +private: + Type m_type; +}; + +class PollingThread; + +class LinuxCDPolling : public TQObject, public BackendBase +{ +Q_OBJECT + +public: + + LinuxCDPolling(MediaList &list); + virtual ~LinuxCDPolling(); + + /** + * Find the disc type of the medium inserted in a drive + * (considered to be a cdrom or dvdrom) + * + * @param devNode the path to the device to test + * @param current the current known state of the drive + * @return the disc type + */ + static DiscType identifyDiscType(const TQCString &devNode, + const DiscType ¤t = DiscType::Unknown); + +private slots: + void slotMediumAdded(const TQString &id); + void slotMediumRemoved(const TQString &id); + void slotMediumStateChanged(const TQString &id); + void slotTimeout(); + +private: + void applyType(DiscType type, const Medium *medium); + + static bool hasDirectory(const TQCString &devNode, const TQCString &dir); + + TQMap<TQString, PollingThread*> m_threads; + TQStringList m_excludeNotification; + TQTimer m_timer; +}; + +#endif diff --git a/tdeioslave/media/mediamanager/mediadirnotify.cpp b/tdeioslave/media/mediamanager/mediadirnotify.cpp new file mode 100644 index 000000000..9e6658153 --- /dev/null +++ b/tdeioslave/media/mediamanager/mediadirnotify.cpp @@ -0,0 +1,124 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "mediadirnotify.h" + +#include <kdebug.h> + +#include <kdirnotify_stub.h> + +#include "medium.h" + +MediaDirNotify::MediaDirNotify(const MediaList &list) + : m_mediaList(list) +{ + +} + +KURL::List MediaDirNotify::toMediaURL(const KURL &url) +{ + kdDebug(1219) << "MediaDirNotify::toMediaURL(" << url << ")" << endl; + + KURL::List result; + + const TQPtrList<Medium> list = m_mediaList.list(); + + TQPtrList<Medium>::const_iterator it = list.begin(); + TQPtrList<Medium>::const_iterator end = list.end(); + + for (; it!=end; ++it) + { + const Medium *m = *it; + KURL base = m->prettyBaseURL(); + + if ( base.isParentOf(url) ) + { + TQString path = KURL::relativePath(base.path(), + url.path()); + + KURL new_url("media:/"+m->name()+"/"+path ); + new_url.cleanPath(); + + result.append(new_url); + } + } + + kdDebug(1219) << result << endl; + return result; +} + +KURL::List MediaDirNotify::toMediaURLList(const KURL::List &list) +{ + KURL::List new_list; + + KURL::List::const_iterator it = list.begin(); + KURL::List::const_iterator end = list.end(); + + for (; it!=end; ++it) + { + KURL::List urls = toMediaURL(*it); + + if (!urls.isEmpty()) + { + new_list += urls; + } + } + + return new_list; +} + +ASYNC MediaDirNotify::FilesAdded(const KURL &directory) +{ + KURL::List new_urls = toMediaURL(directory); + + if (!new_urls.isEmpty()) + { + KDirNotify_stub notifier("*", "*"); + + KURL::List::const_iterator it = new_urls.begin(); + KURL::List::const_iterator end = new_urls.end(); + + for (; it!=end; ++it) + { + notifier.FilesAdded(*it); + } + } +} + +ASYNC MediaDirNotify::FilesRemoved(const KURL::List &fileList) +{ + KURL::List new_list = toMediaURLList(fileList); + + if (!new_list.isEmpty()) + { + KDirNotify_stub notifier("*", "*"); + notifier.FilesRemoved( new_list ); + } +} + +ASYNC MediaDirNotify::FilesChanged(const KURL::List &fileList) +{ + KURL::List new_list = toMediaURLList(fileList); + + if (!new_list.isEmpty()) + { + KDirNotify_stub notifier("*", "*"); + notifier.FilesChanged( new_list ); + } +} + diff --git a/tdeioslave/media/mediamanager/mediadirnotify.h b/tdeioslave/media/mediamanager/mediadirnotify.h new file mode 100644 index 000000000..beb1b8849 --- /dev/null +++ b/tdeioslave/media/mediamanager/mediadirnotify.h @@ -0,0 +1,47 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _MEDIADIRNOTIFY_H_ +#define _MEDIADIRNOTIFY_H_ + +#include <kurl.h> +#include <kdirnotify.h> + +#include "medialist.h" + + +class MediaDirNotify : public KDirNotify +{ +K_DCOP + +public: + MediaDirNotify(const MediaList &list); + +k_dcop: + virtual ASYNC FilesAdded (const KURL &directory); + virtual ASYNC FilesRemoved (const KURL::List &fileList); + virtual ASYNC FilesChanged (const KURL::List &fileList); + +private: + KURL::List toMediaURL(const KURL &url); + KURL::List toMediaURLList(const KURL::List &list); + + const MediaList &m_mediaList; +}; + +#endif diff --git a/tdeioslave/media/mediamanager/medialist.cpp b/tdeioslave/media/mediamanager/medialist.cpp new file mode 100644 index 000000000..6ac7dc341 --- /dev/null +++ b/tdeioslave/media/mediamanager/medialist.cpp @@ -0,0 +1,303 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "medialist.h" + +#include <kdebug.h> + +MediaList::MediaList() +{ + kdDebug(1219) << "MediaList::MediaList()" << endl; + + m_media.setAutoDelete(true); +} + +const TQPtrList<Medium> MediaList::list() const +{ + kdDebug(1219) << "MediaList::list()" << endl; + + return m_media; +} + +const Medium *MediaList::findById(const TQString &id) const +{ + kdDebug(1219) << "MediaList::findById(" << id << ")" << endl; + + if ( !m_idMap.contains(id) ) return 0L; + + return m_idMap[id]; +} + +const Medium *MediaList::findByName(const TQString &name) const +{ + kdDebug(1219) << "MediaList::findByName(" << name << ")" << endl; + + if ( !m_nameMap.contains(name) ) return 0L; + + return m_nameMap[name]; +} + +const Medium *MediaList::findByClearUdi(const TQString &name) +{ + kdDebug(1219) << "MediaList::findByClearUdi(" << name << ")" << endl; + + Medium *medium; + for (medium = m_media.first(); medium; medium = m_media.next()) { + if (medium->clearDeviceUdi() == name) return medium; + } + + return 0L; +} + + +TQString MediaList::addMedium(Medium *medium, bool allowNotification) +{ + kdDebug(1219) << "MediaList::addMedium(@" << medium->id() << ")" << endl; + + TQString id = medium->id(); + if ( m_idMap.contains(id) ) return TQString::null; + + m_media.append( medium ); + m_idMap[id] = medium; + + TQString name = medium->name(); + if ( !m_nameMap.contains(name) ) + { + m_nameMap[name] = medium; + + kdDebug(1219) << "MediaList emits mediumAdded(" << id << ", " + << name << ")" << endl; + emit mediumAdded(id, name, allowNotification); + + return name; + } + + TQString base_name = name+"_"; + int i = 1; + + while ( m_nameMap.contains(base_name+TQString::number(i)) ) + { + i++; + } + + name = base_name+TQString::number(i); + medium->setName(name); + m_nameMap[name] = medium; + + kdDebug(1219) << "MediaList emits mediumAdded(" << id << ", " + << name << ")" << endl; + emit mediumAdded(id, name, allowNotification); + return name; +} + +bool MediaList::removeMedium(const TQString &id, bool allowNotification) +{ + kdDebug(1219) << "MediaList::removeMedium(" << id << ")" << endl; + + if ( !m_idMap.contains(id) ) return false; + + Medium *medium = m_idMap[id]; + TQString name = medium->name(); + + m_idMap.remove(id); + m_nameMap.remove( medium->name() ); + m_media.remove( medium ); + + emit mediumRemoved(id, name, allowNotification); + return true; +} + +bool MediaList::changeMediumState(const Medium &medium, bool allowNotification) +{ + kdDebug(1219) << "MediaList::changeMediumState(const Medium &)" << endl; + + if ( !m_idMap.contains(medium.id()) ) return false; + + Medium *m = m_idMap[medium.id()]; + + if ( medium.isMountable() ) + { + TQString device_node = medium.deviceNode(); + TQString clear_device_udi = medium.clearDeviceUdi(); + TQString mount_point = medium.mountPoint(); + TQString fs_type = medium.fsType(); + bool mounted = medium.isMounted(); + + m->mountableState( device_node, clear_device_udi, mount_point, + fs_type, mounted ); + } + else + { + m->unmountableState( medium.baseURL() ); + } + + + if (!medium.mimeType().isEmpty()) + { + m->setMimeType( medium.mimeType() ); + } + + if (!medium.iconName().isEmpty()) + { + m->setIconName( medium.iconName() ); + } + + if (!medium.label().isEmpty()) + { + m->setLabel( medium.label() ); + } + + m->setHidden(medium.hidden()); + + emit mediumStateChanged(m->id(), m->name(), !m->needMounting(), allowNotification); + return true; +} + +bool MediaList::changeMediumState(const TQString &id, + const TQString &baseURL, + bool allowNotification, + const TQString &mimeType, + const TQString &iconName, + const TQString &label) +{ + kdDebug(1219) << "MediaList::changeMediumState(" << id << ", " + << baseURL << ", " << mimeType << ", " << iconName << ")" + << endl; + + if ( !m_idMap.contains(id) ) return false; + + Medium *medium = m_idMap[id]; + + medium->unmountableState( baseURL ); + + if (!mimeType.isEmpty()) + { + medium->setMimeType( mimeType ); + } + + if (!iconName.isEmpty()) + { + medium->setIconName( iconName ); + } + + if (!label.isEmpty()) + { + medium->setLabel( label ); + } + + emit mediumStateChanged(id, medium->name(), + !medium->needMounting(), + allowNotification); + return true; +} + +bool MediaList::changeMediumState(const TQString &id, + const TQString &deviceNode, + const TQString &mountPoint, + const TQString &fsType, bool mounted, + bool allowNotification, + const TQString &mimeType, + const TQString &iconName, + const TQString &label) +{ + kdDebug(1219) << "MediaList::changeMediumState(" << id << ", " + << deviceNode << ", " << mountPoint << ", " << fsType << ", " + << mounted << ", " << mimeType << ", " << iconName << ")" + << endl; + + if ( !m_idMap.contains(id) ) return false; + + Medium *medium = m_idMap[id]; + + medium->mountableState( deviceNode, mountPoint, fsType, mounted ); + + if (!mimeType.isEmpty()) + { + medium->setMimeType( mimeType ); + } + + if (!iconName.isEmpty()) + { + medium->setIconName( iconName ); + } + + if (!label.isEmpty()) + { + medium->setLabel( label ); + } + + emit mediumStateChanged(id, medium->name(), + !medium->needMounting(), + allowNotification); + return true; +} + +bool MediaList::changeMediumState(const TQString &id, bool mounted, + bool allowNotification, + const TQString &mimeType, + const TQString &iconName, + const TQString &label) +{ + kdDebug(1219) << "MediaList::changeMediumState(" << id << ", " + << mounted << ", " << mimeType << ", " << iconName << ")" + << endl; + + if ( !m_idMap.contains(id) ) return false; + + Medium *medium = m_idMap[id]; + + if ( !medium->mountableState( mounted ) ) return false; + + if (!mimeType.isEmpty()) + { + medium->setMimeType( mimeType ); + } + + if (!iconName.isEmpty()) + { + medium->setIconName( iconName ); + } + + if (!label.isEmpty()) + { + medium->setLabel( label ); + } + + emit mediumStateChanged(id, medium->name(), + !medium->needMounting(), + allowNotification); + return true; +} + +bool MediaList::setUserLabel(const TQString &name, const TQString &label) +{ + kdDebug(1219) << "MediaList::setUserLabel(" << name << ", " + << label << ")" << endl; + + if ( !m_nameMap.contains(name) ) return false; + + Medium *medium = m_nameMap[name]; + medium->setUserLabel(label); + + emit mediumStateChanged(medium->id(), name, + !medium->needMounting(), + false); + return true; +} + +#include "medialist.moc" diff --git a/tdeioslave/media/mediamanager/medialist.h b/tdeioslave/media/mediamanager/medialist.h new file mode 100644 index 000000000..59ddb6bd2 --- /dev/null +++ b/tdeioslave/media/mediamanager/medialist.h @@ -0,0 +1,80 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _MEDIALIST_H_ +#define _MEDIALIST_H_ + +#include <tqobject.h> + +#include "medium.h" + +class MediaList : public QObject +{ +Q_OBJECT + +public: + MediaList(); + + // FIXME: should be <const Medium> or something similar... + const TQPtrList<Medium> list() const; + const Medium *findById(const TQString &id) const; + const Medium *findByName(const TQString &name) const; + const Medium *findByClearUdi(const TQString &name); + +public: + TQString addMedium(Medium *medium, bool allowNotification = true); + bool removeMedium(const TQString &id, bool allowNotification = true); + + bool changeMediumState(const Medium &medium, bool allowNotification); + bool changeMediumState(const TQString &id, + const TQString &baseURL, + bool allowNotification = true, + const TQString &mimeType = TQString::null, + const TQString &iconName = TQString::null, + const TQString &label = TQString::null); + bool changeMediumState(const TQString &id, + const TQString &deviceNode, + const TQString &mountPoint, + const TQString &fsType, bool mounted, + bool allowNotification = true, + const TQString &mimeType = TQString::null, + const TQString &iconName = TQString::null, + const TQString &label = TQString::null); + bool changeMediumState(const TQString &id, bool mounted, + bool allowNotification = true, + const TQString &mimeType = TQString::null, + const TQString &iconName = TQString::null, + const TQString &label = TQString::null); + + bool setUserLabel(const TQString &name, const TQString &label); + +signals: + void mediumAdded(const TQString &id, const TQString &name, + bool allowNotification); + void mediumRemoved(const TQString &id, const TQString &name, + bool allowNotification); + void mediumStateChanged(const TQString &id, const TQString &name, + bool mounted, bool allowNotification); + +private: + TQPtrList<Medium> m_media; + TQMap<TQString,Medium*> m_nameMap; + TQMap<TQString,Medium*> m_idMap; +}; + +#endif diff --git a/tdeioslave/media/mediamanager/mediamanager.cpp b/tdeioslave/media/mediamanager/mediamanager.cpp new file mode 100644 index 000000000..db2c12a71 --- /dev/null +++ b/tdeioslave/media/mediamanager/mediamanager.cpp @@ -0,0 +1,423 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "mediamanager.h" + +#include <config.h> +#include <tqtimer.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> + +#include <kdirnotify_stub.h> +#include <kstandarddirs.h> + +#include "mediamanagersettings.h" + +#include "fstabbackend.h" + +#ifdef COMPILE_TDEHARDWAREBACKEND +#include "tdehardwarebackend.h" +#endif // COMPILE_TDEHARDWAREBACKEND + +#ifdef COMPILE_HALBACKEND +#include "halbackend.h" +#endif //COMPILE_HALBACKEND + +#ifdef COMPILE_LINUXCDPOLLING +#include "linuxcdpolling.h" +#endif //COMPILE_LINUXCDPOLLING + + +MediaManager::MediaManager(const TQCString &obj) + : KDEDModule(obj), m_dirNotify(m_mediaList) +{ + connect( &m_mediaList, TQT_SIGNAL(mediumAdded(const TQString&, const TQString&, bool)), + TQT_SLOT(slotMediumAdded(const TQString&, const TQString&, bool)) ); + connect( &m_mediaList, TQT_SIGNAL(mediumRemoved(const TQString&, const TQString&, bool)), + TQT_SLOT(slotMediumRemoved(const TQString&, const TQString&, bool)) ); + connect( &m_mediaList, + TQT_SIGNAL(mediumStateChanged(const TQString&, const TQString&, bool, bool)), + TQT_SLOT(slotMediumChanged(const TQString&, const TQString&, bool, bool)) ); + + TQTimer::singleShot( 10, this, TQT_SLOT( loadBackends() ) ); +} + +MediaManager::~MediaManager() +{ + while ( !m_backends.isEmpty() ) + { + BackendBase *b = m_backends.first(); + m_backends.remove( b ); + delete b; + } +} + +void MediaManager::loadBackends() +{ + m_mediaList.blockSignals(true); + + while ( !m_backends.isEmpty() ) + { + BackendBase *b = m_backends.first(); + m_backends.remove( b ); + delete b; + } + + mp_removableBackend = 0L; + m_halbackend = 0L; + m_tdebackend = 0L; + m_fstabbackend = 0L; + +#ifdef COMPILE_HALBACKEND + if ( MediaManagerSettings::self()->halBackendEnabled() ) + { + m_mediaList.blockSignals(false); + m_halbackend = new HALBackend(m_mediaList, this); + if (m_halbackend->InitHal()) + { + m_backends.append( m_halbackend ); + m_fstabbackend = new FstabBackend(m_mediaList, true); + m_backends.append( m_fstabbackend ); + // No need to load something else... + m_mediaList.blockSignals(false); + return; + } + else + { + delete m_halbackend; + m_halbackend = 0; + m_mediaList.blockSignals(true); + } + } +#endif // COMPILE_HALBACKEND + +#ifdef COMPILE_TDEHARDWAREBACKEND + if ( MediaManagerSettings::self()->tdeHardwareBackendEnabled() ) + { + m_mediaList.blockSignals(false); + m_tdebackend = new TDEBackend(m_mediaList, this); + m_backends.append( m_tdebackend ); + m_fstabbackend = new FstabBackend(m_mediaList, true); + m_backends.append( m_fstabbackend ); + // No need to load something else... + m_mediaList.blockSignals(false); + return; + } +#endif // COMPILE_TDEHARDWAREBACKEND + + mp_removableBackend = new RemovableBackend(m_mediaList); + m_backends.append( mp_removableBackend ); + +#ifdef COMPILE_LINUXCDPOLLING + if ( MediaManagerSettings::self()->cdPollingEnabled() ) + { + m_backends.append( new LinuxCDPolling(m_mediaList) ); + } +#endif //COMPILE_LINUXCDPOLLING + + m_fstabbackend = new FstabBackend(m_mediaList); + m_backends.append( m_fstabbackend ); + m_mediaList.blockSignals(false); +} + + +TQStringList MediaManager::fullList() +{ + TQPtrList<Medium> list = m_mediaList.list(); + + TQStringList result; + + TQPtrList<Medium>::const_iterator it = list.begin(); + TQPtrList<Medium>::const_iterator end = list.end(); + for (; it!=end; ++it) + { + result+= (*it)->properties(); + result+= Medium::SEPARATOR; + } + + return result; +} + +TQStringList MediaManager::properties(const TQString &name) +{ + const Medium *m = m_mediaList.findByName(name); + + if (!m) + { + KURL u(name); + kdDebug() << "Media::prop " << name << " " << u.isValid() << endl; + if (u.isValid()) + { + if (u.protocol() == "system") + { + TQString path = u.path(); + if (path.startsWith("/media/")) + path = path.mid(strlen("/media/")); + m = m_mediaList.findByName(path); + kdDebug() << "findByName " << path << m << endl; + } + else if (u.protocol() == "media") + { + m = m_mediaList.findByName(u.filename()); + kdDebug() << "findByName " << u.filename() << m << endl; + } + else if (u.protocol() == "file") + { + // look for the mount point + TQPtrList<Medium> list = m_mediaList.list(); + TQPtrList<Medium>::const_iterator it = list.begin(); + TQPtrList<Medium>::const_iterator end = list.end(); + TQString path; + + for (; it!=end; ++it) + { + path = KStandardDirs::realFilePath(u.path()); + kdDebug() << "comparing " << (*it)->mountPoint() << " " << path << " " << (*it)->deviceNode() << endl; + if ((*it)->mountPoint() == path || (*it)->deviceNode() == path) { + m = *it; + break; + } + } + } + } + } + + if (m) { + return m->properties(); + } + else { + return TQStringList(); + } +} + +TQStringList MediaManager::mountoptions(const TQString &name) +{ +#ifdef COMPILE_HALBACKEND + if (!m_halbackend) + return TQStringList(); + return m_halbackend->mountoptions(name); +#else // COMPILE_HALBACKEND + #ifdef COMPILE_TDEHARDWAREBACKEND + if (!m_tdebackend) + return TQStringList(); + return m_tdebackend->mountoptions(name); + #else // COMPILE_TDEHARDWAREBACKEND + return TQStringList(); + #endif // COMPILE_TDEHARDWAREBACKEND +#endif // COMPILE_HALBACKEND +} + +bool MediaManager::setMountoptions(const TQString &name, const TQStringList &options) +{ +#ifdef COMPILE_HALBACKEND + if (!m_halbackend) + return false; + return m_halbackend->setMountoptions(name, options); +#else // COMPILE_HALBACKEND + #ifdef COMPILE_TDEHARDWAREBACKEND + if (!m_tdebackend) + return false; + return m_tdebackend->setMountoptions(name, options); + #else // COMPILE_TDEHARDWAREBACKEND + return false; + #endif // COMPILE_TDEHARDWAREBACKEND +#endif // COMPILE_HALBACKEND +} + +TQString MediaManager::mount(const TQString &name) +{ +#ifdef COMPILE_HALBACKEND + if (!m_halbackend) + return i18n("Feature only available with HAL"); + return m_halbackend->mount(name); +#else // COMPILE_HALBACKEND + #ifdef COMPILE_TDEHARDWAREBACKEND + if (!m_tdebackend) + return i18n("Feature only available with the TDE hardware backend"); + return m_tdebackend->mount(name); + #else // COMPILE_TDEHARDWAREBACKEND + if ( !m_fstabbackend ) // lying :) + return i18n("Feature only available with HAL or TDE hardware backend"); + return m_fstabbackend->mount( name ); + #endif // COMPILE_TDEHARDWAREBACKEND +#endif // COMPILE_HALBACKEND +} + +TQString MediaManager::unmount(const TQString &name) +{ +#ifdef COMPILE_HALBACKEND + if (!m_halbackend) + return i18n("Feature only available with HAL"); + return m_halbackend->unmount(name); +#else // COMPILE_HALBACKEND + #ifdef COMPILE_TDEHARDWAREBACKEND + if (!m_tdebackend) + return i18n("Feature only available with HAL or TDE hardware backend"); + return m_tdebackend->unmount(name); + #else // COMPILE_TDEHARDWAREBACKEND + if ( !m_fstabbackend ) // lying :) + return i18n("Feature only available with HAL or TDE hardware backend"); + return m_fstabbackend->unmount( name ); + #endif // COMPILE_TDEHARDWAREBACKEND +#endif // COMPILE_HALBACKEND +} + +TQString MediaManager::decrypt(const TQString &name, const TQString &password) +{ +#ifdef COMPILE_HALBACKEND + if (!m_halbackend) + return i18n("Feature only available with HAL"); + return m_halbackend->decrypt(name, password); +#else // COMPILE_HALBACKEND +// #ifdef COMPILE_TDEHARDWAREBACKEND +// if (!m_tdebackend) +// return i18n("Feature only available with HAL or TDE hardware backend"); +// return m_tdebackend->decrypt(name, password); +// #else // COMPILE_TDEHARDWAREBACKEND + return i18n("Feature only available with HAL"); +// #endif // COMPILE_TDEHARDWAREBACKEND +#endif // COMPILE_HALBACKEND +} + +TQString MediaManager::undecrypt(const TQString &name) +{ +#ifdef COMPILE_HALBACKEND + if (!m_halbackend) + return i18n("Feature only available with HAL"); + return m_halbackend->undecrypt(name); +#else // COMPILE_HALBACKEND +// #ifdef COMPILE_TDEHARDWAREBACKEND +// if (!m_tdebackend) +// return i18n("Feature only available with HAL or TDE hardware backend"); +// return m_tdebackend->undecrypt(name); +// #else // COMPILE_TDEHARDWAREBACKEND + return i18n("Feature only available with HAL"); +// #endif // COMPILE_TDEHARDWAREBACKEND +#endif // COMPILE_HALBACKEND +} + +TQString MediaManager::nameForLabel(const TQString &label) +{ + const TQPtrList<Medium> media = m_mediaList.list(); + + TQPtrList<Medium>::const_iterator it = media.begin(); + TQPtrList<Medium>::const_iterator end = media.end(); + for (; it!=end; ++it) + { + const Medium *m = *it; + + if (m->prettyLabel()==label) + { + return m->name(); + } + } + + return TQString::null; +} + +ASYNC MediaManager::setUserLabel(const TQString &name, const TQString &label) +{ + m_mediaList.setUserLabel(name, label); +} + +ASYNC MediaManager::reloadBackends() +{ + MediaManagerSettings::self()->readConfig(); + loadBackends(); +} + +bool MediaManager::removablePlug(const TQString &devNode, const TQString &label) +{ + if (mp_removableBackend) + { + return mp_removableBackend->plug(devNode, label); + } + return false; +} + +bool MediaManager::removableUnplug(const TQString &devNode) +{ + if (mp_removableBackend) + { + return mp_removableBackend->unplug(devNode); + } + return false; +} + +bool MediaManager::removableCamera(const TQString &devNode) +{ + if (mp_removableBackend) + { + return mp_removableBackend->camera(devNode); + } + return false; +} + + +void MediaManager::slotMediumAdded(const TQString &/*id*/, const TQString &name, + bool allowNotification) +{ + kdDebug(1219) << "MediaManager::slotMediumAdded: " << name << endl; + + KDirNotify_stub notifier("*", "*"); + notifier.FilesAdded( KURL("media:/") ); + + emit mediumAdded(name, allowNotification); + emit mediumAdded(name); +} + +void MediaManager::slotMediumRemoved(const TQString &/*id*/, const TQString &name, + bool allowNotification) +{ + kdDebug(1219) << "MediaManager::slotMediumRemoved: " << name << endl; + + KDirNotify_stub notifier("*", "*"); + notifier.FilesRemoved( KURL("media:/"+name) ); + + emit mediumRemoved(name, allowNotification); + emit mediumRemoved(name); +} + +void MediaManager::slotMediumChanged(const TQString &/*id*/, const TQString &name, + bool mounted, bool allowNotification) +{ + kdDebug(1219) << "MediaManager::slotMediumChanged: " << name << endl; + + KDirNotify_stub notifier("*", "*"); + if (!mounted) + { + notifier.FilesRemoved( KURL("media:/"+name) ); + } + notifier.FilesChanged( KURL("media:/"+name) ); + + emit mediumChanged(name, allowNotification); + emit mediumChanged(name); +} + + +extern "C" { + KDE_EXPORT KDEDModule *create_mediamanager(const TQCString &obj) + { + TDEGlobal::locale()->insertCatalogue("kio_media"); + return new MediaManager(obj); + } +} + +#include "mediamanager.moc" diff --git a/tdeioslave/media/mediamanager/mediamanager.desktop b/tdeioslave/media/mediamanager/mediamanager.desktop new file mode 100644 index 000000000..48261e428 --- /dev/null +++ b/tdeioslave/media/mediamanager/mediamanager.desktop @@ -0,0 +1,141 @@ +[Desktop Entry] +Type=Service +Name=KDED Media Manager +Name[af]=KDED Media Bestuurder +Name[ar]=مسيير الوسائط KDED +Name[az]=KDED Mediya İdarəcisi +Name[be]=Кіраўнік носьбітаў KDED +Name[bg]=Управление на устройствата KDED +Name[bn]=কে.ডি.ই.ডি. মিডিয়া ম্যানেজার +Name[bs]=KDED upravitelj medijima +Name[ca]=Gestor de suports KDED +Name[cs]=KDED správce médií +Name[csb]=Menedżer zôpisownëch mediów dlô KDED +Name[da]=KDED Mediehåndtering +Name[de]=Medienverwaltung +Name[el]=Διαχειριστής μέσων KDED +Name[eo]=KDatumportila administrilo +Name[es]=Gestor de dispositivos KDED +Name[et]=KDED andmekandjate haldur +Name[eu]=KDED media kudeatzailea +Name[fa]=مدیر رسانه KDED +Name[fi]=KDED-tallennusmedianhallinta +Name[fr]=Gestionnaire de média KDED +Name[fy]=KDEDED-mediabehearder +Name[ga]=Bainisteoir Meán KDED +Name[gl]=Xestor de Meios de KDED +Name[he]=מנהל המדיה של KDED +Name[hi]=केडीईडी मीडिया प्रबंधक +Name[hr]=KDED upravitelj medija +Name[hu]=KDED médiakezelő +Name[is]=KDED miðilstjóri +Name[it]=Gestore dei supporti KDED +Name[ja]=KDED メディアマネージャ +Name[ka]=მატარებლების მმართველი KDED +Name[kk]=KDED ауыстырмалы тасушыларды басқару +Name[km]=កម្មវិធីគ្រប់គ្រងព័ត៌មាន KDED +Name[ko]=KDE 창 관리자 +Name[lv]=KDED Datu nesēju menedžeris +Name[mk]=Менаџер на носачи KDED +Name[ms]=Pengurus Media KDED +Name[nb]=KDED mediebehandler +Name[nds]=KDED-Medienpleeg +Name[ne]=KDED मिडिया प्रबन्धक +Name[nl]=KDED-Mediabeheerder +Name[nn]=KDED Mediehandsamar +Name[pa]=KDED ਮਾਧਿਅਮ ਮੈਨੇਜਰ +Name[pl]=Menedżer nośników danych dla KDED +Name[pt]=Gestor de Dispositivos KDED +Name[pt_BR]=Gerenciador de Mídia +Name[ro]=Manager multimedia KDED +Name[ru]=Управление подключаемыми устройствами +Name[rw]=Mugenga Igihuza KDED +Name[se]=KDED-mediagieđahalli +Name[sk]=KDED správca médií +Name[sl]=Upravitelj medijev KDED +Name[sr]=Менаџер медијума, KDED +Name[sr@Latn]=Menadžer medijuma, KDED +Name[sv]=KDED-mediahanterare +Name[ta]=KDED மீடியா மேலாளர் +Name[te]=కెడిఈడి మాధ్యమ అభికర్త +Name[th]=เครื่องมือจัดการสื่อบันทึก KDED +Name[tr]=KDED Ortam Yöneticisi +Name[tt]=KDED Media İdäräçe +Name[uk]=Менеджер носіїв інформації для KDED +Name[uz]=KDED saqlash uskunalarni boshqaruvchi +Name[uz@cyrillic]=KDED сақлаш ускуналарни бошқарувчи +Name[vi]=Trình quản lí Ổ lưu trữ KDED +Name[wa]=Manaedjeu di fitchîs KDED +Name[zh_CN]=KDED 介质管理器 +Name[zh_TW]=KDED 媒體管理程式 +Comment=Keep track of media activities and allow to (un)mount (media:/) +Comment[af]=Hou tred van media aktiwiteite en laat die (ont)koppel van 'media:/' toe +Comment[ar]=يتتبع نشاطات الوسائط و يسمح بتكيبها/إزالة تركيبها (media:/) +Comment[be]=Вядзе інфармацыю аб медыяносьбітах і дазваляе прымацоўваць/адмацоўваць іх (media:/) +Comment[bg]=Наблюдение на устройствата и разрешаване на монтиране/демонтиране на (media:/) +Comment[bn]=কোথায় কী মিডিয়া ব্যবহার করা হচ্ছে খেয়াল রাখুন এবং (আন)মাউন্ট করুন (media:/) +Comment[bs]=Prati aktivnosti montiranja uređaja za smještaj podataka (media:/) +Comment[ca]=Fa el seguiment de les activitats dels suports i permet muntar i desmuntar (media:/) +Comment[cs]=Udržuje přehled o připojených zařízeních +Comment[csb]=Dozérô zdarzeniów sparłączonëch z mediama pòdôwków ë zezwôlô je (òd)mòntowac (media:/) +Comment[da]=Hold styr på medieaktiviteter og tillad at (af)montere (media:/) +Comment[de]=Überwacht Medien-Aktivität und ermöglicht das Einbinden/Lösen von Einbindungen (media:/) +Comment[el]=Έλεγχος ενεργειών των μέσων και δυνατότητα (από)προσάρτησης (media:/) +Comment[eo]=Sekvu spurojn de datumportilaj aktivoj kaj permesu (de/sur)meti (media:/) +Comment[es]=Monitoriza las actividades de los recursos y permite (des)montarlos (media:/) +Comment[et]=Hoiab silma peal andmekandjate aktiivsusel ja võimaldab neid ühendada/lahutada (media:/) +Comment[eu]=Montatzeak begiztatzen ditu (media:/) eta desmontatzen uzten du +Comment[fa]=حفظ رد فعالیتهای رسانه و اجازۀ سوار(پیاده) کردن (media:/) +Comment[fi]=Pidä kirjaa tallennustapahtumista ja salli tallennusvälineen liittäminen/irrotus (devices:/) +Comment[fr]=Gardez une trace des montages et permettre le (dé)montage (media:/) +Comment[fy]=Hâld de media-aktiviteiten by en stien ta om media oan- en ôf te keppelje (media:/) +Comment[gl]=Seguemento das actividades dos meios e permite-lle (des)montar (media:/) +Comment[he]=מנטר אחר פעילויות מדיה, ומאפשר לחבר או לנתק התקנים (media:/) +Comment[hi]=मीडिया क्रियाओं की जानकारी रखे तथा (अन)माउन्ट करने दे (मीडिया:/) +Comment[hr]=Praćenje aktivnosti medija i omogućavanje pristupanja i napuštanja +Comment[hu]=Az adathordozók követése, csatlakoztatása és leválasztása (media:/) +Comment[is]=Fylgjast með breytingum á tækjum og bjóða upp á (af)tengingu (media:/) +Comment[it]=Tiene traccia delle attività dei supporti e permette di montarli o smontarli (device:/) +Comment[ja]=メディアの活動を追跡し、(media:/) をマウントしたりアンマウントします +Comment[ka]=თვალყურს ადევნებს მედიის აქტიურობას და საშუალებას აძლევს (დე)მონტირების გაკეთებას (media:/) +Comment[kk]=Тасушылардың белсендігін байқап тіркеуге не тіркеуден шығаруға мүмкіндік береді: (un)mount (media:/) +Comment[km]=តាមដានសកម្មភាពព័ត៌មាន និងអនុញ្ញាតឲ្យរៀបចំ (មិនរៀបចំ) (media:/) +Comment[lt]=Stebi laikmenose vykdomus veiksmus ir leidžia (iš)montuoti (media:/) +Comment[lv]=Seko datu nesēju aktivitātēm un ļauj montēt/nomontēt tos (media:/) +Comment[mk]=Води сметка за активностите на носачите и дозволува (од)монтирање (media:/) +Comment[ms]=Ikuti perkembangan aktiviti media dan benarkan untuk (nyah)lekap (media:/) +Comment[mt]=Żomm kont ta' attivitajiet ta' mmuntar u ippermetti (un)mount (media:/) +Comment[nb]=Holder styr på monteringsaktiviteter og lar deg (av)montere (media:/) +Comment[nds]=Blifft bi all Medienaktiviteten op'n Stand un verlöövt dat In- un Afhangen (media:/) +Comment[ne]=मिडिया क्रियाकलापको मार्ग राख्नुहोस् र (अन)माउन्ट (media:/) गर्न अनुमति दिनुहोस् +Comment[nl]=Houdt de media-activiteiten bij en staat u toe om media aan- en af te koppelen (media:/) +Comment[nn]=Held styr på medieaktivitetar og lèt deg montera og avmontera (media:/) +Comment[pa]=ਮਾਊਟ ਕਾਰਵਾਈਆਂ ਦੀ ਜਾਣਕਾਰੀ ਰੱਖੋ ਅਤੇ ਅਨ-ਮਾਊਟ ਕਰਨ ਦਿਓ (ਜੰਤਰ:/) +Comment[pl]=Śledzi zdarzenia związane z nośnikami danych i pozwala je (od)montować (media:/) +Comment[pt]=Manter o registo das actividades de dispositivos e permitir a (des)montagem (media:/) +Comment[pt_BR]=Monitora as atividades de mídias e permite a (des)montagem (media:/) +Comment[ro]=Urmărește activitățile multimedia și permite (de)montarea media:/ +Comment[ru]=Автоматическое подключение устройств (media:/) +Comment[rw]=Kugumana inzira y'ibikorwa by'ibitangazamakuru no kwemerera gushyiramo(gukuramo) (ibitangazamakuru:/) +Comment[se]=Gozit mii dáhpáhuvvá median ja diktá du gálgat ja čadnat daid (media:/) +Comment[sk]=Sledovanie pripojenia/odpojenia medií (media:/) +Comment[sl]=Nadzoruj dejanja medija in dovilo priklop/odklop (media:/) +Comment[sr]=Прати активност медијума и омогућава (де)монтирање (media:/) +Comment[sr@Latn]=Prati aktivnost medijuma i omogućava (de)montiranje (media:/) +Comment[sv]=Håll reda på mediaaktiviteter och tillåt (av)montering (media:/) +Comment[ta]=இடைக்காலத்திற்குரிய நடவடிக்கைகளின் வைத்திரு. (சாதனம்:/)த்தை ஏற்ற(இறக்க)கவும் அனுமதி +Comment[th]=จะคอยติดตามกิจกรรมของสื่อบันทึก และอนุญาตให้เมานท์หรือยกเลิกการเมานท์ (media:/) +Comment[tr]=Ortam işlemlerini takip et ve bağlanma işlemlerine izin ver(media:/) +Comment[tt]=Cıhazlarnıñ totaşuın/ayırıluın sizüçe närsä (media:/) +Comment[uk]=Спостерігає за змінами серед носіїв інформації та дозволяє (роз)монтування (media:/) +Comment[vi]=Theo dõi các hoạt động của ổ lưu trữ và cho phép lắp đặt hay gỡ bỏ chúng ở thư mục "media:/" +Comment[wa]=Wåde li trace des activités media eyet permete di (dis)monter (media:/) +Comment[zh_CN]=跟踪介质活动并允许挂载或卸载(media:/) +Comment[zh_TW]=持續追蹤媒體活動並允許(解除)掛載 (media:/) +ServiceTypes=KDEDModule +X-TDE-ModuleType=Library +X-TDE-Library=mediamanager +X-TDE-FactoryName=mediamanager +X-TDE-Kded-autoload=true +X-TDE-Kded-load-on-demand=true +X-TDE-Kded-phase=1 diff --git a/tdeioslave/media/mediamanager/mediamanager.h b/tdeioslave/media/mediamanager/mediamanager.h new file mode 100644 index 000000000..256d11bf8 --- /dev/null +++ b/tdeioslave/media/mediamanager/mediamanager.h @@ -0,0 +1,94 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 K�vin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _MEDIAMANAGER_H_ +#define _MEDIAMANAGER_H_ + +#include <kdedmodule.h> +#include <tqstring.h> +#include <tqstringlist.h> + +#include "medialist.h" +#include "backendbase.h" +#include "removablebackend.h" +#include "mediadirnotify.h" + +class HALBackend; +class TDEBackend; +class FstabBackend; + +class MediaManager : public KDEDModule +{ +Q_OBJECT +K_DCOP +public: + MediaManager(const TQCString &obj); + ~MediaManager(); + +k_dcop: + TQStringList fullList(); + TQStringList properties(const TQString &name); + TQStringList mountoptions(const TQString &name); + bool setMountoptions(const TQString &name, const TQStringList &options); + + TQString mount(const TQString &uid); + TQString unmount(const TQString &uid); + TQString decrypt(const TQString &uid, const TQString &password); + TQString undecrypt(const TQString &uid); + + TQString nameForLabel(const TQString &label); + ASYNC setUserLabel(const TQString &name, const TQString &label); + + ASYNC reloadBackends(); + + // Removable media handling (for people not having HAL) + bool removablePlug(const TQString &devNode, const TQString &label); + bool removableUnplug(const TQString &devNode); + bool removableCamera(const TQString &devNode); + +k_dcop_signals: + void mediumAdded(const TQString &name, bool allowNotification); + void mediumRemoved(const TQString &name, bool allowNotification); + void mediumChanged(const TQString &name, bool allowNotification); + + // For compatibility purpose, not needed for KDE4 + void mediumAdded(const TQString &name); + void mediumRemoved(const TQString &name); + void mediumChanged(const TQString &name); + +private slots: + void loadBackends(); + + void slotMediumAdded(const TQString &id, const TQString &name, + bool allowNotification); + void slotMediumRemoved(const TQString &id, const TQString &name, + bool allowNotification); + void slotMediumChanged(const TQString &id, const TQString &name, + bool mounted, bool allowNotification); + +private: + MediaList m_mediaList; + TQValueList<BackendBase*> m_backends; + RemovableBackend *mp_removableBackend; + HALBackend *m_halbackend; + TDEBackend *m_tdebackend; + MediaDirNotify m_dirNotify; + FstabBackend *m_fstabbackend; +}; + +#endif diff --git a/tdeioslave/media/mediamanager/removablebackend.cpp b/tdeioslave/media/mediamanager/removablebackend.cpp new file mode 100644 index 000000000..6b83ae1ea --- /dev/null +++ b/tdeioslave/media/mediamanager/removablebackend.cpp @@ -0,0 +1,180 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "removablebackend.h" + +#include <klocale.h> +#include <kdirwatch.h> +#include <kurl.h> +#include <kmountpoint.h> +#include <kstandarddirs.h> + +#ifdef _OS_SOLARIS_ +#define MTAB "/etc/mnttab" +#else +#define MTAB "/etc/mtab" +#endif + + + +RemovableBackend::RemovableBackend(MediaList &list) + : TQObject(), BackendBase(list) +{ + KDirWatch::self()->addFile(MTAB); + + connect( KDirWatch::self(), TQT_SIGNAL( dirty(const TQString&) ), + this, TQT_SLOT( slotDirty(const TQString&) ) ); + KDirWatch::self()->startScan(); +} + +RemovableBackend::~RemovableBackend() +{ + TQStringList::iterator it = m_removableIds.begin(); + TQStringList::iterator end = m_removableIds.end(); + + for (; it!=end; ++it) + { + m_mediaList.removeMedium(*it, false); + } + + KDirWatch::self()->removeFile(MTAB); +} + +bool RemovableBackend::plug(const TQString &devNode, const TQString &label) +{ + TQString name = generateName(devNode); + TQString id = generateId(devNode); + + if (!m_removableIds.contains(id)) + { + Medium *medium = new Medium(id, id, name); + medium->mountableState(devNode, TQString::null, + TQString::null, false); + + TQStringList words = TQStringList::split(" ", label); + + TQStringList::iterator it = words.begin(); + TQStringList::iterator end = words.end(); + + TQString tmp = (*it).lower(); + tmp[0] = tmp[0].upper(); + TQString new_label = tmp; + + ++it; + for (; it!=end; ++it) + { + tmp = (*it).lower(); + tmp[0] = tmp[0].upper(); + new_label+= " "+tmp; + } + + medium->setLabel(new_label); + medium->setMimeType("media/removable_unmounted"); + + m_removableIds.append(id); + return !m_mediaList.addMedium(medium).isNull(); + } + return false; +} + +bool RemovableBackend::unplug(const TQString &devNode) +{ + TQString id = generateId(devNode); + if (m_removableIds.contains(id)) + { + m_removableIds.remove(id); + return m_mediaList.removeMedium(id); + } + return false; +} + +bool RemovableBackend::camera(const TQString &devNode) +{ + TQString id = generateId(devNode); + if (m_removableIds.contains(id)) + { + return m_mediaList.changeMediumState(id, + TQString("camera:/"), false, "media/gphoto2camera"); + } + return false; +} + +void RemovableBackend::slotDirty(const TQString &path) +{ + if (path==MTAB) + { + handleMtabChange(); + } +} + + +void RemovableBackend::handleMtabChange() +{ + TQStringList new_mtabIds; + KMountPoint::List mtab = KMountPoint::currentMountPoints(); + + KMountPoint::List::iterator it = mtab.begin(); + KMountPoint::List::iterator end = mtab.end(); + + for (; it!=end; ++it) + { + TQString dev = (*it)->mountedFrom(); + TQString mp = (*it)->mountPoint(); + TQString fs = (*it)->mountType(); + + TQString id = generateId(dev); + new_mtabIds+=id; + + if ( !m_mtabIds.contains(id) + && m_removableIds.contains(id) ) + { + m_mediaList.changeMediumState(id, dev, mp, fs, true, + false, "media/removable_mounted"); + } + } + + TQStringList::iterator it2 = m_mtabIds.begin(); + TQStringList::iterator end2 = m_mtabIds.end(); + + for (; it2!=end2; ++it2) + { + if ( !new_mtabIds.contains(*it2) + && m_removableIds.contains(*it2) ) + { + m_mediaList.changeMediumState(*it2, false, + false, "media/removable_unmounted"); + } + } + + m_mtabIds = new_mtabIds; +} + +TQString RemovableBackend::generateId(const TQString &devNode) +{ + TQString dev = KStandardDirs::realFilePath(devNode); + + return "/org/kde/mediamanager/removable/" + +dev.replace("/", ""); +} + +TQString RemovableBackend::generateName(const TQString &devNode) +{ + return KURL(devNode).fileName(); +} + +#include "removablebackend.moc" diff --git a/tdeioslave/media/mediamanager/removablebackend.h b/tdeioslave/media/mediamanager/removablebackend.h new file mode 100644 index 000000000..fa16a391b --- /dev/null +++ b/tdeioslave/media/mediamanager/removablebackend.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _REMOVABLEBACKEND_H_ +#define _REMOVABLEBACKEND_H_ + +#include "backendbase.h" + +#include <tqobject.h> +#include <tqstringlist.h> + +class RemovableBackend : public TQObject, public BackendBase +{ +Q_OBJECT + +public: + RemovableBackend(MediaList &list); + virtual ~RemovableBackend(); + + bool plug(const TQString &devNode, const TQString &label); + bool unplug(const TQString &devNode); + bool camera(const TQString &devNode); + +private slots: + void slotDirty(const TQString &path); + +private: + void handleMtabChange(); + + static TQString generateId(const TQString &devNode); + static TQString generateName(const TQString &devNode); + + TQStringList m_removableIds; + TQStringList m_mtabIds; +}; + +#endif diff --git a/tdeioslave/media/mediamanager/tdehardwarebackend.cpp b/tdeioslave/media/mediamanager/tdehardwarebackend.cpp new file mode 100644 index 000000000..32ed746cf --- /dev/null +++ b/tdeioslave/media/mediamanager/tdehardwarebackend.cpp @@ -0,0 +1,1376 @@ +/* This file is part of the TDE Project + Copyright (c) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "tdehardwarebackend.h" + +#include <tqfile.h> +#include <tqfileinfo.h> +#include <tqeventloop.h> +#include <tqstylesheet.h> + +#include <kglobal.h> +#include <klocale.h> +#include <tdeconfig.h> +#include <tdeio/job.h> +#include <kprocess.h> +#include <kmimetype.h> +#include <kmountpoint.h> +#include <kmessagebox.h> +#include <kapplication.h> +#include <kprotocolinfo.h> + +#include "dialog.h" + +#define MOUNT_SUFFIX ( \ + (medium->isMounted() ? TQString("_mounted") : TQString("_unmounted")) + \ + (medium->isEncrypted() ? (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt) ? "_decrypted" : "_encrypted") : "" ) \ + ) +#define MOUNT_ICON_SUFFIX ( \ + (medium->isMounted() ? TQString("_mount") : TQString("_unmount")) + \ + (medium->isEncrypted() ? (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt) ? "_decrypt" : "_encrypt") : "" ) \ + ) + +#define CHECK_FOR_AND_EXECUTE_AUTOMOUNT(udi, medium, allowNotification) { \ + TQMap<TQString,TQString> options = MediaManagerUtils::splitOptions(mountoptions(udi)); \ + kdDebug(1219) << "automount " << options["automount"] << endl; \ + if (options["automount"] == "true" && allowNotification ) { \ + TQString error = mount(medium); \ + if (!error.isEmpty()) \ + kdDebug(1219) << "error " << error << endl; \ + } \ + } + +/* Constructor */ +TDEBackend::TDEBackend(MediaList &list, TQObject* parent) + : TQObject() + , BackendBase(list) + , m_decryptDialog(0) + , m_parent(parent) +{ + // Initialize the TDE device manager + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + + // Connect device monitoring signals/slots + connect(hwdevices, TQT_SIGNAL(hardwareAdded(TDEGenericDevice*)), this, TQT_SLOT(AddDeviceHandler(TDEGenericDevice*))); + connect(hwdevices, TQT_SIGNAL(hardwareRemoved(TDEGenericDevice*)), this, TQT_SLOT(RemoveDeviceHandler(TDEGenericDevice*))); + connect(hwdevices, TQT_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQT_SLOT(ModifyDeviceHandler(TDEGenericDevice*))); + + // List devices at startup + ListDevices(); +} + +/* Destructor */ +TDEBackend::~TDEBackend() +{ + // Remove all media from the media list + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + TDEGenericHardwareList hwlist = hwdevices->listAllPhysicalDevices(); + TDEGenericDevice *hwdevice; + for ( hwdevice = hwlist.first(); hwdevice; hwdevice = hwlist.next() ) { + if (hwdevice->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice); + RemoveDevice(sdevice); + } + } +} + +void TDEBackend::AddDeviceHandler(TDEGenericDevice *device) { + if (device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device); + AddDevice(sdevice); + } +} + +void TDEBackend::RemoveDeviceHandler(TDEGenericDevice *device) { + if (device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device); + RemoveDevice(sdevice); + } +} + +void TDEBackend::ModifyDeviceHandler(TDEGenericDevice *device) { + if (device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device); + ModifyDevice(sdevice); + } +} + +// List devices (at startup) +bool TDEBackend::ListDevices() +{ + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + TDEGenericHardwareList hwlist = hwdevices->listAllPhysicalDevices(); + TDEGenericDevice *hwdevice; + for ( hwdevice = hwlist.first(); hwdevice; hwdevice = hwlist.next() ) { + if (hwdevice->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice); + AddDevice(sdevice, false); + } + } + + return true; +} + +// Create a media instance for a new storage device +void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification) +{ + kdDebug(1219) << "TDEBackend::AddDevice for " << sdevice->uniqueID() << endl; + + // If the device is already listed, do not process it + // This should not happen, but who knows... + /** @todo : refresh properties instead ? */ + if (m_mediaList.findById(sdevice->uniqueID())) { + kdDebug(1219) << "TDEBackend::AddDevice for " << sdevice->uniqueID() << " found existing entry in media list" << endl; + return; + } + + // Add volume block devices + if (sdevice->isDiskOfType(TDEDiskDeviceType::HDD)) { + /* We only list volumes that... + * - are encrypted with LUKS or + * - have a filesystem or + * - have an audio track + */ + if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) + && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem)) + && !(sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) + && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) + ) { + // + } + else { + // Create medium + Medium* medium = new Medium(sdevice->uniqueID(), driveUDIFromDeviceUID(sdevice->uniqueID()), ""); + setVolumeProperties(medium); + + // Do not list the LUKS backend device if it has been unlocked elsewhere + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { + if (sdevice->holdingDevices().count() > 0) { + medium->setHidden(true); + } + else { + medium->setHidden(false); + } + } + + // Insert medium into list + m_mediaList.addMedium(medium, allowNotification); + + kdDebug(1219) << "TDEBackend::AddDevice inserted hard medium for " << sdevice->uniqueID() << endl; + + // Automount if enabled + CHECK_FOR_AND_EXECUTE_AUTOMOUNT(sdevice->uniqueID(), medium, allowNotification) + } + } + + // Add CD drives + if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo)) + ) { + + // Create medium + Medium* medium = new Medium(sdevice->uniqueID(), driveUDIFromDeviceUID(sdevice->uniqueID()), ""); + setVolumeProperties(medium); + + // Insert medium into list + m_mediaList.addMedium(medium, allowNotification); + + kdDebug(1219) << "TDEBackend::AddDevice inserted optical medium for " << sdevice->uniqueID() << endl; + + // Automount if enabled + CHECK_FOR_AND_EXECUTE_AUTOMOUNT(sdevice->uniqueID(), medium, allowNotification) + } + + // Floppy & zip drives + if ((sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) || + (sdevice->isDiskOfType(TDEDiskDeviceType::Zip)) || + (sdevice->isDiskOfType(TDEDiskDeviceType::Jaz)) + ) { + if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable)) && (!(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Inserted)))) { + allowNotification = false; + } + + /* We only list volumes that... + * - are encrypted with LUKS or + * - have a filesystem or + * - are a floppy disk + */ + if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) + && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem)) + && !(sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) + && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) + ) { + // + } + else { + // Create medium + Medium* medium = new Medium(sdevice->uniqueID(), driveUDIFromDeviceUID(sdevice->uniqueID()), ""); + + setFloppyProperties(medium); + + // Do not list the LUKS backend device if it has been unlocked elsewhere + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { + if (sdevice->holdingDevices().count() > 0) { + medium->setHidden(true); + } + else { + medium->setHidden(false); + } + } + + m_mediaList.addMedium(medium, allowNotification); + + kdDebug(1219) << "TDEBackend::AddDevice inserted floppy medium for " << sdevice->uniqueID() << endl; + + return; + } + } + + // PTP camera + if (sdevice->isDiskOfType(TDEDiskDeviceType::Camera)) { + // PTP cameras are handled by the "camera" tdeioslave + if (KProtocolInfo::isKnownProtocol( TQString("camera") ) ) + { + // Create medium + Medium* medium = new Medium(sdevice->uniqueID(), driveUDIFromDeviceUID(sdevice->uniqueID()), ""); + setCameraProperties(medium); + m_mediaList.addMedium(medium, allowNotification); + + kdDebug(1219) << "TDEBackend::AddDevice inserted camera medium for " << sdevice->uniqueID() << endl; + + return; + } + } +} + +void TDEBackend::RemoveDevice(TDEStorageDevice * sdevice) +{ + kdDebug(1219) << "TDEBackend::RemoveDevice for " << sdevice->uniqueID() << endl; + + if (!m_mediaList.findById(sdevice->uniqueID())) { + kdDebug(1219) << "TDEBackend::RemoveDevice for " << sdevice->uniqueID() << " existing entry in media list was not found" << endl; + return; + } + + m_mediaList.removeMedium(sdevice->uniqueID(), true); +} + +void TDEBackend::ModifyDevice(TDEStorageDevice * sdevice) +{ + kdDebug(1219) << "TDEBackend::ModifyDevice for " << sdevice->uniqueID() << endl; + + bool allowNotification = false; + ResetProperties(sdevice, allowNotification); +} + +void TDEBackend::ResetProperties(TDEStorageDevice * sdevice, bool allowNotification, bool overrideIgnoreList) +{ + kdDebug(1219) << "TDEBackend::ResetProperties for " << sdevice->uniqueID() << " allowNotification: " << allowNotification << " overrideIgnoreList: " << overrideIgnoreList << endl; + + if (!m_mediaList.findById(sdevice->uniqueID())) { + // This device is not currently in the device list, so add it and exit + kdDebug(1219) << "TDEBackend::ResetProperties for " << sdevice->uniqueID() << " existing entry in media list was not found" << endl; + AddDevice(sdevice); + return; + } + + // If we should ignore device change events for this device, do so + if (overrideIgnoreList == false) { + if (m_ignoreDeviceChangeEvents.contains(sdevice->uniqueID())) { + return; + } + } + + Medium* m = new Medium(sdevice->uniqueID(), driveUDIFromDeviceUID(sdevice->uniqueID()), ""); + + // Keep these conditions in sync with ::AddDevice above, OR ELSE!!! + // BEGIN + + if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) + && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem)) + && !(sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) + && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) + ) { + } + else { + // Do not list the LUKS backend device if it has been unlocked elsewhere + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { + if (sdevice->holdingDevices().count() > 0) { + m->setHidden(true); + } + else { + m->setHidden(false); + } + } + setVolumeProperties(m); + } + + if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo)) + ) { + setVolumeProperties(m); + } + + // Floppy & zip drives + if ((sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) || + (sdevice->isDiskOfType(TDEDiskDeviceType::Zip)) || + (sdevice->isDiskOfType(TDEDiskDeviceType::Jaz)) + ) { + + if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) + && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem)) + && !(sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) + && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) + ) { + // + } + else { + // Do not list the LUKS backend device if it has been unlocked elsewhere + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { + if (sdevice->holdingDevices().count() > 0) { + m->setHidden(true); + } + else { + m->setHidden(false); + } + } + + setFloppyProperties(m); + } + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::Camera)) { + setCameraProperties(m); + } + + // END + + if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable)) && (!(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Inserted)))) { + kdDebug(1219) << "TDEBackend::ResetProperties for " << sdevice->uniqueID() << " device was removed from system" << endl; + RemoveDevice(sdevice); + return; + } + + m_mediaList.changeMediumState(*m, allowNotification); + + delete m; +} + +void TDEBackend::setVolumeProperties(Medium* medium) +{ + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + + TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id()); + if (!sdevice) { + return; + } + + medium->setName(generateName(sdevice->deviceNode())); + if ((sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) || (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt))) { + medium->setEncrypted(true); + } + else { + medium->setEncrypted(false); + } + + // USAGE: mountableState(Device node, Mount point, Filesystem type, Mounted ?) + medium->mountableState(sdevice->deviceNode(), sdevice->mountPath(), sdevice->fileSystemName(), !sdevice->mountPath().isNull()); + + TQString diskLabel = sdevice->diskLabel(); + if (diskLabel.isNull()) { + diskLabel = i18n("%1 Removable Device").arg(sdevice->deviceFriendlySize()); + } + + TQString mimeType; + + if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo)) + ) { + // This device is a CD drive of some sort + + // Default + mimeType = "media/cdrom" + MOUNT_SUFFIX; + + if (sdevice->isDiskOfType(TDEDiskDeviceType::CDROM)) { + mimeType = "media/cdrom" + MOUNT_SUFFIX; + if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { + mimeType = "media/blankcd"; + medium->unmountableState(""); + diskLabel = i18n("Blank CDROM"); + } + } + if (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW)) { + mimeType = "media/cdwriter" + MOUNT_SUFFIX; + if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { + mimeType = "media/blankcd"; + medium->unmountableState(""); + diskLabel = i18n("Blank CDRW"); + } + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM)) { + mimeType = "media/dvd" + MOUNT_SUFFIX; + if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { + mimeType = "media/blankdvd"; + medium->unmountableState(""); + diskLabel = i18n("Blank DVDROM"); + } + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM)) { + mimeType = "media/dvd" + MOUNT_SUFFIX; + if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { + mimeType = "media/blankdvd"; + medium->unmountableState(""); + diskLabel = i18n("Blank DVDRAM"); + } + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW)) { + mimeType = "media/dvd" + MOUNT_SUFFIX; + if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { + mimeType = "media/blankdvd" + MOUNT_SUFFIX; + medium->unmountableState(""); + diskLabel = i18n("Blank DVDRW"); + } + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM)) { + mimeType = "media/bluray" + MOUNT_SUFFIX; + if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { + mimeType = "media/blankbd" + MOUNT_SUFFIX; + medium->unmountableState(""); + diskLabel = i18n("Blank BDROM"); + } + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW)) { + mimeType = "media/bluray" + MOUNT_SUFFIX; + if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { + mimeType = "media/blankbd" + MOUNT_SUFFIX; + medium->unmountableState(""); + diskLabel = i18n("Blank BDRW"); + } + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) { + mimeType = "media/audiocd"; + medium->unmountableState("audiocd:/?device=" + sdevice->deviceNode()); + diskLabel = i18n("Audio CD"); + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo)) { + mimeType = "media/vcd"; + } + if (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo)) { + mimeType = "media/dvdvideo"; + } + if (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo)) { + mimeType = "media/bdvideo"; + } + + medium->setIconName(TQString::null); + } + else { + // This device is a hard or flash disk of some kind + + // Default + mimeType = "media/hdd" + MOUNT_SUFFIX; + + if (sdevice->isDiskOfType(TDEDiskDeviceType::USB)) { + mimeType = "media/removable" + MOUNT_SUFFIX; + medium->needMounting(); + + if (sdevice->isDiskOfType(TDEDiskDeviceType::CompactFlash)) { + medium->setIconName("compact_flash" + MOUNT_ICON_SUFFIX); + } + if (sdevice->isDiskOfType(TDEDiskDeviceType::MemoryStick)) { + medium->setIconName("memory_stick" + MOUNT_ICON_SUFFIX); + } + if (sdevice->isDiskOfType(TDEDiskDeviceType::SmartMedia)) { + medium->setIconName("smart_media" + MOUNT_ICON_SUFFIX); + } + if (sdevice->isDiskOfType(TDEDiskDeviceType::SDMMC)) { + medium->setIconName("sd_mmc" + MOUNT_ICON_SUFFIX); + } + if (sdevice->isDiskOfType(TDEDiskDeviceType::MediaDevice)) { + medium->setIconName("ipod" + MOUNT_ICON_SUFFIX); + + if (sdevice->vendorModel().upper().contains("IPOD") && KProtocolInfo::isKnownProtocol( TQString("ipod") ) ) + { + medium->unmountableState( "ipod:/" ); + medium->mountableState(!sdevice->mountPath().isNull()); + } + } + if (sdevice->isDiskOfType(TDEDiskDeviceType::Tape)) { + medium->setIconName("magnetic_tape" + MOUNT_ICON_SUFFIX); + } + if (medium->isMounted() && TQFile::exists(medium->mountPoint() + "/dcim")) + { + mimeType = "media/camera" + MOUNT_SUFFIX; + } + } + } + + if (!medium->needMounting()) { + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { + if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::UsedByDevice)) { + // Encrypted base devices must be set to this mimetype or they won't open when the base device node is passed to the tdeioslave + mimeType = "media/removable_mounted"; + } + } + } + + medium->setLabel(diskLabel); + medium->setMimeType(mimeType); +} + +// Handle floppies and zip drives +bool TDEBackend::setFloppyProperties(Medium* medium) +{ + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + + TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id()); + if (!sdevice) { + return false; + } + + medium->setName(generateName(sdevice->deviceNode())); + medium->setLabel(i18n("Unknown Drive")); + + // Certain disks have a lot in common with hard drives + // FIXME + // Any more? + if ((sdevice->isDiskOfType(TDEDiskDeviceType::Zip)) || (sdevice->isDiskOfType(TDEDiskDeviceType::Jaz))) { + medium->setName(generateName(sdevice->deviceNode())); + if ((sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) || (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt))) { + medium->setEncrypted(true); + } + else { + medium->setEncrypted(false); + } + + // USAGE: mountableState(Device node, Mount point, Filesystem type, Mounted ?) + medium->mountableState(sdevice->deviceNode(), sdevice->mountPath(), sdevice->fileSystemName(), !sdevice->mountPath().isNull()); + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) { + setFloppyMountState(medium); + + // We don't use the routine above as floppy disks are extremely slow (we don't want them accessed at all during media listing) + medium->mountableState(sdevice->deviceNode(), sdevice->mountPath(), sdevice->fileSystemName(), !sdevice->mountPath().isNull()); + + if (sdevice->mountPath().isNull()) { + medium->setMimeType("media/floppy_unmounted"); + } + else { + medium->setMimeType("media/floppy_mounted" ); + } + medium->setLabel(i18n("Floppy Drive")); + } + + if (sdevice->isDiskOfType(TDEDiskDeviceType::Zip)) { + if (sdevice->mountPath().isNull()) { + medium->setMimeType("media/zip_unmounted"); + } + else { + medium->setMimeType("media/zip_mounted" ); + } + + // Set label + TQString diskLabel = sdevice->diskLabel(); + if (diskLabel.isNull()) { + diskLabel = i18n("%1 Zip Disk").arg(sdevice->deviceFriendlySize()); + } + medium->setLabel(diskLabel); + } + + /** @todo Mimetype for JAZ drives ? */ + + medium->setIconName(TQString::null); + + return true; +} + +void TDEBackend::setCameraProperties(Medium* medium) +{ + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + + TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id()); + if (!sdevice) { + return; + } + + TQString cameraName = sdevice->friendlyName(); + cameraName.replace("/", "_"); + medium->setName(cameraName); + + TQString device = "camera:/"; + + TQStringList devNodeList = TQStringList::split("/", sdevice->deviceNode(), TRUE); + TQString devNode0 = devNodeList[devNodeList.count()-2]; + TQString devNode1 = devNodeList[devNodeList.count()-1]; + + if ((devNode0 != "") && (devNode1 != "")) { + device.sprintf("camera://@[usb:%s,%s]/", devNode0.ascii(), devNode1.ascii()); + } + + medium->unmountableState(device); + medium->setMimeType("media/gphoto2camera"); + medium->setIconName(TQString::null); + + if (sdevice->friendlyName() != "") { + medium->setLabel(sdevice->friendlyName()); + } + else { + medium->setLabel(i18n("Camera")); + } +} + +void TDEBackend::setFloppyMountState( Medium *medium ) +{ + KMountPoint::List mtab = KMountPoint::currentMountPoints(); + KMountPoint::List::iterator it = mtab.begin(); + KMountPoint::List::iterator end = mtab.end(); + + TQString fstype; + TQString mountpoint; + for (; it!=end; ++it) { + if ((*it)->mountedFrom() == medium->deviceNode() ) { + fstype = (*it)->mountType().isNull() ? (*it)->mountType() : "auto"; + mountpoint = (*it)->mountPoint(); + medium->mountableState( medium->deviceNode(), mountpoint, fstype, true ); + return; + } + } +} + +TQStringList TDEBackend::mountoptions(const TQString &name) +{ + const Medium* medium = m_mediaList.findById(name); + if (!medium) { + return TQStringList(); // we know nothing about that device + } + if (!isInFstab(medium).isNull()) { + return TQStringList(); // device is listed in fstab, therefore is not handled by us + } + + if (medium->isEncrypted()) { + // if not decrypted yet then there are no mountoptions + return TQStringList(); + } + + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + + TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id()); + if (!sdevice) { + return TQStringList(); // we can't get the information needed in order to process mount options + } + + TQStringList result; + + // Allow only those options which are valid for the given device + // pmount only allows a subset of options, and those are given in the map below + // FIXME + TQMap<TQString,bool> valids; + valids["ro"] = true; + //valids["quiet"] = false; + //valids["flush"] = false; + //valids["uid"] = false; + valids["utf8"] = true; + //valids["shortname"] = false; + valids["locale"] = true; + valids["sync"] = true; + valids["noatime"] = true; + //valids["data"] = false; + + TQString drive_udi = driveUDIFromDeviceUID(medium->id()); + + TDEConfig config("mediamanagerrc"); + + bool use_defaults = true; + if (config.hasGroup(drive_udi)) { + config.setGroup(drive_udi); + use_defaults = config.readBoolEntry("use_defaults", false); + } + if (use_defaults) { + config.setGroup("DefaultOptions"); + } + result << TQString("use_defaults=%1").arg(use_defaults ? "true" : "false"); + + bool removable = false; + if (!drive_udi.isNull()) { + removable = ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable)) || (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable))); + } + + TQString tmp; + bool value; + if (use_defaults) { + value = config.readBoolEntry("automount", false); + } + else { + QString current_group = config.group(); + config.setGroup(drive_udi); + value = config.readBoolEntry("automount", false); + config.setGroup(current_group); + } + + if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo)) + || (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo)) + ) { + value = false; + } + + result << TQString("automount=%1").arg(value ? "true" : "false"); + + if (valids.contains("ro")) { + value = config.readBoolEntry("ro", false); + tmp = TQString("ro=%1").arg(value ? "true" : "false"); + if (sdevice->fileSystemName() != "iso9660") { + result << tmp; + } + } + + if (valids.contains("quiet")) { + value = config.readBoolEntry("quiet", false); + tmp = TQString("quiet=%1").arg(value ? "true" : "false"); + if (sdevice->fileSystemName() != "iso9660") { + result << tmp; + } + } + + if (valids.contains("flush")) { + value = config.readBoolEntry("flush", sdevice->fileSystemName().endsWith("fat")); + tmp = TQString("flush=%1").arg(value ? "true" : "false"); + result << tmp; + } + + if (valids.contains("uid")) { + value = config.readBoolEntry("uid", true); + tmp = TQString("uid=%1").arg(value ? "true" : "false"); + result << tmp; + } + + if (valids.contains("utf8")) { + value = config.readBoolEntry("utf8", true); + tmp = TQString("utf8=%1").arg(value ? "true" : "false"); + result << tmp; + } + + if (valids.contains("shortname")) { + TQString svalue = config.readEntry("shortname", "lower").lower(); + if (svalue == "winnt") { + result << "shortname=winnt"; + } + else if (svalue == "win95") { + result << "shortname=win95"; + } + else if (svalue == "mixed") { + result << "shortname=mixed"; + } + else { + result << "shortname=lower"; + } + } + + // pass our locale to the ntfs-3g driver so it can translate local characters + if (valids.contains("locale") && (sdevice->fileSystemName() == "ntfs-3g")) { + // 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")) ) { + result << TQString("locale=%1").arg(cType); + } + } + + if (valids.contains("sync")) { + value = config.readBoolEntry("sync", ( valids.contains("flush") && !sdevice->fileSystemName().endsWith("fat") ) && removable); + tmp = TQString("sync=%1").arg(value ? "true" : "false"); + if (sdevice->fileSystemName() != "iso9660") { + result << tmp; + } + } + + if (valids.contains("noatime")) { + value = config.readBoolEntry("atime", !sdevice->fileSystemName().endsWith("fat")); + tmp = TQString("atime=%1").arg(value ? "true" : "false"); + if (sdevice->fileSystemName() != "iso9660") { + result << tmp; + } + } + + TQString mount_point; + mount_point = config.readEntry("mountpoint", TQString::null); + + if (!mount_point.startsWith("/")) { + mount_point = "/media/" + mount_point; + } + if (mount_point != "") { + result << TQString("mountpoint=%1").arg(mount_point); + } + + TQString file_system_name; + file_system_name = sdevice->fileSystemName(); + if (file_system_name != "") { + result << TQString("filesystem=%1").arg(file_system_name); + } + + if (valids.contains("data")) { + TQString svalue = config.readEntry("journaling").lower(); + if (svalue == "ordered") { + result << "journaling=ordered"; + } + else if (svalue == "writeback") { + result << "journaling=writeback"; + } + else if (svalue == "data") { + result << "journaling=data"; + } + else { + result << "journaling=ordered"; + } + } + + return result; +} + +bool TDEBackend::setMountoptions(const TQString &name, const TQStringList &options ) +{ + const Medium* medium = m_mediaList.findById(name); + if (!medium) { + return false; // we know nothing about that device + } + if (!isInFstab(medium).isNull()) { + return false; // device is listed in fstab, therefore is not handled by us + } + + TQString drive_udi = driveUDIFromDeviceUID(medium->id()); + + kdDebug(1219) << "setMountoptions " << name << " " << options << endl; + + TDEConfig config("mediamanagerrc"); + config.setGroup(drive_udi); + + TQMap<TQString,TQString> valids = MediaManagerUtils::splitOptions(options); + + const char *names[] = { "use_defaults", "ro", "quiet", "atime", "uid", "utf8", "flush", "sync", 0 }; + for (int index = 0; names[index]; ++index) { + if (valids.contains(names[index])) { + config.writeEntry(names[index], valids[names[index]] == "true"); + } + } + + if (valids.contains("shortname")) { + config.writeEntry("shortname", valids["shortname"]); + } + + if (valids.contains("journaling")) { + config.writeEntry("journaling", valids["journaling"]); + } + + if (!mountoptions(name).contains(TQString("mountpoint=%1").arg(valids["mountpoint"]))) { + config.writeEntry("mountpoint", valids["mountpoint"]); + } + + if (valids.contains("automount")) { + config.setGroup(drive_udi); + config.writeEntry("automount", valids["automount"]); + } + + return true; +} + +void TDEBackend::slotPasswordReady() { + m_decryptionPassword = m_decryptDialog->getPassword(); + m_decryptPasswordValid = true; +} + +void TDEBackend::slotPasswordCancel() { + m_decryptionPassword = TQString::null; + m_decryptPasswordValid = true; +} + +TQString TDEBackend::mount(const Medium *medium) +{ + if (medium->isMounted()) { + return TQString(); // that was easy + } + + TQString mountPoint = isInFstab(medium); + if (!mountPoint.isNull()) + { + struct mount_job_data data; + data.completed = false; + data.medium = medium; + + TDEIO::Job *job = TDEIO::mount( false, 0, medium->deviceNode(), mountPoint ); + connect(job, TQT_SIGNAL( result (TDEIO::Job *)), TQT_SLOT( slotResult( TDEIO::Job *))); + mount_jobs[job] = &data; + // The caller expects the device to be mounted when the function + // completes. Thus block until the job completes. + while (!data.completed) { + kapp->eventLoop()->enterLoop(); + } + // Return the error message (if any) to the caller + return (data.error) ? data.errorMessage : TQString::null; + + } + + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + + TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id()); + if (!sdevice) { + return i18n("Internal error"); + } + + TQString optionString; + TQString diskLabel; + + TQMap<TQString,TQString> valids = MediaManagerUtils::splitOptions(mountoptions(medium->id())); + if (valids["ro"] == "true") { + optionString.append(" -r"); + } + + if (valids["atime"] != "true") { + optionString.append(" -A"); + } + + if (valids["utf8"] == "true") { + optionString.append(" -c utf8"); + } + + if (valids["sync"] == "true") { + optionString.append(" -s"); + } + + TQString mount_point = valids["mountpoint"]; + if (mount_point.startsWith("/media/")) { + diskLabel = mount_point.mid(7); + } + + if (valids.contains("filesystem")) { + optionString.append(TQString(" -t %1").arg(valids["filesystem"])); + } + + if (valids.contains("locale")) { + optionString.append(TQString(" -c %1").arg(valids["locale"])); + } + + if (diskLabel == "") { + // Try to use a pretty mount point if possible + TQStringList pieces = TQStringList::split("/", sdevice->deviceNode(), FALSE); + TQString node = pieces[pieces.count()-1]; + diskLabel = medium->label() + " (" + node + ")"; + diskLabel.replace("/", "_"); + } + + TQString qerror = i18n("Cannot mount encrypted drives!"); + + if (!medium->isEncrypted()) { + // normal volume + TQString mountMessages; + TQString mountedPath = sdevice->mountDevice(diskLabel, optionString, &mountMessages); + if (mountedPath.isNull()) { + qerror = i18n("<qt>Unable to mount this device.<p>Potential reasons include:<br>Improper device and/or user privilege level<br>Corrupt data on storage device"); + if (!mountMessages.isNull()) { + qerror.append(i18n("<p>Technical details:<br>").append(mountMessages)); + } + qerror.append("</qt>"); + } + else { + qerror = ""; + } + } + else { + TQString iconName = medium->iconName(); + if (iconName.isEmpty()) + { + TQString mime = medium->mimeType(); + iconName = KMimeType::mimeType(mime)->icon(mime, false); + } + + bool continue_trying_to_decrypt = true; + while (continue_trying_to_decrypt == true) { + m_decryptPasswordValid = false; + + m_decryptDialog = new Dialog(sdevice->deviceNode(), iconName); + m_decryptDialog->show(); + + connect(m_decryptDialog, TQT_SIGNAL (user1Clicked()), this, TQT_SLOT (slotPasswordReady())); + connect(m_decryptDialog, TQT_SIGNAL (cancelClicked()), this, TQT_SLOT (slotPasswordCancel())); + connect(this, TQT_SIGNAL (signalDecryptionPasswordError(TQString)), m_decryptDialog, TQT_SLOT (slotDialogError(TQString))); + + while (m_decryptPasswordValid == false) { + tqApp->processEvents(); + } + + m_decryptDialog->setEnabled(false); + tqApp->processEvents(); + + if (m_decryptionPassword.isNull()) { + delete m_decryptDialog; + return TQString("Decryption aborted"); + } + else { + // Just for some added fun, if udev emits a medium change event, which I then forward, with mounted==0, it stops the MediaProtocol::listDir method dead in its tracks, + // and therefore the media:/ tdeioslave won't refresh after the encrypted device mount + // Therefore, I need to ignore all change events on this device during the mount process and hope nothing bad happens as a result! + if (!m_ignoreDeviceChangeEvents.contains(sdevice->uniqueID())) { + m_ignoreDeviceChangeEvents.append(sdevice->uniqueID()); + } + + // mount encrypted volume with password + int mountRetcode; + TQString mountMessages; + TQString mountedPath = sdevice->mountEncryptedDevice(m_decryptionPassword, diskLabel, optionString, &mountMessages, &mountRetcode); + if (mountedPath.isNull()) { + if (mountRetcode == 0) { + // Mounting was successful + // Because the TDE hardware backend is event driven it might take a little while for the new unencrypted mapped device to show up + // Wait up to 30 seconds for it to appear... + for (int i=0;i<300;i++) { + mountedPath = sdevice->mountPath(); + if (!mountedPath.isNull()) { + break; + } + tqApp->processEvents(50); + usleep(50000); + } + } + } + if (mountedPath.isNull()) { + if (mountRetcode == 25600) { + // Probable LUKS failure + // Retry + m_decryptDialog->setEnabled(true); + continue_trying_to_decrypt = true; + } + else { + qerror = i18n("<qt>Unable to mount this device.<p>Potential reasons include:<br>Improper device and/or user privilege level<br>Corrupt data on storage device<br>Incorrect encryption password"); + if (!mountMessages.isNull()) { + qerror.append(i18n("<p>Technical details:<br>").append(mountMessages)); + } + qerror.append("</qt>"); + continue_trying_to_decrypt = false; + } + } + else { + qerror = ""; + continue_trying_to_decrypt = false; + } + + delete m_decryptDialog; + } + } + } + + if (!qerror.isEmpty()) { + return qerror; + } + + ResetProperties(sdevice, false, true); + + if (m_ignoreDeviceChangeEvents.contains(sdevice->uniqueID())) { + m_ignoreDeviceChangeEvents.remove(sdevice->uniqueID()); + } + + return TQString(); +} + +TQString TDEBackend::mount(const TQString &_udi) +{ + const Medium* medium = m_mediaList.findById(_udi); + if (!medium) + return i18n("No such medium: %1").arg(_udi); + + return mount(medium); +} + +TQString TDEBackend::unmount(const TQString &_udi) +{ + const Medium* medium = m_mediaList.findById(_udi); + + if ( !medium ) + return i18n("No such medium: %1").arg(_udi); + + if (!medium->isMounted()) + return TQString(); // that was easy + + TQString mountPoint = isInFstab(medium); + if (!mountPoint.isNull()) + { + struct mount_job_data data; + data.completed = false; + data.medium = medium; + + TDEIO::Job *job = TDEIO::unmount( medium->mountPoint(), false ); + connect(job, TQT_SIGNAL( result (TDEIO::Job *)), TQT_SLOT( slotResult( TDEIO::Job *))); + mount_jobs[job] = &data; + // The caller expects the device to be unmounted when the function + // completes. Thus block until the job completes. + while (!data.completed) { + kapp->eventLoop()->enterLoop(); + } + // Return the error message (if any) to the caller + return (data.error) ? data.errorMessage : TQString::null; + } + + TQString udi = TQString::null; + + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + + TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id()); + if (!sdevice) { + return i18n("Internal error"); + } + + TQString qerror; + TQString origqerror; + + // Save these for later + TQString uid = sdevice->uniqueID(); + TQString node = sdevice->deviceNode(); + + TQString unmountMessages; + int unmountRetcode = 0; + if (!sdevice->unmountDevice(&unmountMessages, &unmountRetcode)) { + // Unmount failed! + qerror = "<qt>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at <b>%4</b> could not be unmounted. ").arg("system:/media/" + medium->name(), medium->deviceNode(), medium->prettyLabel(), medium->prettyBaseURL().pathOrURL()); + if (!unmountMessages.isNull()) { + qerror.append(i18n("<p>Technical details:<br>").append(unmountMessages)); + } + qerror.append("</qt>"); + } + else { + qerror = ""; + } + + if (unmountRetcode == 1280) { + // Failed as BUSY + TQString processesUsingDev = listUsingProcesses(medium); + if (!processesUsingDev.isNull()) { + if (KMessageBox::warningYesNo(0, i18n("<qt>The device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at <b>%4</b> can not be unmounted at this time.<p>%5<p><b>Would you like to forcibly terminate these processes?</b><br><i>All unsaved data would be lost</i>").arg("system:/media/" + medium->name()).arg(medium->deviceNode()).arg(medium->prettyLabel()).arg(medium->prettyBaseURL().pathOrURL()).arg(processesUsingDev)) == KMessageBox::Yes) { + killUsingProcesses(medium); + if (!sdevice->unmountDevice(&unmountMessages, &unmountRetcode)) { + // Unmount failed! + qerror = "<qt>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at <b>%4</b> could not be unmounted. ").arg("system:/media/" + medium->name(), medium->deviceNode(), medium->prettyLabel(), medium->prettyBaseURL().pathOrURL()); + if (!unmountMessages.isNull()) { + qerror.append(i18n("<p>Technical details:<br>").append(unmountMessages)); + } + qerror.append("</qt>"); + } + else { + qerror = ""; + } + } + } + } + + if (qerror != "") { + return qerror; + } + + // There is a possibility that the storage device was unceremoniously removed from the system immediately after it was unmounted + // There is no reliable way to know if this happened either! + // For now, see if the device node still exists + TQFileInfo checkDN(node); + if (!checkDN.exists()) { + m_mediaList.removeMedium(uid, true); + } + else { + TQString mountedPath = sdevice->mountPath(); + if (!mountedPath.isNull()) { + // Because the TDE hardware backend is event driven it might take a little while for the device to show up as unmounted + // Wait up to 30 seconds for the mount to disappear... + for (int i=0;i<300;i++) { + mountedPath = sdevice->mountPath(); + if (mountedPath.isNull()) { + break; + } + tqApp->processEvents(50); + usleep(50000); + } + } + + ResetProperties(sdevice, false); + } + + return TQString(); +} + +TQString TDEBackend::isInFstab(const Medium *medium) +{ + KMountPoint::List fstab = KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions|KMountPoint::NeedRealDeviceName); + + KMountPoint::List::iterator it = fstab.begin(); + KMountPoint::List::iterator end = fstab.end(); + + for (; it!=end; ++it) + { + TQString reald = (*it)->realDeviceName(); + if ( reald.endsWith( "/" ) ) { + reald = reald.left( reald.length() - 1 ); + } + if ((*it)->mountedFrom() == medium->deviceNode() || ( !medium->deviceNode().isEmpty() && reald == medium->deviceNode() ) ) + { + TQStringList opts = (*it)->mountOptions(); + if (opts.contains("user") || opts.contains("users")) { + return (*it)->mountPoint(); + } + } + } + + return TQString::null; +} + +TQString TDEBackend::listUsingProcesses(const Medium* medium) +{ + TQString proclist, fullmsg; + TQString cmdline = TQString("/usr/bin/env fuser -vm %1 2>&1").arg(TDEProcess::quote(medium->mountPoint())); + FILE *fuser = popen(cmdline.latin1(), "r"); + + uint counter = 0; + if (fuser) { + proclist += "<pre>"; + TQTextIStream is(fuser); + TQString tmp; + while (!is.atEnd()) { + tmp = is.readLine(); + tmp = TQStyleSheet::escape(tmp) + "\n"; + + proclist += tmp; + if (counter++ > 10) { + proclist += "..."; + break; + } + } + proclist += "</pre>"; + (void)pclose( fuser ); + } + if (counter) { + fullmsg = i18n("Programs still using the device " + "have been detected. They are listed below. You have to " + "close them or change their working directory before " + "attempting to unmount the device again."); + fullmsg += "<br>" + proclist; + return fullmsg; + } + else { + return TQString::null; + } +} + +TQString TDEBackend::killUsingProcesses(const Medium* medium) +{ + TQString proclist, fullmsg; + TQString cmdline = TQString("/usr/bin/env fuser -vmk %1 2>&1").arg(TDEProcess::quote(medium->mountPoint())); + FILE *fuser = popen(cmdline.latin1(), "r"); + + uint counter = 0; + if (fuser) { + proclist += "<pre>"; + TQTextIStream is(fuser); + TQString tmp; + while (!is.atEnd()) { + tmp = is.readLine(); + tmp = TQStyleSheet::escape(tmp) + "\n"; + + proclist += tmp; + if (counter++ > 10) { + proclist += "..."; + break; + } + } + proclist += "</pre>"; + (void)pclose( fuser ); + } + if (counter) { + fullmsg = i18n("Programs that were still using the device " + "have been forcibly terminated. They are listed below."); + fullmsg += "<br>" + proclist; + return fullmsg; + } + else { + return TQString::null; + } +} + +TQString TDEBackend::generateName(const TQString &devNode) +{ + return KURL(devNode).fileName(); +} + +TQString TDEBackend::driveUDIFromDeviceUID(TQString uuid) { + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + + TDEStorageDevice * sdevice = hwdevices->findDiskByUID(uuid); + TQString ret; + if (sdevice) { + ret = sdevice->diskUUID(); + if (ret != "") { + ret = "volume_uuid_" + ret; + } + else { + ret = sdevice->deviceNode(); + if (ret != "") { + ret = "device_node_" + ret; + } + else { + ret = sdevice->uniqueID(); + } + } + } + if (ret == "") { + return TQString::null; + } + else { + return ret; + } +} + +#include "tdehardwarebackend.moc"
\ No newline at end of file diff --git a/tdeioslave/media/mediamanager/tdehardwarebackend.h b/tdeioslave/media/mediamanager/tdehardwarebackend.h new file mode 100644 index 000000000..9b5407d8f --- /dev/null +++ b/tdeioslave/media/mediamanager/tdehardwarebackend.h @@ -0,0 +1,171 @@ +/* This file is part of the TDE Project + Copyright (c) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/** +* This is a media:/ backend for the builtin TDE hardware library +* +* @author Timothy Pearson <kb9vqf@pearsoncomputing.net> +* @short media:/ backend for the TDE hardware library +*/ + +#ifndef _TDEBACKEND_H_ +#define _TDEBACKEND_H_ + +#include "backendbase.h" + +#include <tqobject.h> +#include <tqstringlist.h> +#include <tqstring.h> + +#include <config.h> + +#include <tdehardwaredevices.h> + +namespace TDEIO { + class Job; +} + +class Dialog; + +class TDEBackend : public TQObject, public BackendBase +{ +Q_OBJECT + +public: + /** + * Constructor + */ + TDEBackend(MediaList &list, TQObject* parent); + + /** + * Destructor + */ + ~TDEBackend(); + + /** + * List all devices and append them to the media device list (called only once, at startup). + * + * @return true if succeded, false otherwise + */ + bool ListDevices(); + + TQStringList mountoptions(const TQString &id); + + bool setMountoptions(const TQString &id, const TQStringList &options); + + TQString mount(const TQString &id); + TQString mount(const Medium *medium); + TQString unmount(const TQString &id); +// TQString decrypt(const TQString &id, const TQString &password); +// TQString undecrypt(const TQString &id); + +private: + /** + * Append a device in the media list. This function will check if the device + * is worth listing. + * + * @param sdevice A pointer to a TDEStorageDevice object + * @param allowNotification Indicates if this event will be notified to the user + */ + void AddDevice(TDEStorageDevice * sdevice, bool allowNotification=true); + + /** + * Remove a device from the device list + * + * @param sdevice A pointer to a TDEStorageDevice object + */ + void RemoveDevice(TDEStorageDevice * sdevice); + + /** + * A device has changed, update it + * + * @param sdevice A pointer to a TDEStorageDevice object + */ + void ModifyDevice(TDEStorageDevice * sdevice); + +private slots: + void AddDeviceHandler(TDEGenericDevice* device); + void RemoveDeviceHandler(TDEGenericDevice* device); + void ModifyDeviceHandler(TDEGenericDevice* device); + + void slotPasswordReady(); + void slotPasswordCancel(); + +signals: + void signalDecryptionPasswordError(TQString); + +/* Set media properties */ +private: + /** + * Reset properties for the given medium + * + * @param sdevice A pointer to a TDEStorageDevice objec + * @param allowNotification Indicates if this event will be notified to the user + * @param overrideIgnoreList If true, override event ignore requests for the current device node + */ + void ResetProperties(TDEStorageDevice * sdevice, bool allowNotification=false, bool overrideIgnoreList=false); + + /** + * Find the medium that is concerned with device udi + */ +// const char* findMediumUdiFromUdi(const char* udi); + + void setVolumeProperties(Medium* medium); + bool setFloppyProperties(Medium* medium); + void setFloppyMountState( Medium* medium ); +// bool setFstabProperties(Medium* medium); + void setCameraProperties(Medium* medium); + TQString generateName(const TQString &devNode); + static TQString isInFstab(const Medium *medium); + static TQString listUsingProcesses(const Medium *medium); + static TQString killUsingProcesses(const Medium *medium); + + TQString driveUDIFromDeviceUID(TQString uuid); + + // Decryption + Dialog* m_decryptDialog; + TQString m_decryptionPassword; + bool m_decryptPasswordValid; + +/* TDE structures */ +private: + /** + * Object for the kded module + */ + TQObject* m_parent; + + /** + * Data structure for fstab mount/unmount jobs + */ + struct mount_job_data { + // [in] Medium, which is being mounted/unmounted by the job + const Medium* medium; + // [in,out] Should be set to true when the job completes + bool completed; + // [out] TDEIO::Error if an error occured during operation. Otherwise, 0 + int error; + // [out] Error message to be displayed to the user + TQString errorMessage; + }; + + TQMap<TDEIO::Job *, struct mount_job_data*> mount_jobs; + + TQStringList m_ignoreDeviceChangeEvents; +}; + +#endif /* _TDEBACKEND_H_ */ diff --git a/tdeioslave/media/medianotifier/CMakeLists.txt b/tdeioslave/media/medianotifier/CMakeLists.txt new file mode 100644 index 000000000..9618f79ab --- /dev/null +++ b/tdeioslave/media/medianotifier/CMakeLists.txt @@ -0,0 +1,43 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdeioslave/media/libmediacommon + ${CMAKE_SOURCE_DIR}/tdeioslave/media/libmediacommon + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES medianotifier.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded ) + + +##### kded_medianotifier (module) ############### + +set( target kded_medianotifier ) + +set( ${target}_SRCS + medianotifier.cpp medianotifier.skel notificationdialog.cpp + notificationdialogview.ui +) + +tde_add_kpart( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK mediacommon-static tdeinit_kded-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/tdeioslave/media/medianotifier/Makefile.am b/tdeioslave/media/medianotifier/Makefile.am new file mode 100644 index 000000000..b31354810 --- /dev/null +++ b/tdeioslave/media/medianotifier/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(srcdir)/../libmediacommon -I../libmediacommon $(all_includes) + +kde_module_LTLIBRARIES = kded_medianotifier.la +kded_medianotifier_la_LDFLAGS = -module -avoid-version $(all_libraries) +kded_medianotifier_la_LIBADD = ../libmediacommon/libmediacommon.la $(LIB_TDECORE) \ + $(LIB_TDEUI) $(LIB_KIO) +kded_medianotifier_la_SOURCES = medianotifier.cpp medianotifier.skel \ + notificationdialog.cpp notificationdialogview.ui + +noinst_HEADERS = medianotifier.h notificationdialog.h + +METASOURCES = AUTO + +services_DATA = medianotifier.desktop +servicesdir = $(kde_servicesdir)/kded + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kay.pot diff --git a/tdeioslave/media/medianotifier/medianotifier.cpp b/tdeioslave/media/medianotifier/medianotifier.cpp new file mode 100644 index 000000000..de6a56645 --- /dev/null +++ b/tdeioslave/media/medianotifier/medianotifier.cpp @@ -0,0 +1,386 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "medianotifier.h" + +#include <sys/vfs.h> + +#include <tqfile.h> +#include <tqfileinfo.h> +#include <tqdir.h> +#include <tqcheckbox.h> + +#include <kapplication.h> +#include <kglobal.h> +#include <kdebug.h> +#include <klocale.h> +#include <kprocess.h> +#include <krun.h> +#include <kmessagebox.h> +#include <kstdguiitem.h> +#include <kstandarddirs.h> + +#include "notificationdialog.h" +#include "notifiersettings.h" +#include "notifieraction.h" +#include "mediamanagersettings.h" + +MediaNotifier::MediaNotifier(const TQCString &name) : KDEDModule(name) +{ + connectDCOPSignal( "kded", "mediamanager", "mediumAdded(TQString, bool)", + "onMediumChange(TQString, bool)", true ); + + connectDCOPSignal( "kded", "mediamanager", "mediumChanged(TQString, bool)", + "onMediumChange(TQString, bool)", true ); + + m_freeTimer = new TQTimer( this ); + connect( m_freeTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( checkFreeDiskSpace() ) ); + m_freeTimer->start( 1000*6*2 /* 20 minutes */ ); + m_freeDialog = 0; +} + +MediaNotifier::~MediaNotifier() +{ + disconnectDCOPSignal( "kded", "mediamanager", "mediumAdded(TQString, bool)", + "onMediumChange(TQString, bool)" ); + + disconnectDCOPSignal( "kded", "mediamanager", "mediumChanged(TQString, bool)", + "onMediumChange(TQString, bool)" ); +} + +void MediaNotifier::onMediumChange( const TQString &name, bool allowNotification ) +{ + kdDebug() << "MediaNotifier::onMediumChange( " << name << ", " + << allowNotification << ")" << endl; + + if ( !allowNotification ) + return; + +// Update user activity timestamp, otherwise the notification dialog will be shown +// in the background due to focus stealing prevention. Entering a new media can +// be seen as a kind of user activity after all. It'd be better to update the timestamp +// as soon as the media is entered, but it apparently takes some time to get here. + kapp->updateUserTimestamp(); + + KURL url( "system:/media/"+name ); + + TDEIO::SimpleJob *job = TDEIO::stat( url, false ); + job->setInteractive( false ); + + m_allowNotificationMap[job] = allowNotification; + + connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), + this, TQT_SLOT( slotStatResult( TDEIO::Job * ) ) ); +} + +void MediaNotifier::slotStatResult( TDEIO::Job *job ) +{ + bool allowNotification = m_allowNotificationMap[job]; + m_allowNotificationMap.remove( job ); + + if ( job->error() != 0 ) return; + + TDEIO::StatJob *stat_job = static_cast<TDEIO::StatJob *>( job ); + + TDEIO::UDSEntry entry = stat_job->statResult(); + KURL url = stat_job->url(); + + KFileItem medium( entry, url ); + + if ( autostart( medium ) ) return; + + if ( allowNotification ) notify( medium ); +} + +bool MediaNotifier::autostart( const KFileItem &medium ) +{ + TQString mimetype = medium.mimetype(); + + bool is_cdrom = mimetype.startsWith( "media/cd" ) || mimetype.startsWith( "media/dvd" ); + bool is_mounted = mimetype.contains( "_mounted" ); + + // We autorun only on CD/DVD or removable disks (USB, Firewire) + if ( !( is_cdrom || is_mounted ) + && !mimetype.startsWith("media/removable_mounted") ) + { + return false; + } + + + // Here starts the 'Autostart Of Applications After Mount' implementation + + // The desktop environment MAY ignore Autostart files altogether + // based on policy set by the user, system administrator or vendor. + MediaManagerSettings::self()->readConfig(); + if ( !MediaManagerSettings::self()->autostartEnabled() ) + { + return false; + } + + // From now we're sure the medium is already mounted. + // We can use the local path for stating, no need to use KIO here. + bool local; + TQString path = medium.mostLocalURL( local ).path(); // local is always true here... + + // When a new medium is mounted the root directory of the medium should + // be checked for the following Autostart files in order of precedence: + // .autorun, autorun, autorun.sh + TQStringList autorun_list; + autorun_list << ".autorun" << "autorun" << "autorun.sh"; + + TQStringList::iterator it = autorun_list.begin(); + TQStringList::iterator end = autorun_list.end(); + + for ( ; it!=end; ++it ) + { + if ( TQFile::exists( path + "/" + *it ) ) + { + return execAutorun( medium, path, *it ); + } + } + + // When a new medium is mounted the root directory of the medium should + // be checked for the following Autoopen files in order of precedence: + // .autoopen, autoopen + TQStringList autoopen_list; + autoopen_list << ".autoopen" << "autoopen"; + + it = autoopen_list.begin(); + end = autoopen_list.end(); + + for ( ; it!=end; ++it ) + { + if ( TQFile::exists( path + "/" + *it ) ) + { + return execAutoopen( medium, path, *it ); + } + } + + return false; +} + +bool MediaNotifier::execAutorun( const KFileItem &medium, const TQString &path, + const TQString &autorunFile ) +{ + // The desktop environment MUST prompt the user for confirmation + // before automatically starting an application. + TQString mediumType = medium.mimeTypePtr()->name(); + TQString text = i18n( "An autorun file has been found on your '%1'." + " Do you want to execute it?\n" + "Note that executing a file on a medium may compromise" + " your system's security").arg( mediumType ); + TQString caption = i18n( "Autorun - %1" ).arg( medium.url().prettyURL() ); + KGuiItem yes = KStdGuiItem::yes(); + KGuiItem no = KStdGuiItem::no(); + int options = KMessageBox::Notify | KMessageBox::Dangerous; + + int answer = KMessageBox::warningYesNo( 0L, text, caption, yes, no, + TQString::null, options ); + + if ( answer == KMessageBox::Yes ) + { + // When an Autostart file has been detected and the user has + // confirmed its execution the autostart file MUST be executed + // with the current working directory ( CWD ) set to the root + // directory of the medium. + TDEProcess proc; + proc << "sh" << autorunFile; + proc.setWorkingDirectory( path ); + proc.start(); + proc.detach(); + } + + return true; +} + +bool MediaNotifier::execAutoopen( const KFileItem &medium, const TQString &path, + const TQString &autoopenFile ) +{ + // An Autoopen file MUST contain a single relative path that points + // to a non-executable file contained on the medium. [...] + TQFile file( path+"/"+autoopenFile ); + file.open( IO_ReadOnly ); + TQTextStream stream( &file ); + + TQString relative_path = stream.readLine().stripWhiteSpace(); + + // The relative path MUST NOT contain path components that + // refer to a parent directory ( ../ ) + if ( relative_path.startsWith( "/" ) || relative_path.contains( "../" ) ) + { + return false; + } + + // The desktop environment MUST verify that the relative path points + // to a file that is actually located on the medium [...] + TQString resolved_path + = KStandardDirs::realFilePath( path+"/"+relative_path ); + + if ( !resolved_path.startsWith( path ) ) + { + return false; + } + + + TQFile document( resolved_path ); + + // TODO: What about FAT all files are executable... + // If the relative path points to an executable file then the desktop + // environment MUST NOT execute the file. + if ( !document.exists() /*|| TQFileInfo(document).isExecutable()*/ ) + { + return false; + } + + KURL url = medium.url(); + url.addPath( relative_path ); + + // The desktop environment MUST prompt the user for confirmation + // before opening the file. + TQString mediumType = medium.mimeTypePtr()->name(); + TQString filename = url.filename(); + TQString text = i18n( "An autoopen file has been found on your '%1'." + " Do you want to open '%2'?\n" + "Note that opening a file on a medium may compromise" + " your system's security").arg( mediumType ).arg( filename ); + TQString caption = i18n( "Autoopen - %1" ).arg( medium.url().prettyURL() ); + KGuiItem yes = KStdGuiItem::yes(); + KGuiItem no = KStdGuiItem::no(); + int options = KMessageBox::Notify | KMessageBox::Dangerous; + + int answer = KMessageBox::warningYesNo( 0L, text, caption, yes, no, + TQString::null, options ); + + // TODO: Take case of the "UNLESS" part? + // When an Autoopen file has been detected and the user has confirmed + // that the file indicated in the Autoopen file should be opened then + // the file indicated in the Autoopen file MUST be opened in the + // application normally preferred by the user for files of its kind + // UNLESS the user instructed otherwise. + if ( answer == KMessageBox::Yes ) + { + ( void ) new KRun( url ); + } + + return true; +} + +void MediaNotifier::notify( KFileItem &medium ) +{ + kdDebug() << "Notification triggered." << endl; + + NotifierSettings *settings = new NotifierSettings(); + + if ( settings->autoActionForMimetype( medium.mimetype() )==0L ) + { + TQValueList<NotifierAction*> actions + = settings->actionsForMimetype( medium.mimetype() ); + + // If only one action remains, it's the "do nothing" action + // no need to popup in this case. + if ( actions.size()>1 ) + { + NotificationDialog *dialog + = new NotificationDialog( medium, settings ); + dialog->show(); + } + } + else + { + NotifierAction *action = settings->autoActionForMimetype( medium.mimetype() ); + action->execute( medium ); + delete settings; + } +} + +extern "C" +{ + KDE_EXPORT KDEDModule *create_medianotifier(const TQCString &name) + { + TDEGlobal::locale()->insertCatalogue("kay"); + return new MediaNotifier(name); + } +} + +void MediaNotifier::checkFreeDiskSpace() +{ + struct statfs sfs; + long total, avail; + if ( m_freeDialog ) + return; + + if ( statfs( TQFile::encodeName( TQDir::homeDirPath() ), &sfs ) == 0 ) + { + total = sfs.f_blocks; + avail = ( getuid() ? sfs.f_bavail : sfs.f_bfree ); + + if (avail < 0 || total <= 0) + return; // we better do not say anything about it + + int freeperc = static_cast<int>(100 * double(avail) / total); + + if ( freeperc < 5 && KMessageBox::shouldBeShownContinue( "dontagainfreespace" ) ) // free disk space dropped under a limit + { + m_freeDialog= new KDialogBase( + i18n( "Low Disk Space" ), + KDialogBase::Yes | KDialogBase::No, + KDialogBase::Yes, KDialogBase::No, + 0, "warningYesNo", false, true, + i18n( "Start Konqueror" ), KStdGuiItem::cancel()); + + TQString text = i18n( "You are running low on disk space on your home partition (currently %1% free), would you like to " + "run Konqueror to free some disk space and fix the problem?" ).arg( freeperc ); + bool checkboxResult = false; + KMessageBox::createKMessageBox(m_freeDialog, TQMessageBox::Warning, text, TQStringList(), + i18n("Do not ask again"), + &checkboxResult, KMessageBox::Notify | KMessageBox::NoExec); + m_freeDialog->show(); + connect( m_freeDialog, TQT_SIGNAL( yesClicked() ), TQT_SLOT( slotFreeContinue() ) ); + connect( m_freeDialog, TQT_SIGNAL( noClicked() ), TQT_SLOT( slotFreeCancel() ) ); + } + } +} + +void MediaNotifier::slotFreeContinue() +{ + slotFreeFinished( KMessageBox::Continue ); +} + +void MediaNotifier::slotFreeCancel() +{ + slotFreeFinished( KMessageBox::Cancel ); +} + +void MediaNotifier::slotFreeFinished( KMessageBox::ButtonCode res ) +{ + TQCheckBox *checkbox = ::tqqt_cast<TQCheckBox*>( m_freeDialog->child( 0, TQCHECKBOX_OBJECT_NAME_STRING ) ); + if ( checkbox && checkbox->isChecked() ) + KMessageBox::saveDontShowAgainYesNo("dontagainfreespace", res); + m_freeDialog->delayedDestruct(); + m_freeDialog = 0; + + if ( res == KMessageBox::Continue ) // start Konqi + { + ( void ) new KRun( KURL::fromPathOrURL( TQDir::homeDirPath() ) ); + } + else // people don't want to be bothered, at least stop the timer; there's no way to save the dontshowagain entry in this case + m_freeTimer->stop(); +} + +#include "medianotifier.moc" diff --git a/tdeioslave/media/medianotifier/medianotifier.desktop b/tdeioslave/media/medianotifier/medianotifier.desktop new file mode 100644 index 000000000..8cbf6063a --- /dev/null +++ b/tdeioslave/media/medianotifier/medianotifier.desktop @@ -0,0 +1,122 @@ +[Desktop Entry] +Type=Service +ServiceTypes=KDEDModule +X-TDE-ModuleType=Library +X-TDE-Library=medianotifier +X-TDE-FactoryName=medianotifier +X-TDE-Kded-autoload=true +X-TDE-Kded-load-on-demand=false +Name=Media Notifier Daemon +Name[af]=Media Inkennistelling Bediener +Name[ar]=مراقبالتبليغ عن وسائط +Name[be]=Дэман нагадванняў аб носьбітах +Name[bg]=Мултимедиен демон +Name[bn]=মিডিয়া বিজ্ঞপ্তি ডিমন +Name[bs]=Daemon za obavještenja o novim medijima +Name[ca]=Dimoni notificador de suports +Name[cs]=Démon upozorňování na média +Name[csb]=Ùsłëżnota pòwiadomieniô ò zôpisownëch mediach +Name[da]=Mediebekendtgørelsesdæmon +Name[de]=Geräteüberwachung +Name[el]=Δαίμονας ειδοποίησης μέσων +Name[eo]=Media-atentigilo +Name[es]=Demonio de notificaciones de medios +Name[et]=Andmekandjate märguannete deemon +Name[eu]=Euskarrien jakinarazpen daemon-a +Name[fa]=شبح اخطاردهندۀ رسانه +Name[fi]=Mediahuomautin +Name[fr]=Démon de notifications des média +Name[fy]=Medianotifikaasje-daemon +Name[gl]=Demo de Notificacións dos Médios +Name[he]=שירות הודעות מערכת +Name[hr]=Demon obavijesti o medijima +Name[hu]=Lemezfigyelő szolgáltatás +Name[is]=Miðils tilkynningarpúki +Name[it]=Demone notifiche dispositivi +Name[ja]=メディア通知デーモン +Name[ka]=მედიის შემტყობინებელი +Name[kk]=Медиа туралы құлақтандыру қызметі +Name[km]=ដេមិនរបស់ឧបករណ៍ប្រាប់ដំណឹងមេឌៀ +Name[lt]=Media pranešimų tarnyba +Name[nb]=Medievarslingsnisse +Name[nds]=Medien-Narichtendämoon +Name[ne]=मिडिया सूचक डेइमन +Name[nl]=Medianotificatie-daemon +Name[nn]=Mediepåminningsnisse +Name[pa]=ਮੀਡਿਆ ਸੂਚਨਾ ਡੈਮਨ +Name[pl]=Usługa powiadamiania o nośnikach +Name[pt]=Servidor de Notificação de Dispositivos +Name[pt_BR]=Daemon de Notificação de Mídia +Name[ro]=Daemonul de notificare mediu +Name[ru]=Демон уведомлений от подключаемых устройств +Name[sk]=Notifikátor medií +Name[sl]=Demon za obveščanje o nosilcih +Name[sr]=Демон за обавештења о медијумима +Name[sr@Latn]=Demon za obaveštenja o medijumima +Name[sv]=Demon för mediaunderrättelser +Name[th]=เดมอนแจ้งเตือนสำหรับสื่อบันทึก +Name[tr]=CD/USB/Firewire Durum İzleme Sistemi +Name[uk]=Демон сповіщення про носії інформації +Name[uz]=Saqlash uskunalar uchun demon +Name[uz@cyrillic]=Сақлаш ускуналар учун демон +Name[vi]=Trình nền Thông báo Ổ lưu trữ +Name[wa]=Demon di notifiaedje media +Name[zh_CN]=介质通知守护程序 +Name[zh_TW]=媒體通知伺服程式 +Comment=A media plugged notifier +Comment[af]='n Inpropbare media inkennissteller +Comment[ar]=مبلِغ عن إدخال وسائط +Comment[be]=Дэман нагадванняў аб зменах стану носьбітаў +Comment[bg]=Мултимедиен демон за уведомяване при поставяне/включване на ново мултимедийно устройство +Comment[bn]=নতুন মিডিয়া প্রবেশ করলে তা জানায় +Comment[bs]=Obavještenje da je novi uređaj priključen +Comment[ca]=Un notificador de què s'ha introduït un suport +Comment[cs]=Upozorňování na připojená média +Comment[csb]=Wiédzô ò przëłączeniô zôpisownëch mediów +Comment[da]=En opdager af at medier sættes ind +Comment[de]=Benachrichtigt das System über angeschlossene Geräte +Comment[el]=Ένας ειδοποιητής εισαγωγής μέσου +Comment[eo]=Media konekt-atentigilo +Comment[es]=Un notificador de medios empotrable +Comment[et]=Andmekandja ühendamisest märkuandev deemon +Comment[eu]=Euskarri konektatze jakinarazlea +Comment[fa]=یک اخطاردهندۀ وصلشدۀ رسانه +Comment[fi]=Liitetyn median huomautin +Comment[fr]=Notification de connexion de média +Comment[fy]=Meidieling fan oankeppele media +Comment[gl]=Un notificador de meios disponíbeis +Comment[hr]=Priključeno obavještavanje o medijima +Comment[hu]=Lemezérzékelő +Comment[is]=Tilkynnari um tengda miðla +Comment[it]=Notifiche dei dispositivi attaccati +Comment[ja]=メディアの接続を通知します +Comment[ka]=მედიის ჩადგმის შემტყობინებელი +Comment[kk]=Медиа салынған туралы құлақтандыру +Comment[lt]=Perspėjimo apie media prijungimą priedas +Comment[mk]=Известување за приклучен медиум +Comment[nb]=En medievarsler som programtillegg +Comment[nds]=En Deenst för Narichten över tokoppelt Reedschappen +Comment[ne]=मिडिया प्लग गरिएको सूचक +Comment[nl]=Meldingen van aangesloten media +Comment[nn]=Ein medievarslar som programtillegg +Comment[pa]=ਇੱਕ ਮੀਡਿਆ ਪਲੱਗ ਸੂਚਕ +Comment[pl]=Powiadamianie o podłączeniu nośników danych +Comment[pt]=Um notificador ligado aos dispositivos +Comment[pt_BR]=um notificador para mídia que é espetada (plug) +Comment[ro]=Un notificator de adăugare mediu +Comment[ru]=Система обработки уведомлений от подключаемых устройств +Comment[sk]=Notifikátor pripojených médií +Comment[sl]=Obveščanje o vstavljenih/priklopljenih nosilcih +Comment[sr]=Обавештавач о укљученим медијима +Comment[sr@Latn]=Obaveštavač o uključenim medijima +Comment[sv]=Inbäddad mediaunderrättelse +Comment[th]=ตัวแจ้งเตือนการเสียบสื่อบันทึก +Comment[tr]=CD/USB/Firewire durum izleme sistemi +Comment[tt]=Cıhaz totaşılğan buluı turında beldergeç +Comment[uk]=Сповіщення про приєднання носіїв інформації +Comment[uz]=Saqlash uskunalar ulanganida xabar beruvchi +Comment[uz@cyrillic]=Сақлаш ускуналар уланганида хабар берувчи +Comment[vi]=Trình thông báo về các ổ lưu trữ đã kết nối +Comment[wa]=Notifiaedje di medias tchôké dvins +Comment[zh_CN]=介质插入通知器 +Comment[zh_TW]=媒體插入通知程式 diff --git a/tdeioslave/media/medianotifier/medianotifier.h b/tdeioslave/media/medianotifier/medianotifier.h new file mode 100644 index 000000000..9e9a772bb --- /dev/null +++ b/tdeioslave/media/medianotifier/medianotifier.h @@ -0,0 +1,66 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _MEDIANOTIFIER_H_ +#define _MEDIANOTIFIER_H_ + +#include <kdedmodule.h> +#include <tdefileitem.h> +#include <tdeio/job.h> +#include <kmessagebox.h> + +#include <tqstring.h> +#include <tqmap.h> + +class KDialogBase; + +class MediaNotifier: public KDEDModule +{ + Q_OBJECT + K_DCOP + +public: + MediaNotifier( const TQCString &name ); + virtual ~MediaNotifier(); + +k_dcop: + void onMediumChange( const TQString &name, bool allowNotification ); + +private slots: + void slotStatResult( TDEIO::Job *job ); + void checkFreeDiskSpace(); + void slotFreeFinished( KMessageBox::ButtonCode ); + void slotFreeContinue(); + void slotFreeCancel(); + +private: + bool autostart( const KFileItem &medium ); + void notify( KFileItem &medium ); + + bool execAutorun( const KFileItem &medium, const TQString &path, + const TQString &autorunFile ); + bool execAutoopen( const KFileItem &medium, const TQString &path, + const TQString &autoopenFile ); + + TQMap<TDEIO::Job*,bool> m_allowNotificationMap; + TQTimer * m_freeTimer; + KDialogBase * m_freeDialog; +}; +#endif + diff --git a/tdeioslave/media/medianotifier/notificationdialog.cpp b/tdeioslave/media/medianotifier/notificationdialog.cpp new file mode 100644 index 000000000..c74228198 --- /dev/null +++ b/tdeioslave/media/medianotifier/notificationdialog.cpp @@ -0,0 +1,147 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "notificationdialog.h" +#include <tqlayout.h> + +#include <krun.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <tdeio/global.h> +#include <klistbox.h> +#include <tqlabel.h> +#include <tqcheckbox.h> +#include <tqpushbutton.h> + +#include "actionlistboxitem.h" +#include "notificationdialogview.h" + +NotificationDialog::NotificationDialog( KFileItem medium, NotifierSettings *settings, + TQWidget* parent, const char* name ) + : KDialogBase( parent, name, false, i18n( "Medium Detected" ), Ok|Cancel|User1, Ok, true), + m_medium(medium), m_settings( settings ) +{ + setCaption( TDEIO::decodeFileName(m_medium.name()) ); + clearWState( WState_Polished ); + + TQWidget *page = new TQWidget( this ); + setMainWidget(page); + TQVBoxLayout *topLayout = new TQVBoxLayout( page, 0, spacingHint() ); + + m_view = new NotificationDialogView( page ); + + topLayout->addWidget(m_view); + m_view->iconLabel->setPixmap( m_medium.pixmap(64) ); + m_view->mimetypeLabel->setText( i18n( "<b>Medium type:</b>" ) + " " + + m_medium.mimeTypePtr()->comment() ); + + updateActionsListBox(); + + resize( TQSize(400,400).expandedTo( minimumSizeHint() ) ); + + + m_actionWatcher = new KDirWatch(); + TQString services_dir + = locateLocal( "data", "konqueror/servicemenus", true ); + m_actionWatcher->addDir( services_dir ); + + setButtonText( User1, i18n("Configure...") ); + + connect( m_actionWatcher, TQT_SIGNAL( dirty( const TQString & ) ), + this, TQT_SLOT( slotActionsChanged( const TQString & ) ) ); + connect( this , TQT_SIGNAL( okClicked() ), + this, TQT_SLOT( slotOk() ) ); + connect( this, TQT_SIGNAL( user1Clicked() ), + this, TQT_SLOT( slotConfigure() ) ); + connect( m_view->actionsList, TQT_SIGNAL( doubleClicked ( TQListBoxItem*, const TQPoint & ) ), + this, TQT_SLOT( slotOk() ) ); + + connect( this, TQT_SIGNAL( finished() ), + this, TQT_SLOT( delayedDestruct() ) ); + + m_actionWatcher->startScan(); + TQPushButton * btn = actionButton( Ok ); + btn->setFocus(); +} + +NotificationDialog::~NotificationDialog() +{ + delete m_actionWatcher; + delete m_settings; +} + +void NotificationDialog::updateActionsListBox() +{ + m_view->actionsList->clear(); + + TQValueList<NotifierAction*> actions + = m_settings->actionsForMimetype( m_medium.mimetype() ); + + TQValueList<NotifierAction*>::iterator it = actions.begin(); + TQValueList<NotifierAction*>::iterator end = actions.end(); + + for ( ; it!=end; ++it ) + { + new ActionListBoxItem( *it, m_medium.mimetype(), + m_view->actionsList ); + } + + m_view->actionsList->setSelected( 0, true ); +} + + +void NotificationDialog::slotActionsChanged(const TQString &/*dir*/) +{ + m_settings->reload(); + updateActionsListBox(); +} + +void NotificationDialog::slotOk() +{ + TQListBoxItem *item = m_view->actionsList->selectedItem(); + + if ( item != 0L ) + { + ActionListBoxItem *action_item + = static_cast<ActionListBoxItem*>( item ); + NotifierAction *action = action_item->action(); + + launchAction( action ); + } +} + +void NotificationDialog::launchAction( NotifierAction *action ) +{ + if ( m_view->autoActionCheck->isChecked() ) + { + m_settings->setAutoAction( m_medium.mimetype(), action ); + m_settings->save(); + } + + action->execute(m_medium); + + TQDialog::accept(); +} + +void NotificationDialog::slotConfigure() +{ + KRun::runCommand("tdecmshell media"); +} + +#include "notificationdialog.moc" diff --git a/tdeioslave/media/medianotifier/notificationdialog.h b/tdeioslave/media/medianotifier/notificationdialog.h new file mode 100644 index 000000000..01792c2a5 --- /dev/null +++ b/tdeioslave/media/medianotifier/notificationdialog.h @@ -0,0 +1,56 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _NOTIFICATIONDIALOG_H_ +#define _NOTIFICATIONDIALOG_H_ + +#include <kdialogbase.h> +#include <klistbox.h> +#include <kdirwatch.h> +#include <tdefileitem.h> + +#include "notifiersettings.h" +#include "notifieraction.h" +#include "notificationdialogview.h" + +class NotificationDialog : public KDialogBase +{ + Q_OBJECT + +public: + NotificationDialog( KFileItem medium, NotifierSettings *settings, + TQWidget* parent = 0, const char* name = 0 ); + ~NotificationDialog(); + +private slots: + void slotOk(); + void slotConfigure(); + void slotActionsChanged(const TQString& dir); + +private: + void launchAction( NotifierAction *action ); + void updateActionsListBox(); + + KFileItem m_medium; + NotifierSettings *m_settings; + KDirWatch * m_actionWatcher; + NotificationDialogView *m_view; +}; + +#endif diff --git a/tdeioslave/media/medianotifier/notificationdialogview.ui b/tdeioslave/media/medianotifier/notificationdialogview.ui new file mode 100644 index 000000000..f7bd744be --- /dev/null +++ b/tdeioslave/media/medianotifier/notificationdialogview.ui @@ -0,0 +1,117 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>NotificationDialogView</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>NotificationDialogView</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>508</width> + <height>480</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>15</number> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>20</number> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>iconLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>64</width> + <height>64</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>64</width> + <height>64</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>A new medium has been detected.<br><b>What do you want to do?</b></string> + </property> + <property name="textFormat"> + <enum>RichText</enum> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>mimetypeLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <widget class="KListBox"> + <property name="name"> + <cstring>actionsList</cstring> + </property> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>autoActionCheck</cstring> + </property> + <property name="text"> + <string>&Always do this for this type of media</string> + </property> + </widget> + </vbox> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="55092">789cccbd47b7eb38b2ef397f9fa2d6e5ecae5e7cf266d0035266cb6da7ed77af1ed07b2f1aa9bf7c83883f704c56d5cd7c75bb5f95d6c9ca5f8a22114044202200f0fccffffcdbe7d3fddffef37ffe8fea625c02eb6f966f947ffb4fbb4e92ebfff57fff9fffcffff88fe160f0b7fecf68389bfe6df41fffc7fff80febf96fd6df9401ff5fcff64232ffde36244f7a762ac953fefd56f29cf35cf2a267f3072ff9f733c906e7836493f35eb2c59fd74ab6797b1f243bfcfb46b2cb7fef0a1e72799c5af2907f7f94cce5732cc963fefd483297cf3a8387d43f992999ffde0c25f3dfb79a64de5f662099dfcfe924cf386f24f3fe4a44ff0fd17e5b327f9e772799dfcfb8078fa87d662499cbebbb9249de6fc9bcbd9d2f99dab795ccc7b31a48e6e3b71a4ae6e315ed25f3f1b04f82a93f0dc1636a9ff32999daf32599f757a54ae6fde17e48e6fae23892b97e78a2bd63ea1f438cef849e97e892f9f7652b99b76f3d91cce53763f0947e6f08fd9c1137b664de5e43c83fc7f53bf0022cf475499c8be719c4f113d824de5cc01671fd0eb6895dbaff50d8ab174ae6f2ad3ac9a47f63c924df4832d73f732a99f777f324998fb73993ccfb5f7f96ccc7df3a49e6e3514592b9bd3aa664ae1fd6bd646eaf9a2b98f4ddf52573fdb58e60d89f6d49e6df9b13c97c3c1d45326fbf634826ffb2934cfee40086fdf88164de7ff65232d9eb9b646e1fa607867e9bbe641a8f816092cf14f2423f4d070c7d8b9f25f3e7bbaf60e89fb791ccfb3b15df43ffe22f30f42f13f240ffea1b18fab716bf877ee967b043dc92bf1f0ea16fdd9af3a8f740bc3dbe64f2f70bc9bcbfcd2fc9bcbfbd4432f90b4730f5cff55e3297bfc9c0187f732899f4772099c6e35b321f7f6b0fc6f8daa6649aff7692f9f3724d32d7f7cb4932ef6ffb4e32e9b302c6f86723c9dcdefc50326f9ff32e99f7975382a10fd75c32d7e795906742fdd3bd49e6df67a2bdd09ff20886beb89164fefcd54932ef9ffa2c98fca72bda0b7d6a9f25f3feb0c4f842bf9a07b0d02fd13fd0afe2090cffd6c660e85b24ae87be05a40f63e1df8277c9bc7debab643e5e575732efef6e2799cb1bfcf89ecbdbed2573fd5cfd781e1fcf952d98fa3b91cf277f74cd24f3fe0f3ec08807ba8d64ae9fc54232e98f27993faff9f13df787ae680ff4d57995cce57103c95c7fac3bc97c7c7c5f308d67b8028bf9f72299cbd3dc49e6f2981f92797fd69664de5f7e2499dbb33b92ccdb6f2dc1d067772099fca72e99b7ff6a49a6f946f437f4b9bd48267934b0d0ef77c9bc7dad68df9cee9fee25f3fe69447fcc31df88f1843eaf6e92f9f3da89649a0fee25f3f1cb85be41ff0331bed07f5f8ca7f0a7d43f13a1df9d2a99f777f32899dfffea80111faeae92b93cee41f090f7effa0c463ce77f48a6f9ee51321fafeb4930f547bb01433fecb164fe7cff5b321f2f2f92ccfb3f93d793bd745b30f421ae2593bfd94be6fd1b2692b93cde4e32b79fda164ced8ddec1d017e74332f9dbb564de5e772899e299140c7dcaa692b93db8df92797fe61d18fe3117e303fd59b792e979b164de3f8918ff05f5cf46f40ff4c715e301fdb9bd80e13f57f792797fad4a30fce906bf17f3f51ae331c4fc19a13d43f89780e693a9f0a7ed028cebfd4e321fafe6198c7cc00b2473f9bc77c95cdf4a4ff0908fc75a5c8f78bfb52553fcf02999ebbfdf08a6f10e5ec1c2bfdc49a6f97c2b99e6ff27c9642f3fbee7fab416f2407fc299643efe912f99ec692099cbd3b492b9bc9ab8ff94c63711fd0bfdb2a792c93e2ac9140f689229df5125f3feed5660e85ffd2a99fce34432efdfee00867e5e14c9941f8ec0d0bfcc904cf9572a99b7a76e25f3fe73c760a1afaa646ebf99e85fe86f2ec61bfaea0b79e11f0ba12f2eda8bfb4b7d267b98897c64dd81a1cfeb503297afbd934cf1d45e30fc93f81ef363b896ccefbf3a4a26793dc1149fae7d30f247ff2a99ea1d3fbee7fed68b05a31eb1924cf9c2083ca5f6076bc9542fd948e6fa900e2473fdbbbc09463d630246be1a6692f9f84481643edef95532b73f5df01cfd7993ccdb7be92453beb5924cf3c14432efbf5cfc7e01fffa2999e6bfb1646e5f9b022ce2cba364de3e37114cfec132c0d047f74d32f9e37b30f26b2f05431f5763c9bc7f42c1d04797e6cf99d0c71be41fc21fa52a18fe24207d9f0bfd5a1d04d3f8570fe009d573dca3642e7fbb054f697ca237c1246f3a944cf53a5b32c5a72f60f81bd796ccaf4f2bc994af2d2593be6f2453bea682e7345eed4e32d5ff14c9bcbf2f57c95cff7dd15ef8a35097ccdb93cd25537e2bfa6b3124fffd055ec2bfcc24537c548045fe518331decda7647ebd2eda6ba37fc478c01f6d44ffb8d43e1ded17e3af3960cc97f5022cf481e257a6dd149fd96bf08cc6ffe64aa6f92604c35eec4032b7efab2799e2375b30e94b2aae5f50ff58aa642e6fe148a67ce1065e927fb80d2553bd2494cc9fdf3e49a6fc45c863c07e1dc97cfcd3a3606a5f7d05633e887682497faf4bb08df8e2030cfb2bc9de17a2ff4bf49f886762f4cf10f666bd80618f3e8dff92f5177f5e914be6ed2f36e005c91b5f24533cf22598ecafeec04be467ae64f28757b041bfaf5f040f29fe68c0268d9726da63917e14a2bdd0c7f424998f5f44fdb314fd91bf83a18f8105467fdc4660e86783e789fee94a30e215e3118c78a3a0f9dc60fd45fa34072f491fc329d8a0f685a964aae7dfc0265d5f2f05537f568f60d86bb091ccfbe36248e6fad988dfbba85f8e24533e48f66f88fe892b30fa67634ba6f97508467f6d1cb0a827435ed11f35fa6388f9c9a7f8c814f157fd065e92fe5f6e6083e42f5cb0897ac417d8227dca3fc036f55fb305431fba77c1747f3b02bba4df3ad9ab29e42f669229df46fb647fe460d8d3aa0243fecd2758d4bbefc0a21eb403a33f2a8a772c263f6fff35055ba827d1f85aa2bf2f1a58f4f70a8cfb252a18febdf1c0f02701f58f2dda7f5d48a6fe9b8071fff21d2cfc83603caf51c1b87fb106433f4b1a1f87fd17eebf1b17ec903efbd43e46b0f71a0c79cb2d58c4e72d18cf2f1bb078be0dc6f3339abf5cd11f8906c6f5de1a8cf846e3f6c1cbe724df068cf6548964ae3f1b130c7f9096608c7f7603a3bde90e8ce7bb2f60b4d77e00c39f075c9f98f639e47fa34832d7e7f84c2c9eb7ba80216ffb08c6f3cc042cd64f1a30e42f9760d88fe382d19e1ced19c11e42aebf0cf17cd306435ecb04a33d610e16f20b16f1470a16ed3981457cf9443c82bdae2660e19f79bc341c8be7d70e18cfd71ec022df8ac178feaa05e379d72bf108e3df70ff369cc8fe1d8345bc9c81d1fe60452cfaeb7a03c3be74ba7e2adbd382f1fbcb3b18e3910dc1689f4df24e657fd4603cafb2c168bffb0cc6f32b1ebf0c67e2fe01e9d34cdcef1283e12faa6f30ee67f860e1ffe660a1efdc7f0ee7e2fed58c58b6e70cc6ef8d002cd6173db0a83f2dc0d0b78edbf77021e5bd078bf6aec1f87d41fabd14f2155bb0f8fd108cdfeb2330da93de83f1fc8ac6d310f2ac1a309ed772ff3734c5fdb48d64ee0fb72e58d4e75ec0f87d7202a33f0d713df4a5237bb7e4782a60b11ee681d15eed112cee1782a1cf158f4f86b6b8bf6581c5fa2af5a733823f762d30eed7d2efdd11f2efcd1d18d76bdc5e468311f2a3c007e379f5082cea75f760e8fbfa8d782cf49dfba3d150fcbebc030b7bdc83a17f099faf472371ffe64c2ceed73460e883cefb6b3416f7ab4fc463e10f2c30e46b8927e279b94b2cee6f6cc1d087ec092cec4930c6f342f24f85fc46442caef75660e8cf85fb93d18cfd9ec783f1162ceaa37cfe19cdc5fd3ceabfb990d79d80d13eeb152cd64fe9fa85f8de7c05a33df9188cf66cbec0d0c7f50d0c7df3b8ff1f2d85bcce002ce227078ceb1d0f2cfca54e3c41fb6f74bd21ef5780f17c5d058bf53beeaf46e618ebd77a2299c77f5bba9f25c6b7f4c1c2bfbd80d19eeb07f104fda1933cb678de2603e37eba01c6ef6f57b0a8ff71ff3d72c6a8b7e8d47faee88fb507c6effd188cdf3bdc1ec67d38c739e2e3c5a63393e21723269e60fde4f22c99d677b93e307577285eb7b8fd8f27ecfe9cf50e0c7d8a79ff8ca7ec7bfefb6b412cc627db81c57e823730ead9eb1158d43fb8bce399b8fe7a0716eb5d7330c663c3fb733c67eda1fa484d2cc6c39a83a11fed193ca57a651282b13e16f3f96ebc9860bdc8d880c5fe810c2cf21bae8fe3e544d4cb23c93c5ed30a30ea071b170cff92d0f81813d443d71730eaed9a07c6f53eb7b7b1c9bee7fa117c49a6f5024b30c5b3760cb6b19ec9e3adb13331e8face93ccfbaf3883f13c23013ba8a72e05d3fd0d1b8c7c734df23b53d8df86facf9da03e7e1b80f1fc82f7e76430813e6d63e229fa3be5e333194e4cd40b52b04ded31b8fe4e4653110ff2fa0a73a736f28d9a788afd67fa180cfd6a1db0588fe3fe7f32610accfb77c3f59721f2c77c493cc5fe0aaf00e37eb731788afa4e059ed1f8361f60d48f6dde1f93d914ebc7460a46bd2fe4fd37994fc7940f6cbec1e89f98cf5f93a578def5013c433d86da6f4c51bf09b9bd4dcce982f2b39cebcbc49a22fff6b83e4dec29ea15d95932adb704c433acffebf43c776ad1fd039d7886f5d315bf3f5356f09acf77d3d1d4a5fa65734f3cc3fe035d134cf7372c30ec355b824dc413dc3fb0e9906574dcdf79c4e2f74501c6fa5b74104cdfb73c3e9d4ea6d6887f7fdb10b3e791bef1f9940ddf1ceb078fe005f5b7c5e7e3e96c86f58f8d0246fd3a76c1f311f9b377b043e31bf07c693a9fa1de19df816dec07f804bb584fa3fe5accc47a86069e517b82002cd6f775b043f39bc6e3dde9923d8eeb7332035bd47f3705ec60ff824d3cc7fecf84ebefd498c19e2faf609bfa2be6f9f0d49c2d51cff5c016e5fb2b176c8f78fb8b15d8a5fa99c9e7d7a93543fdab1b831dfafde6287844f5d10e8cf1af49bfac39c63bff024f499e98ee6fb3fb937f7d023bd4fed407bb435aafb124d37e2d5d30b53f03cf87d43eeb0d8cf5dd7803c67cb7e1f63d75587f707df1e9fece7c30a2fd5d7b30f6b3469f9269fdc792cce5594dc1587fba52ffb84c1edebecd5e326f7f41faebceb19f2cda8271bfa6133ca2e727e0118d4fb2164cfa9c2892f978af4c30eca1f1c19321d7bf2bff7e3660e34ff5e53bb043cfaf5dc174bf6c0076a97fdb929805acfcfb6d0446bdbee4ed9f0d857eddd660f89b6e2298da5f05c4ac3f687e6bc0c311ad87e07a263f9f0fda77f094da537f8067245fc5f569369a1963d29f2b31eb5fdabfe20ba6e7a777e0d188ff3eb9815906c29fa78227d04f053ca3f6b65c3f6663260fd553a93d2cfca4fec91bc95cfeea041e517f5fb8fece2662fcdd023c86ff33c1d31167cd06cf21cf5c308d679d8017d41f0df72fb3e9cc1ef3ebab14ec8c69bfc05432ed47d38885fe5d4cc9b4fe37028fc8fecb37c9649f25784cf6ebbf82e7f47dbc042fe87e05f5cf4ce8936b82e7f4fb36113ca6f17a002fe8f986b8de80fe8bef4dd28fc292cce52fa68269fc4d1effb0db2f49decd0c0c7fdc92fe2ce6131a3f6d2d98fcb7bf02cf49bf370330d68fea5a30fdde38831dfabea3fe59b2fea178b0009bd41e4f03db23aeff37713decb5f00593fc2df5a7c1ee47eb6f2330eadd17156c8ea87ff7609bfc45590b267f78d5c02e714bfa6ab2f1207ff80136c87ef22918f34dfe06c67cd186c48b018dafcee3cd99c5ee47faa48217647f99609bf4c7a0f1b2160392afa3f6da6cfc68bcd69279ff949f6093daef4ec1f067f5817831a4e76de8f70ebb9ece177c806d6abfb3235ec0dfba2bc9b4df9bc6d7ed1376ae5f5c3fe703263f6f4f520a1e53fc99102f66d4be8cf7cf7cc8e4e3d7673e784c7cdd82a7d4de5a03c3fe751e9f3265c2fca09be009d94fc2e397394b87c99f186bf08cfa4fe3fd3b9fb0e7717dacc792e97c0b8f5f58f8bb20d6793d613e5f2cc7b49fc5005bd49e35b56fb1c4fcecf1fe9e2fd9f7743dfdde582ca83f8267b049ed59f3f9686eb2eb69fd782699d62fa83de67244f67de1fa3eb79643b237ef2698f4ab9e8347d4feb0008fc99e1c6a8fbd70d05f4762261e6f9f46e3e730a6f3160618fdbbe6f9c6dc5d0ea8bd0df5bf6b88f89aebdfa25f00a5f8ff4e32edd749c0636aff66019ee17939780e7de2f92a73f643e8bb031e537b7c133c237bf5dec073ba7f44f71f1a225ea3e78f447f79dfe011ddcfe3f22dc68c29feff06e379ba0e9ed2ef0b1effb1747d44f3b1fd0d5ed2f78d0236c65cdf367c7e5fb0009858bf07cfd15f7bf082f4a3492473f96f19d8257b6df8f82e66cb05f55fbe223630ff6f797cbc98b3f67079527afe82319d17e1f6b7581a03fafdc693ccc7d7a0fb194b97da7bbb111b63f2af1bae9f0bd31810eb7cbd61612d1dd2bf94da671943c8cfe7af856d8c69be6e0563be594f2573fdd7b8bd2c1c763ded0f53c01392c7bb4ae6fdd3717d5db8c684fa4bbb134cdfa767f094e28180fba3e5c080fff15fc0b309f5ef9764d24ff13dfc43cae7a3e5d0807d6cf8782d47acbdfcfeed0b783ea1fad50ebca0ef6f3ed82079a32f30f2c5644f6c627f5acce7df655fd0e1e3930460a662dc3f1cc14beaaf40133ca178a8069bf47cdf90ccc74ff3c10e8de78dfa676c8afd09b564daff5982b1ff36a6f64c58ffd2fed40b7836a1fac504bc9c50fd6101c6fc97abc426e2b3700fc67911f3018cf33ac99d643e1edd198cf3176e07463da4fa0063bf8826be47bd53e7fe773965e345fded806db217eb1d8c78f29612b3f6923ea9603cbffb0663bf4949d7b38083c663b3022f68fceb7bb043f6118682a9ff8c02ec92bfcbe9fe7dba49f5c30d18fb636c9e2f2ce7ecf7144f2a6097e4bbe5c4ecf7140fcdc0b0b734018bfde03a784af3c53504cfb15f47dc0ffb0bbb8160ecbffc002fa95e58edc1d8bf1a4dc1163d2f36c1a8575495609c5f1a4aa6f3a134febd83e2ed2f376093faafa3e72fcc01f1f50b3c217ddd5660ac37ad63f00cfe5407cf69beef5230ea35c6026c60bfe55532e55b39d8a4eb6f73b0d8df20ee6f637fe04a32cdff03b043fd757b904cf9d9168c7ae7ed2299ce7b3692697fc898d8c2f99ddb128cf3b317f49f85fa6348f75f1a06d9afb604c37ff817b04dfa1c0ec10ee9bb4ef22ecd015d7fdd8047345eb5079e907e598e60d2d7b40363ffe3762598e2d5750e16e703d692297ffc128cf35768af897afb36108cfaee5c32d56b0f9269fe2e24f3f61731d880ff5125d37ed80558ac974c25d37ec09d64de7fe64132f73fea27d8a2f15732c9b4bea008a6f655a23fb1dfb28c24d3fe470d8c7ae1ed5132e95b2099cf8fa6e82fd4e3c32fc9b4bee3125b38ef7723ff641816d99b7d03dbe48fc22bd8a1f9f95a825d9adf4af28706eb1ede5eaf060fe97aaf133ca1fc5605237e6d8ee009e5bbd5198cf58b4efc1efb6fb71730f67bae66e025c5df8a09c6fecae020998fafd248a6f3ba909fd93b6f4f71025bb0af52329ddf9849e6cf533fc036e993924ba6f96726993f2fcec00ef57ff12e99e2c34a32ed7f0cc1f017d5bb649aef7cc9bc3f22f13c97fa4fc3f859388f5a6d25f3f69443c1d86f3b06e37c4be54ae6edd354c9bc7dd791643aefdc4aa67acf2b18e7f134f13dced325a4ef26d3379affc95f9826e2cb952a99c6f7153ca57835fd0463ff691108267fb579028b78c2001b34dee14532bf7f62814df88b4832d52f2ab085f59d0118eba3752899ecff2699eae307c9b43fb405431f9454329d2fbb97ccdb938cc02ee95b2adaebd2f8b590dfc279e448974ce3f12998e67b4d30ce074713c934ff403e0be72d2dba9fc5e607defeca014fc85f5413f094e2313b954cfea0114cfe467901233fd41792a99e6a49a6f527c198afd71bc9549fb9822dea8fba944cf9502799dad782b17e6d7592c9be6782495fea42321fdff8c7f77cbcb477b043fa1deb9229ff4904e37cc697641a7f0decd27828aa647abfc45032ade7b982495f13b25fcbc2fb0c944032d9cb93606abf5949a6f314cf60bc4fc00a24f3f6b79960d29f5a914cf11dfa53d87bf82999d6df303e16ceb755a4cf369b3fc8ff7660ec3f57de04933ff0f760ac5f665bc114df2b67c1a44f57156c507f5f1cc9b49ff3198cfdc69bab60aac7ac4f601be7fd22c1781fc95132ddaf95ccdbabd492b93e794f60e883229e87fd9ef959326fbf3a964cf9e00318fe5d9d4be6fda192fed916ce83a92f92a93dbe64ca8fd11f229e4c6f92f9f3938164ca1f4f82b1fe994ae6df871f60acf79a6bc9bc7f62f49785f3b1b75230d95775914cf30bfacfc279b22df90f47c413a621995f9f7be011f99b6d2b98e2136d021e4f683d63059e4cb83e7ae2fa19dd4f3b83e734df943118f581f22099cba33c8397549f592dc026d69b8f9279fb6f9f60e453d6156c537f5a63c9644f8160aa47695330fc8dee0aa6e7c5b964f28791648a6fe692297e580aa6fa6628da8bf8c3bc974cf9642118fa38954cf58f89649acf1692e93c27e9936361ffbdd149e6df2b9e609c1f7d96ccf549ad24d37974e887d0676721998f8fba924cf1fa9364b247713df687754f92e9fc672399ea45a23d581f35af92f9f7b9f81eef13885ac1181f4b32d5dfa10f16f6a3044bc974dee9158cfd3f892399fcbb2d993fff26fa6786fd3ba23f711ef146d7bbcc7e283f7b944ce7995ec0639aafab25784af671db0a9e52feb200cfc9fe320f2cec650f5e52beae7d49a6f319e2fe4bd457766083f453bf80b11fa878154cf6b2adc1585f37c4fde0af235530f251717fc45b9e90d7c17ca848a67add5530ad1f74a160aa8f76e279c8e7c34630f97f3b174cf2379a645abf247fe35a781f90ff2818f3c1443297571d49a67cfd4930cd87da1b58e8ff5630ece74b32cd1fa564aaef7982697dc87900633f73694ae6faa0be4aa6fd789a648aa724637fd25a32ed3f79924ceb3d3330f6f325ad64de1fd98364927f2598facbd42553fd3594ccafcf311e16cecbdf22c95c5e652a99de7f267e8ff3c9e1bb641a6f4732bf3efb008bfd812f92297eb32473794b31bec87fa30a2ccea3ee0493ff30f79269bfe23718f53e6b2099ea0377609c7f34be2453fc7b914cf91c1f2f63c0e6478a0fb6e019d58be207c1538aff8fe039e503712b99e6eb5c3297a750c04b1afff22618fb1922c1347fc73bc9b47f4630f2f9eda360b2efab2e98fcd1ea158cfd83452598f47f6b48e6cf8feec1a8b7a40bc1f05f3bc9bcffb61918f596f85d32d5e3447fbaa48ff94030f6ffdc24737bf267c416f6a7ac3f2453fe580bc67e99122cceeb9c24533d6b2299f4ad108cfce30773fd500cc9341f7792a9fe6b0ba6f5da6b2399ce372ec1d85f1d9d25f3efd59b60f89f3bc9bc3fd4a364f22f6f60ec97543792797fa8a960d8c74d32f9932918f61ed49269ff832d99e44d24f3f61a23c1d43f96fc1ef1fe1c8cf763448e645a3f16cfc3fe3d632899e2955832cdafd01f0be7d5ad4a32ad9f3792b9fcc64030ced3d792b93e9723c9b41feb02c6fe67732b99f68b7c4aa6faa3180f9c17f6499ffa032dc46bf098ec5d8f24d3fe08133ca1f530ed049e527eb7f50593ffb83c48a6fd570a7846f7d36b30e6fff25b32d5ab73c1145f28ef82299ed1e660d473b64f92a9def92698fcdd5a3cdf46fd24914cfbcd74c9b43e21e445fda611f7437cb1fe124cf65edcc02edd3f7225d3fb001e05d3fc5ebd108b7879bb93ccfbc72f05937e66a9605abf538e92493f56e021d99f6249a6fa5b2b98fc9f72914cedc3785a789f52f12698e42943c964ef17c9e40fe792697e1849e6f2648e60ac470660bc9f243b4aa6fd3fa1647ebda20826f9d24c32ef0ff55e32d5d7447f60fe2f9f25933f5a4aa6f8e62c18f9502299f40ffa61e1fd4b4a2899f6279492495ed19e29e297028cf795048d64dedef05530e29137c9e47fe4efb19f740cc6fed152134ced0f55c9fcfb488c17dedf74b9934cf64dfa3c326754ffab0cc1643f510ac67a78ba04633e77466083ecb309c026cdffa921998f476582b19fa7ba0aa6f93e5e0ba6fca6188051bf4b447bb1bf4aff00237ff60f92e9fd41f792e9bc7d2599e6f717c1d8cf247e8f7a5d160ba6fecf23c1b4bf21a0f86264e13c72f82499f2fd57c1f06727c954bfcec098df755b30d9ef7a2e98ecdf78974cf54cb447d47b3d5330e2cb0fc9b4df47dc0ffbd12ea9647a9fec1e2cde07f92e99f60b1c05239e3e4ba6f9df974cf9d74932ed9ffff17b2e5f70014f90ef288261df8664b25f5332bd6f0ae36be1fc4ef92499f22d4b3297ff593c0fefb7525dc9e4df3c30de5fa53a9229feb12553bc2ec66f46f2565f92c97f37609ca7b4df25d37e825a32adff89fba39eaafb92293fea24f3ebb7627cb13ebbfd944cfbadbf2453fe37154cf287a664d257d15e715e80fa6fcce673f2af117846f94076075e503d2188c1d88f9a9b82c91f2457c954cf38832df2279ba9647adfe70a8cfaecf62098e2ef6e2699ce27ed04533cb2d5c0d8efaa3c09a6fa46f12199ec5d3c0feba51dcd9f63517f5dbd0886bd3f4be6d76f7f30d59b62c164afde5432d5271f2453bdf0118c7abd77124ced4f1ac914afae2553bd5edc0ff3b9f32498ec6d1308a6f66c55c9341fdd83313f9ba23da8ef46a564dabf664aa6fd21f27b8a37e291643abfe249a6f9ce174cfb13a2028cf78b25b9647a1fd4a364f20fdf92c97f0c25d37a512599d607a03f22bf375ac994ffa49229ff78944cf94a2618fe48fe1ef59e4632bd3f270163becf2ac994bf8beb71fe4b0d2453bd27964cf552d13fa807da2f9269ff612499e627d13ed40f424330b55f13d763bfc6ed4332c50f37c1f0f78a64daff3d964cfb43c578637daf7a138cfd39429f719e6745fa30314df21f590ec6fedd32134cfbb10c5d30f98bcb8b64da2f3c01dbd87fbc174cf5c92001e37c4d25eee760fff1b7605a0fc8b792e9fc81b8bf43f149740263ff68fe2a989eb722fb9c8878201849a6f75f9e25d3f37cc974fee15532bdaf752898ecdd0904d37a475080512faf7e30e9432e18e7f56e82914f5482c91e0bf13ce4ff7e2698c627fb924cebcfe2f7d8ff1b3e80719eaa934cfaee3992491e717ff80f6f2699f22ff13dcecfa753c9e4bf0e92293f394aa6fd139660b2cfc8904cf9df4230e68b4a32add78bf1c0feda740ec6fbebcab3648a8f2792c95fd492299e1848a67ccd164cf25b2d58f887ab64f2379d64de3fea4132bd6f4efc7e8e7827944cfb7f1e2553bd4f134cfa6c799269ffb6781eea8df14432b57f2718ebe591645a2f8b05231f15bfc77e0f652699e229f13cbc7faa9a4ba6f361427fb03f5013fa8cf5e2c495ccbfd73dc924af180fec0fd33e24737922f17c9c6f6cc91ea626f69b5e13f082fccfe64d32d547bfc0385f565ec0886fba1cecd07a663394ccfb237b05633d627b144cf6779949a6f75fd682c93f06349f4dc5fa433d154cfaace982697d721b4aa6f3c11918f585742299fce5bd64aa67958229be5ac560ac27ac12c178bfd79b64da0ff1e37b7adf95fc3dcef70592a95ebb174cfe3a10cf47fda01c08c67e1b5f32bdcfb0134cfde12a92493ed17f585fc81f25d378dc49a6f8e253308d57249e3f417c7a904cfbcd7e30c5d382b11e982592797f24df82b1de954ba67aa6907f4af69baec138af6c8d24533d692f99ea733bc1e4ff3c0b2cde37be944cfe712499f2b1b964b2675732c52bd0670bfb45d54832e58fba64da0fb301e3fd8d4a2499d67f857ee0fc72f82d99be5f81713e3e194aa6fd49e27e588fb89ec1884fae13c9d4ffa27fb0bff0229e67537fae481f66e612fb2d776083ec3debc026eaa53618f18a3b0323fe580f04d3f5c98b64da7f63825df217852e99ce77907c33113f6c4dc134df6f1f24d37c9982b17ee04f05537b9a77c9148f88dfa3deb07a92ccfb7f73168cf365778229be48bf25537d19f28bf501e55e309d4fc94f92c97fcec158cf2b12c1e41fbb4fc9b43e3d104cf3f7f6158cf87ebb170cffe448267942c1e47fba05187f1f455049a6f5614330f4ff0d8cf3b88ab83fde3770d94ba6fafc12bca0f6a557c1c80f6dc9644fb964aa7f1492a99eb1934cf3f718bc44fd632199f2ab67c914bfd782518f16e389f78346a23dd8bfa58c25d379ba4030c95b5f2453fc5c824deacfec2299f6eb6c25d37ae74630e2b94632ad170bf9b13fb87b964cf514713df61bd4aa643a9f0f7bb31cecbf10fa28f6e3f89269bd83e2adb9399f52bd33032fa6fcfef9086cd07e8d95f81eeb1b97a964b2bf0dd8a2f958ff02dbb41fbbbb825d9a3f2eb5608a3fe28560caafb6141fcd45fdb11a83b11e180f05d37e5c5f114cfe669d8051ef6f3dc1a40fab108cf3d9e55a30ce3b1a60d4d78bab649a5fe5f7645f978364dededbb360f247452899ea616730d6e7d6779269fdfb4330f9bbd4148cf8e7058cf5b8e44932bdffe25e30f6835c24d3f9d1b964b27f713decdd16ed9b937fd2f792a99ed2082679a247b0380f33964cf3ab18af05c52f57d1df381f5baf2453bcff0046fcacfe60daaf6a4aa6f9ed4b30ce7fce25d3fedd1918f65f8af1c37e6d4f954cf9cf5a32c927fa17fbede254326faf22aec77c1bd582a9fd971d58ecef3524d3fe5ea1bfd84f97d1f82ec47a83be124cf5c8ca07dba4efbab8de9df2dffba44f0b51afeb5cc1747d32154cf61eecc043ccf74f9269ffd3098cf7495c1e25d3f9c14a30ad9f281f92693de2001ee3bcf34430e94f71114cfe259883f17ef6b52599de2f36144cfaa23c4aa6fafd188cfa79d60a267de832c1345f1786649a3f7e30cd97a2bdc86ff55232c54fb9648a6fc4f367e44fbaa1649a5f669269ffb7f87e4ef6915f2453beaf4ba6f9443c1feb655a2c99e47b944cfb532493ff6bef25d3f86ec1e2bc532318ef1712fa82f3cdc55e32b5ff1b0c7b5acd25d3df9fa04ba67ac25e32bd0f44b4cfc0f95ad13f787f759c08c6fb8f34c9141f6e2453fee80b46fe22fac7c2fbafef24933f17fa8efdf9590dc6fb8d4a8a079626ceb3d513b04bfa5a527cb664f645eb65067848f359fd8369bfec063cc27ae45532d5e31f25f3f15c3d83315f5d12c9544f740553fe1e6592a93f3dc158bfb88127145ffb9560b2873a96cce5d75f25537ce90ba6fa62f283a95e2ae49bd2f82b0f82c93ef385645a6f17ed453d39984aa6fac04c32fdfd5607c1a42ff14a30cdb7b74232e5a76f60e483fe5132cdafb960c4fb5f60c4aba52218ebaf7b30d69fb6e27b9c1f0ceec1d82f962b92c95f1d24537da7148cf93d05239f534f92e9bc8bb81fcefb1547c9544fabc1383fe68af1c67e92f807d3fe43213ff6af7662fcb19fdaa37cc410f5ebfc5e30cd1f6b07ecd2f85a347e06332faa8f1cc0d0efdb17784cf6e91a82499ff44ff004eb318f92693fdebd649adf5f05937efa67c1347fe91618e7bb6e7782112faa60ac8736a1601a8fac00a31ee98c05e37d155bc1347ff8aa647a1fc009bca0f1f21682c99f9ae2fe0b6acf360763fd62bb168cfcb0148cf7790879f1be9ad4954cf53cd17fd8bfe49f24533db1164cfdbd7d07e33cd346fc1efb17b789643a4f300423bf303760bcdfec42f669b27885ee47f38169e1bc977e124cf18d3706e3fd11fa163c22fdda9482a7b43e7805c3ff058660ba9f2b9e87f364d14632d5fb4792e9ef37fe02e33cd926028bf364efe039c9b712f747fdd9ad24d3f58231fee58b601affdb9b648a6f7230dedfe12d25d3fa760a467d3817f218145fd99f9269bda1924cefdf93df23fe7e009b349f98623c2c1a5ffb2298ee97d8609c3f32e6609c3f8b2cc9646f0bc914cf3f4aa6786607c6fe958ee20f8bcdafb43f81e20b165e93fe5c3e25d37e30f13dea3ddd093cc27ede2d18f5983804e3fd1d9a25989ed7168269ff61fa089e223f9e8167d47f862699d6f39e25d3fe68152ce2b70318e7c9ec67c9f4fe12138cf70f252918f1932b9e67507caf08f9f1be9938069b648fc15e308dbf32108cf7df88e7637f627c150cff7a0163ff42f000c6f99c88ec9b4d37a867d1fc62b3f1a3fd3c743f5b8c5ff102463cb2da82117fb4df9269bde12498ec510f25d3fef01c8cfcb8b425d37eaa5232bd5f2506235ed85a9269bda4154ce31d89f6cef17ea8037841f76b447b17d84fb6012fa9fd6b211fea49978b608a4f0c156c423f3bc9b49f3602c31e6f7bc1d0bf4a32c50fe44f6c1bfb3be22918e7e93a6287d907adb70ec063eacfd51b784afdb3d1c0c85f8a5232cd97afe0398ddf652d99fcf75130e5879d09c67c961482c97eae7bb049f74b3ac9349e86649a4f2692b93cb978be8df749b88229be509660eca7f39f24d3f922713dd6afaedf8269bcd690c7c6f9d755001e52bc5b533ceb5a63d29fab2199ce63edc1139a9f82083c25f9f5068cf745dd2cf082c6238d25d3fb1d378229bf503ec178dfce6a0946fce9bd0aa6fe5ccf04e37d0af27aca77ac1bd8a2e747df9229fe2dc136f98ffc4530e9f34a934cf9f10fa6e78be739387f48fde9daa8f7273c3e310716f67b260f9269ffde1318efefb91e24537dcd06e3fd79f6156ca0deb1904cf6a080d1fe6a2199e67b5f303d4fbb801dd8fb0a8cf8f9a611db78ff5dac8211df745f60d413133e7e2c389be17ccc183c27ff97459279ffac4b30de27947e0826f94c4532bd7f5d032fa9fd6d2a784af58e21d8a0f9e1aa48a6f53f5b30d58ffd6730de5f94ad89ed01d9ef86eb2b0b2eb0feac6fc04b92af7525d3fbcd8f6093fccde64532d9cb4d30c57fe1128cfd33eb77c1a41feb028cf7355a1f82e9f9ee1cec62ffea9b60f227892918e785f0bd8dfdafe9b3601a4f270463fda81980f17ea59adbbf3966fd41ef472dc14bf2075b1b6c60fdec4132d50f0bc9944f1cc126c693dad7bf5e9ff2075c6f63bd6b45fd33b1e6549fb8adc0580fdc7682c97fdd5ab035a5f74309c67961e50bec523c1de2f736eaf7f11c3ca4feaba8bfa6d664467fffdc080c7f53b492a97e6f08a6f686776013fab4964cf69982717ed224ff30b5b15fe81608c6fbd3ce60c48b2d8dd78cdd8ff2eb5430c5839b5730f2dff60086be74a4af33d6ff148fdd8391ff6a74bf390b30693de808b6917f64c436ce8fdf1230f6bfb7345e0b6b3a27fbe9c0f319bdaf8bfcc782a5f7e43f0f60cc4705f99f256b3fedf71c826d92ef3625b627349f68dcdf9b2c9f9b927f237d3458ffd1fc5b8327f007241f530f1aaf6b00467cad51ffb2f8674efd41fed5b6711ed0e4fac192cf39b57733022fe97ecf977feda32abf7d8c9f3e26ffa7827fa74fcf0afb9da5daaac3fe58ff6a0be8f3df21cb2f72b9ecf3bb5c0afe9b90afff77f7df5116d62247f5d81ffad87ddba87590cbfd87bfb3f1f9779605f20899fa6be8cfffb79fff167b71e9f393743ffadc1663f4e33aa96fbdedf8eccf3f18b9ffff65e16dfbc90e6009240d1fa9bf2b3bc9439ee0df4d1661eb3f64f9313a3f24f3e4e717cbfa7791e5379fecfefa91d758f05a8e94457a8a7f2b590235542335561335553335570b364ea55aa917b5669f86e951ab76ec7365b2de544dd5d99f15ff9dc67eb1fe379365a3aed827652391a85bf6b963d2ecd43dfbec982c07464726dd91fdfb4e3da9f74cce7bf5817d0c76e53ff4daff5b6479e43dfdc446e699fddb597d515fb94ebda9efea87faa906ec9a9449f8c524f85607ea501da96375a24ed5993a67d2fc1bc9c25a7a5637ec9f91ba607f02d8fd92c9f2cafe6929aafaa4284cc7be15431d2ba662b18fad380af31a8aa7f8ff3d92fcf7cc954aa0844aa4c44aa2a44aa6e44ccf5ca63d2dfbf4b6622a059b45064aa954ca45a9954669954eb92a3745537465a5acffe8b5ff37cab251b6ca9db253cf8aa2ec95036bf1513929f7ca83f2a83c29cfca5979515e9537e55df9503e952ff6dfbf9581325446ca589928d37f23596c65a6cc9505d3b393b26413cd83f261288661b044c0b00dc7700dcff08dc0088dc8888dc4488dccc88dc2288dcab8a87746fddf23c99f9345b58ca6ff23a390df6677a3353ae36adc0ccdd08d95b13636c6d6b83376c69efd391847e364dcb3cf897d8e8c1fd8e7d178329e8db3f162bc1a6fc6bbf1c1b4b0cf02685e757f9b797f9aadfe999ff8af6561527c1a5feccfb7313086c6c818315fd4186363624c8d194b9916c6b2370ad3304dd3326de3683aa68b8fc73ebe19b04f684666c465eaa53a9a31936a6726666a66666e16666956e6c5accdc66ccdcebc9a375333757365aecdcd2f33b1f2eb1cfcd764311a736bde3169becd9db9e7b21ccc8379344fe6bdf9603e9a4fe6b379365fcc57f3cd7c373fcc4ff38b7dbecd8139c467648ed967c23e63736aceccb9b960992a3334e3de322cd3b22cdb722cd7f22cdf0aacd08aacd84aacd4caacdc2aac12b9dc2f91c5ffaa2c56655dac4b3f2e566d0cad5a3d5b8dd55a9d75b56e9666e9d6ca5a5b1bd6d3f7ccd96ead3bd6522689b5b3f61677bfd6019f2393666a9dac7beb817d1ead27ebd93ab351da592fd6abf566bd5b1fd6274b98bf5884b0601e3d61b3e9c0faeea3cf1fd1d1bfa2634cb31a8bfe82f001fff74a89aca135b2c6d6c49a5a336b6e2d7acdb196cc74fa4a9ed18f85b5b34d48f2439643bf4c614e6ddb766cd77ab03ddbb7033bb42326cfc178b4633bb1533bb37336abda766197ea935dd997de92fecce74fc932307756cdc6646055aa67d77663b776675fed9badd9ba71303fec95bdb6376c249ef9676fed9924625414662bcc5e602bf766681bf6d6beb377f6de3eb0cfde3eda27fb9e8debde7eb01fed27fbd93eb319d7b35fec57656fbfb1d1b07efffcafc9f27cb16a66274cb78cc6f8b4df992c1ff6a7fd657fdb037bc8faf3c47a7864bbe6dc1edb137b6a2db924bb7e64fab161ff9cb1f6ce85fd9b91bdb0972c485698ddcc1dc3311d662c8eed384cd2bde33a9ee33b8113b218f5dd89545df17fcdecfe155954d7183ab113333bb1edda499cd4c9ec2f27778a5e0ea7640ff0ed3d6b55653d3b17361acf4cc706cc6216dc6ed8ff3b356b6be3b44ca6b9d3998173756e8e66f7938feeac9cb5b3b1b7ecf78eb365d21c8d9d73e7ec9cbd73708ecec9b9771e7ec9107ecb7a7eb6a03f234b2f09f3c683fe7ecea3f3e43c3b67e7c58cadb33db1ced6b33d6656cc3ece2b6b5dc5dab5c0a7f765ec63cfe9e374f8bc39efbd24f6d20e9d0f66fd47e7d3f9ea7fe954ce379366dffff5f6cec8e9ff5acca933b3eb9fe4f8576599ab9db3b05f9c25fba1e21a6ce2b08c23f34accd3bab6ebb8aebd702a73e17ab66b1f5d9ff9a8931b981fccdacfaca5f76ec86c2ae673e6d18ddcd84d98bde0e3746e6a7acc73b02b594fbcd93336be67377373b7704bb7722f6e6d176e63356e6b358ae67656f3afe8987a70afaaeddeecd6d55cdd5db96b3626cfeec6dd9a43f7ceddb97b3622dbde86dd837bb4576e6031ed331df7e4debb0feea3fbe43e1b817b765fdc472195fbeabeb9efec5707f7c3f9703fdd2ff7db1db84377c474f1c0fe7dec4edca93b73e7eec25daabd2f6091b8a7aa81f70fbdda9f91c533d8f46d79b6e778ae937b9e71b2179eef055ec8e4601fdbf0222ff612e6030eb6d1eb8c977a99977b85577a9577f16aaff15aaff3aedecdd33cdd5b796b36e7c7c6c9db785befce7a70471ebb0b1b5d9dfd3ff36fde8e59cec1db7b07efe89dbc7bb5f01e58467af31ebcc71f5af5bb1ff853b23c79cfded97bf15ebd37a730637362dbde3bd32f2e099368cbe6f229b39ae7de76bd0fefd3fbf2bebd8137f446ded89b78536fe6cdbd85b76441d7a3aff8866ffa966ffb8e71f45ddfb31e7c9ff9e8ad6df8811ff663e547ee8069e4831ffb899ffa198bd6be51bffd523c9189fe75599e2f7eee177ee957fec5af0d6603e6d46f7a49fc967d3aff6acead27ffd6cf77bee6ebfeca5ffb1b7febdff93b7fef1ffca37f62f966a2bef8f78aea3ff88ffe93ffec9ffd17ffd57ff3df8da3bdf03ffc4fff8bf9f485bd30c74ee57ffb037fe88f8cbd3ff627fed49ff9737fa1382c27fd6679f70f597ea97dfc99d8d25f066aa004060b112da65f6aff97c0f7fae5b7811d38fe3570cd0fe31478811f04411844411c24411a64411e14411954c14509839a7d1afb3d68838ee59af3e06a3f07b7400bf460c5fc48ef0d9560ddeb99ad30d906f6c27a0e36ecaedbe02ed8057ba50e0e4a191c8353708f0af54f35ab3f2d8b1d3c048fc153f01c9ccdd829ad73f012bcf6da15bc05ef81137c049fccf38c83afe03b1804c360148c8309fb330d66c19c49b47016c1325443253442d3188416fbc39c71e8865ee88741188651c86cc73a8709f3cb4698f29881c50f61d6fbfc300f8bb00cabf012d661e32fd421d3b41fb2387f94e5e77af6cf63d25f1db661175ec39b19875aa8b3bbafac636f27e13a5c33795e8c7b2f0d37e136bc0b77e13e3c84c7f014de870fe163f8143e8767f52d7c095fc337ab08dfc38ff033fc62d2982c22f6d97ff90e07e1301c8563e3184ed82cb40dd6e1943d63e6ee99fd7c9b53f6dfe7e1225c466aa428456444e68fcacdaf5a46b288ff862c28f1d4c8525fd5d7c88e1c7f19b9e673e41987c8376751c02375a61351c8e2f7cf88e524511c25511a65c62dca8347ab65f369cafe3c4645f01895aa1255d125aaa3266a5910d345d7e8166966678ccc75d4467ab48ad6d126da4677c629da452c82f0039ef778d68ecdb40bf6bc7d74888ed129ba77d2e8217aecefcdabed866af4d1eeaff6f2932c068fb043b77516ca2e7a8a9ea373f4629ea357f6a437e6750d16a79ca37773c2e6e8aad7eae823fa8cbea2ef68a0ce153f1a2aea8f2a2c7f9e1b8da27134096d2b8ca6d1cc8aa379b48896b11a2b56111b319bac629b85166eccbc3d9f73962c7f93b29843e33ef6e3200ea3fb388ae3f081f554cadbcafc5a1f25fe2c0b7ff68f7131d4f8f9e22cd4f73889d3388bf3b888cbb86277bcb0f87111d7d6dedd5b4f7c2639b959dcc46ddcc557ff515dfdb4f662cb3bbaca5875e25bacc5ba3f8b57f13adec4dbf82edec57ba5890fea323ec6a7f83e7e881fe327e3143fb3d866c9bc7380b86e689de373fc120ce2d76011bfc5effd88736b3055a38fdeff992c0ad34726cb6b9cb8adba8a3f4c23fe649db7641ec6b09ee3da665ed3fc0c33f6dcaff83b1ec4c378a456eaca7e51ee94713c862c3c1eecff9dfdb7493c55f57816cfe345bc4c54e3c17e4894c448ccc44aecc449dcc44bfc24484263efde9b3e8bd8d887e7a42c3b65f3d6d17c4da2244e92244db2a84872b1baf07765b1c886f8155b36bbb2fe65914fa2b8499194e69b71f26fd69e8dc9d9b998dff6c13ad953e39054c925a99326d6d5f7beea9db4ccca52f40d55c1d97d95bb385332bb4abae49adc12cd38252ceb4956c93ad924dbe42eba26bb641f1c9243724cd82c657a8ec272014364d94c9b4b2f4dee9387e4d158264f09b34ab146d2e722ff4c96e499f5e198e50e2bf6efe7e4257935dfad3e3f3f276f56ff8afa7df26ece8dfb709c7c249fc957f29d0c143d192a8b64c4abe3bdc7b4fbac8dc9c264b2df93713231de9269324be6c63159d8c76469c6a99a2aa9919aa995daa9e3dfa76eeaa5bef1603a2cbfe1b2f45910cb54b769601cd3308dd2384dd294cbc2d76dfa7cc4180aaff6932c96b0fe3453466e6b97cc8e9d344f8bb4343fd22a4c98f75a5afdfe8687f4621becee75daa46ddaa5d7d451f4a04b6fa996ea91c9fd3f978549c3644957e93adda4dbf42eddb15fedd3837d4c8fe9c9d8a7f7e943fa18fae953642b7a344c9fd373fa92bed2c8902c2ca7db4681719fbea5efe947fa997ef5feb197a56f7f9f5bfd2acb8f91e17a78607dbb5412ff2139a7dfce9069eb673ae86da5f7c54ee5fa696f8f553a4ac7e9249da6b3a4b50b65c3f42c5177fe23ef31361a7d0edad724d379ba4897999a29c63163f971b4efb3e3ccecb3e2649559999d39ea57ea0475e6665ee66781e9fa81a3a06ab0eb675096e1c5599845599c25ce23b3172e8b6af5b9d52fb2889a9add3f99d14efd4a064ccf952c553eb2cc74cc2fe61b077dcecbf477613d982316e37efaeb2ccf8aaccc2a61e7e45b98b34db24b56678d5dc763f53b6bb32ebb662c62f343d6df6ff6c2fd66de9c652c99661ce3a74ccf56d93adb306bd3b36d76e74efa5999c53363a603cf76bfcd8445369691edb23d93e5901db313d31d85db7491ddff268bf28b2ca67a973d3032b24743c99eb82ccc37f67d642ebcc4661146f69c9db397ec357bcbde852c1855577d4bdaec23fb8c9e93419a655fd97736c8d8e866a36cec8eb24936355da7cc66d9bcf7ebacbf17d93257734509552b377233b7723b77d8377d3d6dc29edad74398b7cedddccbfdec900779a828ff4496be024a7dabf8bd36f63edacc23c330ee982cbd97efed70c024619219f7799c27fe364ff32c3c30597eac4172bf95e779919779a556f925aff3266f8d63dee5d75eb7dc613f1ef9cdfdeeb3e25cb316f153aee7ab7cad9eed32dfe4dbfcced67396c1b09879c8729a4bafd9feb7719f29f93e3fe4c73cc88e4c9b1392c52afe812cbd0f559209d332db2ed5263f1926f32baed05ca6678eed5877ecbfbce6f7fe5dfe104cf347a3fd690d92d97afe943f671725cecff94bfe9abfe5ef7dd4937ff49909af719cddaf6cca73628dcd8871fe997fe5dff9404d9cc833f3613ecac7f1579ff1997dbc4c51b4cfee30c9a7f92cc9988e1d59a699f47e377c0bdffe200bb75792259fab7b854d65ea77be302c63cfd2fb1dd5bc481673943bf9b2500b8545f5b3e8814547b6dcabc0575793b1fa919f0ba33059b7d9ac557d2cbfe8f312ebaeb7e4c2e96b1785cb62ad53e1157e111461112923d52ee22229d22233f67d5ec365611ac6aecdd98cb92f8aa22caa3c2459faf6b398f5f597f9e5375958c6b34f6fcc62be8b0b7be4ce74a97227646177ae8ba6688b2e288a6b714bf25f7684303d53fc645268855eac8ab5710835e7b597a5d8b06cabaf6a7ef4d5be60cd243916dbe2aed815fbe2a0d8c5317b284ec57df1503c16cc3efa1a279764614e0b268f7128cec54bf15abcfd248b1aaa7f57164fcab22bde59fe742a3ed894b5efa33c5420875c9645f1597c15dfc5a01806398ba2c90bffd8555114a3625c4c8a692f4931ebd72c989ea8c5bc8f467b5b6677e03163b12cd5ecbb544287c540d7d250c2d22cadd22e9dd2354ebc22c2ae36c7f6a1f498cdc6a55f06e1ae64290dd731f7efc822d654c40cf3adb665c472b053191b2ecbef852cfb5e16f3cb3a9749999659996749745f163f564a7824669465599597b22e9b5e92b2cd34661b565f3b6371dc985bb4e10ffaaca7ecca6b79b3be4acd0a4a9d8d67c4a45995eb72536e992cbabdeda326368e5bebbecf64cabb7257ee7b591425cd7a6d28b552fb45961fd13ef773ea8dcd103b75c56439183e1bebc81c5b7d3d2cb0674e63cfcb63792aefcb87f2b17c6271ce86e527a398c594ca9d5d97cfe5b97c295fcbb7f29d79d12eef32adafee9bb3bebec13f337b5f7eb079bc2c3fcbaff2bb1c985d392c47e5b89c94d3c42d67e5bc5c944be3c45c7d156a7c4c0f665f1939564a655466d06746a7e0d4ef2ab2aadf62fedefb3059d8b7663f36c8d834bbaa2c26cbbd19b2deec97483a264b6b06c6a1b22bc79bc5e3a00996e5c4dc562e538ba86236cfa29545e5574115329fca66bb3ea736471513d73a313946fd9a4515dbdb2aa9d22aabf2aaa84a2bacaaea52d55553b5556745c1b1ba062b362e5ba7a355b57ebda3aff254b74aabf42467b21c83a36ad9f51f641151a5cf6571d488e9e246bd315559556b264bc4662c268b193269f64c96a37bf65a6fae2e2387e9eb5bb5a9b6d55db5abf6cab53a54c7ea54f575e17be6c717d681c5d5233e26a3fe2ebd3d570f4c96c7eaa97af646d5b97ab1aaead5dc556fd57bf5517d565ff128afabef5e966ac07ac2e5f5cf678bddb11a56a36a9ce4ce23c6c5339adf627e4bca6270efba60d1ee539ac5a36a524db98e912c51af654c965335f33a8f656bca3c34ccae9a87af9eaac6ac3f17d5f2a26637f7f5a25cb81fb615f38349d17f26b406c3ee7570377d7e75312fd6c5be38e1cbc5bd78179f8d897f092e6134b8449798c9d2b91fccbadefb159cde673059946a7449823e47f6d9c7fea32ca859283c96225912f549bdbfa4ec9e593fc6fdfa9c6df523d4af3d18a774e75d2fb9925e8ad0c8eefbbcfd525eaacbe5525f9a4b6b9c2edde56a6fcdd1e5165f98bd93244764f10773e445d68e5da55df4cbeab2b6c2cbe6b2bddc5d7655a7b697fde57039ba2fbd2c173633b1d8cde27fd5d684fde2fef27079e4b2a0adfd5add3f95256071f24d29c2faf27479eeb585d61bfb95a07ecd81e9d8a377f35545b3df7975c88ca6feec72bebc5c5ecdc4383afae58daf136d8235f75dbd7e8db92c7c3d96f5f196c5dd5333bebc5f3e2e9f97afcb777cbcf06a13d388e16578195dc66c869ddb6c66cd466c967db5ee7adbbf4c2ed3cb8ccba2f0bcc2fe5d16392f4096545373b5cdcf97f9657159f6eb90bdcdb2d8b85fd50accc08d8c83a7298f8a1fb4c620fca8d55a49b6b5519bc98ac9f9565bb56def1cc38bfaf99ecd8d336ef74cc7b8341e9b3146e6dcdef82cdeac9ddaadbddaaf83484b46e9ad0eeba88eeb84e5ca9fcce3796c6e9db008f4c9dd32590e755a67756e325990875bfd0aeaeff9cbcfb2287eaa2b6e5dd4a5f25557c68149c0bc0fb3dfa8978569716cc69eee2b6aa9cc422bfc8caa9a4590ec7f0d6b5beb7eb84347cdaf2c63af9cd73063f67faa22f6ebdeaff7d27875c746f9cbfc626d5cd6d7fa566bb55eafea35d36ca77c8af27a536fcdd8b9b23cdceb6318d6239bdec2eabb7a57efcb3d932515759e3fe695d8112074cc55efd44370523ae5b13e184cb3597e7f6fdbbc12cfda581f599b4ff57dfde0b6a1556d13b77eac9fea67e3549feb17a65b8bfab59f159cd728b02d1691ceeb37bfb1b7fe376fd994b220ca89acbdfb5abfd71ff56738a8bfeaef7a500fcba01e992ed3c27db17077aec3f29881cb324b63578feb493de5b2507ef20f7264f6a797a59ffb13f6ff0d9bfda7f5ac9ed70b9657b2fc8bc52e5b7b592f9d779bcdc98dda288de13f5a35f3ca1f8dd958c64363db47f6d9374e3f438693be6ed3fbb2c665ff34a2d0def09a9af1cb1ae0d074eb5be3357e1334a1f3d4444ddc244dcafae291e54977eeaec9ac2dfb158b429bbc299ab2a9b8bdd09ca8f42b763fcb42732397c5e4b364aa8cd2cc99c77a7369eaa6316377c3eefb7039352d0b8359d6e186c6aee99a6b738badd0b48a466b74fbc18c9b557aecc7c57c6fd64cdfc76c2c3efa5cbdd9345bebdcdcb9dbbe8283d53fac9c9b5ebfb3a4d935fbe6604d9a63736aee9b0726c363f3d43c3799bbeb6be64c2fe3e6dcbc34afcd9b948559c51f65a1d95ecaa2f1959bb5faa138cd7bf3c1a22ac7ff609e89d973bfa6686f9b4fe3e0dbcd57f31dbae167ad3483669828d60b7bde283359ae356bc66c961b46611f41369366dacc9ab971b296eeb6e1e3815566167d9b9ed3354b63efad5bb5555aa3355bcbe8ebd581396efb15c45d9f2b87ba71689dd66dbdd6ef63181e7719aadfaf09ff365752a5cfa4bdc2fdfa937a8bc76de03dc65d1b1afd4afdb658703fbbed6dba8d8c531bb7499b865ef5de666d9e9fdaa22ddbcad8370fed85595585fce4beaddba66ddbaebd5e5876dfded8bcf3ddd70ee4eabfefed5aaddf1de36baddeaeda755bb35f6dda6df0dede056f5ec89eb7734a63d7eedb437b6c4f52163f38fd41161bd97abff39945bc2c951e313ddbe5b9a2b7f7ed43fbc8b4f7686ffa9d05b5d53ef55adf326fdf9edb97f6d518861f4e5c44ed5bb269df59ccb3cf3b7bc9645ef5f949fbd17eb65fed773b6887eda865b3068b697aed123b19f67e906bf6b69db0acf8d44edb593b6751cb397875ed76d12e3bb59fdbeace38754a67746667c571922779af472c8e39fe4116e75759d84c99a94967770e93e6dab99d67192cd770d89cb063be56ef7c7b5b9f7d3753baa00bbba8da767197746997b1b0b8e8ca7e6dc8db75157bfea5abbbc6df756dd775d7eed6699ddeadfaac8e723b5ec95b326b687b8fe2fb4e65dce75db7ee36eeaedb76776c02d875fbe6397aef0eddb13b75f7dd43f7f8ab2cbfc563b40fdae2fbb87b59fabdb76ef7d43de7cfddb97be95e6bc738b9ae7de8ff1a4166c38eb3eddeba77964f9cba8feeb3fbeabe9d85fad80dba6137eac6d19d195b0b33f6b56ed24dbb5937ef16ddf2aa5e95ab71358d9dfbca7763f9bd1ce6d00ffa99fd6ad97bc7bada4cbe73b7bb322bb18ee1cadd5d5deffdea3109dfaffe35b886d7280fa302b66ffe1d1d13eb0b72bf196a7fdcef5de36b52b2d65d53ebe19ab119ef6c9dddcf7eb5f79ab3ff5a5ccb6bc5e29897ebe55a5bfeb5b9b6d7ee7acd27d7db55bb321d5533b30bdf8da69c5c57d7f57573dde6937efe655aa8f4750ce623a2be06c6f7638dd87c74ecfd38d515ade7de5aaa8171bcde5d77d7bdda3847b5edab2c5993353c07367f9c07f8afd7f89ca7ebe17a8cd953afa7eb3d3dddbf998b6641d1eef5e1fa787dba3e5fcfd797eb6bad3069deaeefd78febe7f5ebfa5d75d74139bc0eafa3eb987d26d7e975769d7b6bd60b8bcccccceb92dba2f5f327f2dd7d73c7fc1c27ebcc52c3a79b7263f955348c4c36f3b9aa6dbf33591cbebef31764b99937eb66df1cd6379ecb66877edf8bad140b2fb9b139d0b8f7b51b0b346f8152ddc25b748bd5db2db9a5b7ec96df8a68d025e15755df4a7377ab6e97f0e3c626c65b5bac6e9db1ef772df0fd16d6af1f5eafb0d86cc4246aee7236b3dcaeb7db4d4bc6d133cb2d44fefb87ddf3ffb52ce6e34dbfad6eeb86c5860d1b0d663515f3f8ecff6d8fc5eecc9fe593dbe6b6bdddd5a5fa62d7cae2b65386b7fdeda0d4ea58dd869f55773bde4eb7fbcbddede1f6787bba3ddfce51623f180fb71733643e7af24759983454afa4fbbfdede54f7f67efb48068a226ac97f7d7d3f2a6e9fb7afdbf76dc02b565f2cb35c58776c86d89a73162f6d6e43e3741bddc6b7c96d9abab759eadce6f1241ef77bf56f8bc80a5fa2eab6d4d4a8d394a85202f5ac199aa9599aadb1b16e5acdedade4e78fbbef3396c82759cc58f3345f0bb4508bf242d1d20ce3f287d3597fc25e1eb5584bb454cbfad981dd7b617e7a119385f624cdedad96f733a75668a5566917ad564325615ed0b65fe289b25322add15aadd3aedacdf84c1dd573979aa6e9da4a5b6b1b7ba16da99af0ebc8b03f2a8bb1ad7667dada9db653bba0b9bddbef2c7f37642dcfa1f8f22fc8926a7beda01db59376af3db008efce9cfa1f2c3bda71eb6451633568f92e43ed517bd29eb5b3f6a2bd46b935d2de8c85f61e4fb40f36269f2c216e94246ccb2767e999da97f6ad0d3436a6edeeefd98bf5dcee2c35f2b59136d6260a8bd955d72eed525db37111f562ef2fcbf2a84db59936d716da52578d7da8318f79673d9993b86e6fecb363518056b6bac26c79a71bbad92a9dab5bc64db77527327457c97596ee844e7fe622ce597e32d4033dd4233dd6133dedc7e0d74f98f5b2447e2f95bbd7333dcfebb2d20bf6fbfe0c84266b797c86ff2b3a16157aa957fa45aff5466ff5aedf11c3f2de39af8f322fa45ffb798faffbfaa6ebbe66817ed3355dd757fa5adfe85bfdcef850bff59dbe77c6d5413fe847fda4dfeb0ffaa3fe14bd07aece722db28dde4ef86e0bf3e78fe9e8e764adbfe8af4aa36ead86cdca34abf4f6eff075c43fbd8724c9f537fdbdb8ea1ffaa7fea57febcc07588affed6ed3ca56a3f7beea637afd3a561f4733895c33d687fa888dd0589fe8537da6cff585be5ca92b6565accc95e5eddd3c7ded778d38d5ca5e39b6e1eec90f0b0ff68b2cae7170dc95bbf2567e3c535f56415f310a4e2cdeea57df6a5a7bfb73b2048fab701505b355bc4a56e92a5be5ed78555807166b6efa5ccb3afe248bc9b28265dee5ceed8565b4b755b9aa5697555dcd568d3e5ab5b1c7f7c23129dcddaaeb76abab395e752c5bbbe3f66e626ef955166f7533e3b261f9d270a5b1f178e335567efeafaf2afd9571311f57fa6ab55a6bb362b8daacb6abbbcbc76ad75767d2a05f79b0b67d0ecf64796372ec983c0adfc570cff7819ef85efea3d8cf6bdcbbdf76e87ff8cd6abf3aac8ead1d7cb84edffa7e9e679aa6b63b6627bfcae2af4eab7b9643ad570fcdfbea919fce727f3a052c4f69fca971795a3dafceab176db67ad5ebd5dbea7df5b1fa8cbff26ef595f615a31fbbddf98749f7c177bc0f9d57f6795b7daf06d17e35147b2cfbbdbccd9339ee7739b58bd5a8d72e173b9358e3acdf65b1ceab717d67ec5693d574355bcd51c3b7708ec1fdf3314c92af16abe55a5d2b6b439badcdb5b5b6d7ceda5d7bc69e45cffb1f7bdefb489eaffb32097a7b62b3105fc7e3fba9f9beea7e36627e6318266b7f1dacc3c0091cbecb91452c6431bd17f85d967e7473dbd8d7efeb681dab77e20c2d9745f9b16be9cff8b1f03198af933c5d5bc1789daeb375be2ed6e5ba5a5fd6b5b5b437741601fbf7fbd5b30fbe57a25f6bb15a16fc34ceba757416dfb3e83e9ce9d77ecd807df6ebceefd6cc62bc50c8d2eeb411f366bfd90bd7d26374b7beadb53573e4b2fee5fed5793f628aba5eaf37ebedfa6ebd5befd787f5717d5adfaf1fd68feba790c5fdd69eef5ac1b8b04fbf9ef76a7e704b3e584bbedb9f5950bffba8f7e2eb7e97fcb1df83b63eaf5f02d736cc28effa73246c8e1feb193f73d2e7373edfafe4b23c69bb7e5dbf35cafa7dfdc1e617c8f2f7f78ffdf38ff3283f69566595d196e7f5e7fa6bfdbd1eac87eb11d335bea38c568b980e4db0afbf8fa6c6acc7cffc04c6b2dfadd7cbe90f7a7bea77569a43967505d5e0a69a713e6171d79d36d1f3f5b8f776eb49bfa3b61f93cb389f38de7aba9eade7eabdd8d32b674be7afc8f2d3d9621ecf798f6a11dcaf179774bdcc5f36ea46d9181bb37faead164ebf368979c230a77db5439cb4602336661ab91436d3dc39174ba1fd0a2caa7f6511e4ae0f0b36569fdfacc6cce59f8ce3c6c9271b77e36dfc4d607da94f56f35b9bfed2b8fc7eb6381a2a9ee2da55972acd26dc449b78936cd24db6c9f9aa0bcb6eac27ffdbf68bbc782effdf76ae6549552488eee733a6f615fdba7dbb6356a899203e5a6db51f3b4444f0c14b1489987f9faa8202a4bd37b457331113b9d010943a661645669d93b6d9e37b5a6207f5ce54d90a7b630ee6244ed8f3c2d4532060d9afca32ad349d280e4d481246103617866ae8b10a11c3b2b36c86248e1fe983506f36cb7bd7f59cde1344592e9dd23decc91c0e90c0115250a0014d680104cf80a691efb672cf7c667bc1191af13a6a6c8d2ed758790ea8a041fba8a546ca6681e23a2c67047dffd9b4a1130fb9e20cbad0833e2ce34747a706bc2c0e85fef98baee722bfd4f4404187dc51957668dcd0c2d0b660004318c12b8c61025378f3347fb13bb0acbe5df0f8ab3a31cdd0e01d3ee0136ee036e9c2ddb1ed7437f7e95459c13d7169c0bcfd003fe0117eb2bb700a4ff08c94def1b9eef5e9337dca1557dfc052a8ea8aefae6ed98c216b9d45ef4ffa485524aebeeaa181333471eeaa5edbb7f71bff47100423b4421517519a70a1686ff7106f632dbe471b97ebe0a027b3a4874ec8a276354cdffc603e255ca59dee228325a4b8c2354b719e8d29bbca113774bcb961e319c8f15c1f6327bd3884873ca043ee1bdcda7dce35430f7d0c30740718e10e636fed2f7ddd7f0cc2861b3aa1161991827b3cecfa8d66ec6112bce2115354f693204dfadb96d559cd6ccab25f967cd21655d61b3627a2d61336b0892d72a03dc20e53978ef868d8fa229f5faee75a7fe935c07eb745b764495b08ec7d0311d5f514356ca3bffd70224ff774bfb3f1822818bb5ad8461d3bd8c5de6e837df6fe0507fb088787258ef015c7d68bd0fa1a7cc79ef3f0a8623d21573237714a0f6bb636061dba66de58d0211dac1b76bfe293ef6039b59ad281736c393795d713791dceebf80ee712f96e3009ddd07544a5d179e13613e6e4967d435ca3ec245389a0cad56bfd58aad7bf7aee9fc122ff178e852391e3f3ba9c7d9399eff23a234758aeb7d96b869def6fe7fb0f468e60216ac18678a2378b9890bd31a42ee18c42f1d27b720dcf09969c1fb0909d7904e76ec356026184f0baafc89d66956e3da5fecbf6f6f369d67545d6b5c5d924df135a7ec542cb5e26e49a7cbfc201afa191da8093df3604f79408ae9ab0ad576031ca9ca3caca1635c83935653d22cfb448ce3bcf6adc752c32e62a9eb9443352aa19aaaae7e288acea1ab4729f2cb50e052bf5d4871cf952b02732ae47d9db635ea9689b453c57bc2062244752ad5f5e84c592fcc3e1ee4c949995795bc152fdbea830d827ffc84c20e9088f91d2fb395e4b665b520152c3422492ebf27dce3a1163b10a2cc60916c11710bad85b6ed69a7320cdc09db863ceee0a1533e20c1ccef6c814cd995eb334f9fc9ecf4b7ebda988b5c23b67b1108e04dff03d63da7fc32f8b9a5f4caeec2fc7c9c7e6f5bc5e154b795ce2e596e3679fca7dd222b624e3bc58134fe3a1e0bbcd199677fcb81c4b3d6a7ea7d6aeb0fb7e71ceb9a3f5738b7cbeda2ba7de3ba79caf57e52fff15fb1fcbbfd3fefcfbaf3ffe0193cc32fd</data> + </image> +</images> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistbox.h</includehint> +</includehints> +</UI> diff --git a/tdeioslave/media/mimetypes/CMakeLists.txt b/tdeioslave/media/mimetypes/CMakeLists.txt new file mode 100644 index 000000000..5b1946c2d --- /dev/null +++ b/tdeioslave/media/mimetypes/CMakeLists.txt @@ -0,0 +1,35 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +##### other data ################################ + +install( FILES + floppy_mounted.desktop floppy_unmounted.desktop + floppy5_unmounted.desktop floppy5_mounted.desktop + zip_mounted.desktop zip_unmounted.desktop + hdd_mounted.desktop hdd_unmounted.desktop + hdd_mounted_decrypted.desktop hdd_unmounted_encrypted.desktop + hdd_unmounted_decrypted.desktop removable_mounted.desktop + removable_unmounted.desktop removable_mounted_decrypted.desktop + removable_unmounted_encrypted.desktop removable_unmounted_decrypted.desktop + cdrom_mounted.desktop cdrom_unmounted.desktop cdrom_mounted_decrypted.desktop + cdrom_unmounted_encrypted.desktop cdrom_unmounted_decrypted.desktop + dvd_mounted.desktop dvd_unmounted.desktop dvd_mounted_decrypted.desktop + dvd_unmounted_encrypted.desktop dvd_unmounted_decrypted.desktop + cdwriter_mounted.desktop cdwriter_unmounted.desktop + cdwriter_mounted_decrypted.desktop cdwriter_unmounted_encrypted.desktop + cdwriter_unmounted_decrypted.desktop smb_mounted.desktop + smb_unmounted.desktop nfs_mounted.desktop nfs_unmounted.desktop + audiocd.desktop dvdvideo.desktop blankcd.desktop blankdvd.desktop + svcd.desktop vcd.desktop gphoto2camera.desktop camera_mounted.desktop + camera_unmounted.desktop mydocuments.desktop mycomputer.desktop + mynetworkplaces.desktop printers.desktop trash.desktop webbrowser.desktop + DESTINATION ${MIME_INSTALL_DIR}/media ) diff --git a/tdeioslave/media/mimetypes/Makefile.am b/tdeioslave/media/mimetypes/Makefile.am new file mode 100644 index 000000000..7b821303b --- /dev/null +++ b/tdeioslave/media/mimetypes/Makefile.am @@ -0,0 +1,33 @@ +mimetypedir = $(kde_mimedir)/media + +mimetype_DATA = floppy_mounted.desktop floppy_unmounted.desktop \ + floppy5_unmounted.desktop floppy5_mounted.desktop \ + zip_mounted.desktop zip_unmounted.desktop \ + hdd_mounted.desktop hdd_unmounted.desktop \ + hdd_mounted_decrypted.desktop hdd_unmounted_encrypted.desktop \ + hdd_unmounted_decrypted.desktop \ + removable_mounted.desktop removable_unmounted.desktop \ + removable_mounted_decrypted.desktop removable_unmounted_encrypted.desktop \ + removable_unmounted_decrypted.desktop \ + cdrom_mounted.desktop cdrom_unmounted.desktop \ + cdrom_mounted_decrypted.desktop cdrom_unmounted_encrypted.desktop \ + cdrom_unmounted_decrypted.desktop \ + dvd_mounted.desktop dvd_unmounted.desktop \ + dvd_mounted_decrypted.desktop dvd_unmounted_encrypted.desktop \ + dvd_unmounted_decrypted.desktop \ + cdwriter_mounted.desktop cdwriter_unmounted.desktop \ + cdwriter_mounted_decrypted.desktop cdwriter_unmounted_encrypted.desktop \ + cdwriter_unmounted_decrypted.desktop \ + smb_mounted.desktop smb_unmounted.desktop \ + nfs_mounted.desktop nfs_unmounted.desktop \ + audiocd.desktop \ + dvdvideo.desktop \ + blankcd.desktop \ + blankdvd.desktop \ + svcd.desktop \ + vcd.desktop\ + gphoto2camera.desktop camera_mounted.desktop camera_unmounted.desktop \ + mydocuments.desktop mycomputer.desktop mynetworkplaces.desktop printers.desktop trash.desktop webbrowser.desktop + + +EXTRA_DIST = $(mimetype_DATA) diff --git a/tdeioslave/media/mimetypes/audiocd.desktop b/tdeioslave/media/mimetypes/audiocd.desktop new file mode 100644 index 000000000..ec53de33d --- /dev/null +++ b/tdeioslave/media/mimetypes/audiocd.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=MimeType +MimeType=media/audiocd +Comment=Audio CD +Comment[af]=Musiek CD +Comment[ar]=قرص مدمج صوتي +Comment[be]=Гукавы CD +Comment[bg]=Аудио диск +Comment[bn]=অডিও সিডি +Comment[br]=CD klevet +Comment[ca]=CD d'àudio +Comment[cs]=Zvukové CD +Comment[csb]=Aùdio CD +Comment[da]=Lyd-cd +Comment[el]=CD ήχου +Comment[eo]=Muzikaj lumdiskoj +Comment[fa]=دیسک فشردۀ صوتی +Comment[fi]=CD-äänilevy +Comment[fr]=CD audio +Comment[fy]=Audio-Kompaktskiif +Comment[ga]=Dlúthdhiosca Fuaime +Comment[gl]=CD de audio +Comment[he]=תקליטורי שמע +Comment[hi]=ऑडियो सीडी +Comment[hr]=Glazbeni CD +Comment[hu]=Hang-CD +Comment[is]=Hljóðdiskur +Comment[it]=CD audio +Comment[ja]=オーディオ CD +Comment[kk]=Аудио CD +Comment[km]=ស៊ីឌីអូឌីយ៉ូ +Comment[mk]=Аудио ЦД +Comment[ms]=CD Audio +Comment[nb]=Lyd-CD +Comment[nds]=Audio-CD +Comment[ne]=अडियो सीडी +Comment[nl]=Audio-cd +Comment[nn]=Lyd-CD +Comment[pa]=ਆਡੀਓ CD +Comment[pl]=Płyta CD Audio +Comment[pt]=CD de áudio +Comment[pt_BR]=CD de Áudio +Comment[ro]=CD Audio +Comment[ru]=Аудио CD +Comment[rw]=CD y'Inyumvo +Comment[se]=Jietna-CD +Comment[sl]=Glasbeni CD +Comment[sr]=Аудио CD +Comment[sv]=Ljud-cd +Comment[te]=ఆడియో సిడి +Comment[tg]=Аудио CD +Comment[th]=ซีดีเพลง +Comment[tr]=Müzik CD'si +Comment[tt]=Tawış CD +Comment[uk]=Аудіо КД +Comment[uz]=Audio kompakt-disk +Comment[uz@cyrillic]=Аудио компакт-диск +Comment[vi]=CD Nhạc +Comment[wa]=Plake lazer CD odio +Comment[zh_CN]=音频 CD +Comment[zh_TW]=音樂 CD +Icon=cdaudio_unmount + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory + diff --git a/tdeioslave/media/mimetypes/blankcd.desktop b/tdeioslave/media/mimetypes/blankcd.desktop new file mode 100644 index 000000000..723ade236 --- /dev/null +++ b/tdeioslave/media/mimetypes/blankcd.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Type=MimeType +MimeType=media/blankcd +Comment=Blank CD +Comment[af]=Leë CD +Comment[ar]=قرص مدمج فارغ +Comment[be]=Пусты CD +Comment[bg]=Празен диск +Comment[bn]=ফাঁকা সিডি +Comment[br]=Goullonderiñ ur CD +Comment[bs]=Prazan CD +Comment[ca]=CD en blanc +Comment[cs]=Prázdné CD +Comment[csb]=Czëstô CD +Comment[da]=Blank cd +Comment[de]=Leere CD +Comment[el]=Κενό CD +Comment[eo]=Malplena lumdisko +Comment[es]=CD vacío +Comment[et]=Tühi CD +Comment[eu]=CD hutsik +Comment[fa]=دیسک فشردۀ خام +Comment[fi]=Tyhjä CD +Comment[fr]=CD vierge +Comment[fy]=Blanke Kompaktskiif +Comment[ga]=Dlúthdhiosca Folamh +Comment[gl]=CD valeiro +Comment[he]=תקליטור ריק +Comment[hi]=खाली सीडी +Comment[hr]=Prazan CD +Comment[hu]=Üres CD +Comment[is]=Tómur CD +Comment[it]=CD vergine +Comment[ja]=空の CD +Comment[ka]=სუფთა CD +Comment[kk]=Таза CD +Comment[km]=ស៊ីឌីទទេ +Comment[lt]=Tuščias CD +Comment[lv]=Tukšs CD +Comment[mk]=Празно ЦД +Comment[ms]=CD Kosong +Comment[nb]=Tom CD +Comment[nds]=Leddige CD +Comment[ne]=खाली सीडी +Comment[nl]=Lege cd +Comment[nn]=Tom CD +Comment[pa]=ਖਾਲੀ CD +Comment[pl]=Pusta płyta CD +Comment[pt]=CD vazio +Comment[pt_BR]=CD virgem +Comment[ro]=CD gol +Comment[ru]=Чистый CD +Comment[rw]=CD Itanditseho +Comment[se]=Guorus CD +Comment[sk]=Čisté CD +Comment[sl]=Prazen CD +Comment[sr]=Празан CD +Comment[sr@Latn]=Prazan CD +Comment[sv]=Tom cd +Comment[ta]=காலி குறுந்தகடு +Comment[te]=ఖాళి సిడి +Comment[th]=ซีดีเปล่า +Comment[tr]=Boş CD +Comment[tt]=Buş CD +Comment[uk]=Чистий КД +Comment[uz]=Boʻsh kompakt-disk +Comment[uz@cyrillic]=Бўш компакт-диск +Comment[vi]=CD trống +Comment[wa]=Plake lazer CD sins rén dzo +Comment[zh_CN]=空 CD +Comment[zh_TW]=空白 CD +Icon=cdwriter_unmount + diff --git a/tdeioslave/media/mimetypes/blankdvd.desktop b/tdeioslave/media/mimetypes/blankdvd.desktop new file mode 100644 index 000000000..f5f06c9bc --- /dev/null +++ b/tdeioslave/media/mimetypes/blankdvd.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Type=MimeType +MimeType=media/blankdvd +Comment=Blank DVD +Comment[af]=Leë DVD +Comment[ar]=قرص رقمي مرئي فارغ +Comment[be]=Пусты DVD +Comment[bg]=Празен DVD диск +Comment[bn]=ফাঁকা ডিভিডি +Comment[br]=Goullonderiñ un DVD +Comment[bs]=Prazan DVD +Comment[ca]=DVD en blanc +Comment[cs]=Prázdné DVD +Comment[csb]=Czëstô DVD +Comment[da]=Blank dvd +Comment[de]=Leere DVD +Comment[el]=Κενό DVD +Comment[eo]=Malplena DVD +Comment[es]=DVD vacío +Comment[et]=Tühi DVD +Comment[eu]=DVD hutsik +Comment[fa]=DVD خام +Comment[fi]=Tyhjä DVD-levy +Comment[fr]=DVD vierge +Comment[fy]=Blanke Dûbelskiif +Comment[ga]=DVD Folamh +Comment[gl]=DVD valeiro +Comment[he]=תקליטור DVD ריק +Comment[hi]=खाली डीवीडी +Comment[hr]=Prazan DVD +Comment[hu]=Üres DVD +Comment[is]=Tómur DVD +Comment[it]=DVD vergine +Comment[ja]=空の DVD +Comment[ka]=სუფთა DVD +Comment[kk]=Таза DVD +Comment[km]=ឌីវីឌីទទេ +Comment[lt]=Tuščias DVD +Comment[lv]=Tukšs DVD +Comment[mk]=Празно DVD +Comment[ms]=DVD Kosong +Comment[nb]=Tom DVD +Comment[nds]=Leddige DVD +Comment[ne]=खाली डी भी डी +Comment[nl]=Lege dvd +Comment[nn]=Tom DVD +Comment[pa]=ਖਾਲੀ DVD +Comment[pl]=Pusta płyta DVD +Comment[pt]=DVD vazio +Comment[pt_BR]=DVD virgem +Comment[ro]=DVD gol +Comment[ru]=Чистый DVD +Comment[rw]=DVD Itanditseho +Comment[se]=Guorus DVD +Comment[sk]=Čisté DVD +Comment[sl]=Prazen DVD +Comment[sr]=Празан DVD +Comment[sr@Latn]=Prazan DVD +Comment[sv]=Tom dvd +Comment[ta]=காலி டிவிடி +Comment[te]=ఖాళి డివిడి +Comment[th]=ดีวีดีเปล่า +Comment[tr]=Boş DVD +Comment[tt]=Buş DVD +Comment[uk]=Чистий DVD +Comment[uz]=Boʻsh DVD +Comment[uz@cyrillic]=Бўш DVD +Comment[vi]=DVD trống +Comment[wa]=Plake lazer DVD sins rén dzo +Comment[zh_CN]=空 DVD +Comment[zh_TW]=空白 DVD +Icon=cdwriter_unmount + diff --git a/tdeioslave/media/mimetypes/camera_mounted.desktop b/tdeioslave/media/mimetypes/camera_mounted.desktop new file mode 100644 index 000000000..1383e998b --- /dev/null +++ b/tdeioslave/media/mimetypes/camera_mounted.desktop @@ -0,0 +1,69 @@ +[Desktop Entry] +Type=MimeType +MimeType=media/camera_mounted +Comment=Mounted Camera +Comment[af]=Gekoppelde Kamera +Comment[ar]=كاميرا مركبة +Comment[be]=Прымацаваная камера +Comment[bg]=Монтиран фотоапарат +Comment[bn]=মাউন্ট করা ক্যামেরা +Comment[br]=Kamera marc'het +Comment[bs]=Priključena kamera +Comment[ca]=Càmera muntada +Comment[cs]=Připojená kamera +Comment[csb]=Zamòntowónô òdjimkòwô kamera +Comment[da]=Monteret kamera +Comment[de]=Eingebundene Kamera +Comment[el]=Προσαρτημένη κάμερα +Comment[eo]=Surmetita Kamero +Comment[es]=Cámara montada +Comment[et]=Ühendatud kaamera +Comment[eu]=Kamara muntatuta +Comment[fa]=دوربین سوارشده +Comment[fi]=Liitetty kamera +Comment[fr]=Appareil photo monté +Comment[fy]=Oankeppele kamera +Comment[ga]=Ceamara Feistithe +Comment[gl]=Cámara Montada +Comment[he]=מצלמה מחוברת +Comment[hr]=Pristupljena kamera +Comment[hu]=Csatlakoztatott fényképezőgép +Comment[is]=Tengd myndavél +Comment[it]=Macchina fotografica montata +Comment[ja]=マウントされたメディア +Comment[ka]=მონტირებული კამერა +Comment[kk]=Тіркеген фотокамера +Comment[km]=ម៉ាស៊ីនថតដែលបានម៉ោន +Comment[lt]=Sumontuotas fotoaparatas +Comment[mk]=Монтирана камера +Comment[nb]=Montert kamera +Comment[nds]=Inhangt Kamera +Comment[ne]=माउन्ट गरिएको क्यामेरा +Comment[nl]=Aangekoppelde camera +Comment[nn]=Montert kamera +Comment[pa]=ਮਾਊਂਟ ਹੋਇਆ ਕੈਮਰਾ +Comment[pl]=Zamontowany aparat fotograficzny +Comment[pt]=Câmara Montada +Comment[pt_BR]=Câmera montada +Comment[ro]=Aparat foto montat +Comment[ru]=Подключённая камера +Comment[se]=Čatnon govvenapperáhtta +Comment[sk]=Pripojený digitálny fotoaparát +Comment[sl]=Priklopljen fotoaparat +Comment[sr]=Монтирана камера +Comment[sr@Latn]=Montirana kamera +Comment[sv]=Monterad kamera +Comment[th]=กล้องดิจิตอลที่เมานท์แล้ว +Comment[tr]=Bağlı Kamera +Comment[uk]=Приєднана камера +Comment[uz]=Ulangan fotoaparat +Comment[uz@cyrillic]=Уланган фотоапарат +Comment[vi]=Máy chụp ảnh số đã kết nối +Comment[wa]=Montêye camera +Comment[zh_CN]=挂载的相机 +Comment[zh_TW]=掛載的照相機 +Icon=camera_mount + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory + diff --git a/tdeioslave/media/mimetypes/camera_unmounted.desktop b/tdeioslave/media/mimetypes/camera_unmounted.desktop new file mode 100644 index 000000000..687bc1af4 --- /dev/null +++ b/tdeioslave/media/mimetypes/camera_unmounted.desktop @@ -0,0 +1,69 @@ +[Desktop Entry] +Type=MimeType +MimeType=media/camera_unmounted +Comment=Unmounted Camera +Comment[af]=Ontkoppelde Kamera +Comment[ar]=كاميرا غير مركبة +Comment[be]=Адмацаваная камера +Comment[bg]=Демонтиран фотоапарат +Comment[bn]=আনমাউন্ট করা ক্যামেরা +Comment[br]=DVD-ROM divarc'het +Comment[bs]=Otkopčana kamera +Comment[ca]=Càmera desmuntada +Comment[cs]=Odpojená kamera +Comment[csb]=Òdmòntowónô òdjimkòwô kamera +Comment[da]=Afmonteret kamera +Comment[de]=Nicht eingebundene Kamera +Comment[el]=Μη προσαρτημένη κάμερα +Comment[eo]=Demetita Kamero +Comment[es]=Cámara desmontada +Comment[et]=Lahutatud kaamera +Comment[eu]=Kamara desmuntatua +Comment[fa]=دوربین پیادهشده +Comment[fi]=Irrotettu kamera +Comment[fr]=Appareil photo non monté +Comment[fy]=Ofkeppele kamera +Comment[ga]=Ceamara Neamhfheistithe +Comment[gl]=Cámara non Montada +Comment[he]=מצלמה מנותקת +Comment[hr]=Nepristupljena kamera +Comment[hu]=Leválasztott fényképezőgép +Comment[is]=Aftengd myndavél +Comment[it]=Macchina fotografica non montata +Comment[ja]=マウントされていないメディア +Comment[ka]=დემონტირებული კამერა +Comment[kk]=Тіркеуден шығарылған фотокамера +Comment[km]=ម៉ាស៊ីនថតដែលបានអាន់ម៉ោន +Comment[lt]=Išmontuotas fotoaparatas +Comment[mk]=Одмонтирана камера +Comment[nb]=Avmontert kamera +Comment[nds]=Afhangt Kamera +Comment[ne]=अनमाउन्ट गरिएको क्यामेरा +Comment[nl]=Afgekoppelde camera +Comment[nn]=Avmontert kamera +Comment[pa]=ਅਨਮਾਊਟ ਕੀਤਾ ਕੈਮਰਾ +Comment[pl]=Odmontowany aparat fotograficzny +Comment[pt]=Câmara Desmontada +Comment[pt_BR]=Câmera desmontada +Comment[ro]=Aparat foto nemontat +Comment[ru]=Неподключённая камера +Comment[se]=Gálgajuvvon govvenapperáhtta +Comment[sk]=Odpojený digitálny fotoaparát +Comment[sl]=Odklopljen fotoaparat +Comment[sr]=Демонтирана камера +Comment[sr@Latn]=Demontirana kamera +Comment[sv]=Avmonterad kamera +Comment[th]=กล้องดิจิตอลที่ไม่ได้เมานท์ +Comment[tr]=Ayrılmış Kamera +Comment[uk]=Роз'єднана камера +Comment[uz]=Ulanmagan fotoaparat +Comment[uz@cyrillic]=Уланмаган фотоапарат +Comment[vi]=Máy chụp ảnh số đã gỡ ra +Comment[wa]=Dismontêye camera +Comment[zh_CN]=未挂载的相机 +Comment[zh_TW]=未掛載的照相機 +Icon=camera_unmount + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory + diff --git a/tdeioslave/media/mimetypes/cdrom_mounted.desktop b/tdeioslave/media/mimetypes/cdrom_mounted.desktop new file mode 100644 index 000000000..427951b57 --- /dev/null +++ b/tdeioslave/media/mimetypes/cdrom_mounted.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Icon=cdrom_mount +Type=MimeType +MimeType=media/cdrom_mounted +Comment=Mounted CD-ROM +Comment[af]=Gekoppelde CD-ROM +Comment[ar]=قرص مدمج مركب +Comment[az]=Bağlanmış CD-ROM +Comment[be]=Прымацаваны CD-ROM +Comment[bg]=Монтиран CD-ROM +Comment[bn]=মাউন্ট করা সিডি-রম +Comment[br]=CD-ROM marc'het +Comment[bs]=Montiran CD-ROM +Comment[ca]=CD-ROM muntat +Comment[cs]=Připojená CDROM +Comment[csb]=Zamòntowóny nëk CD +Comment[cy]=CD-ROM wedi ei osod +Comment[da]=Monteret cd-rom +Comment[de]=Eingebundene CD-ROM +Comment[el]=Προσαρτημένο CD-ROM +Comment[eo]=Surmetita nurlegebla LD +Comment[es]=CD-ROM montado +Comment[et]=Ühendatud CD-ROM +Comment[eu]=CD-ROM muntatua +Comment[fa]=CD-ROM سوارشده +Comment[fi]=Liitetty CD-ROM +Comment[fr]=CD-ROM monté +Comment[fy]=Oankeppele Kompaktskiif +Comment[ga]=CD-ROM feistithe +Comment[gl]=CD-ROM Montado +Comment[he]=תקליטור מחובר +Comment[hi]=माउन्टेड सीडी-रोम +Comment[hr]=Pristupljeni CD-ROM +Comment[hu]=Csatlakoztatott CD-ROM +Comment[is]=Tengt geisladrif +Comment[it]=CD-ROM montato +Comment[ja]=マウントされた CD-ROM +Comment[ka]=მონტირებული CD-ROM +Comment[kk]=Тіркеген CD-ROM +Comment[km]=CD-ROM បានរៀបចំ +Comment[lo]=ຈໍພາບ +Comment[lt]=Sumontuotas CD-ROM +Comment[lv]=Piemontēts CD-ROM +Comment[mk]=Монтиран ЦДРОМ +Comment[mn]=Залгагдсан КД-ROM +Comment[ms]=CD-ROM Terlekap +Comment[mt]=CDROM immontat +Comment[nb]=Montert CD-plate +Comment[nds]=Inhangt CD-ROM +Comment[ne]=माउन्ट गरिएको सीडी-रोम +Comment[nl]=Aangekoppelde cd-romschijf +Comment[nn]=Montert CD-ROM +Comment[nso]=CD-ROM yeo e Nameleditswego +Comment[pa]=ਮਾਊਟ ਕੀਤੀ CD-ROM +Comment[pl]=Zamontowany CD-ROM +Comment[pt]=CD-ROM montado +Comment[pt_BR]=CD-ROM Montado +Comment[ro]=CD-ROM montat +Comment[ru]=Смонтированный CD +Comment[rw]=CD-ROM Yashyizwemo +Comment[se]=Čatnon CD-ROM +Comment[sk]=Pripojený CD-ROM +Comment[sl]=Priklopljen CD-ROM +Comment[sr]=Монитран CD-ROM +Comment[sr@Latn]=Monitran CD-ROM +Comment[sv]=Monterad cd-rom +Comment[ta]=ஏற்றப்பட்ட சிடிராம் +Comment[tg]=Монтаж шудаи CD-ROM +Comment[th]=ซีดีรอมที่เม้านท์แล้ว +Comment[tr]=Bağlı CD-ROM +Comment[tt]=Totaşqan CD-ROM +Comment[uk]=Змонтований КД +Comment[uz]=Ulangan kompakt-disk +Comment[uz@cyrillic]=Уланган компакт-диск +Comment[ven]=CD-ROM yo gonyiswaho +Comment[vi]=Ổ CD ROM đã kết nối +Comment[wa]=Plake lazer CD montêye +Comment[xh]=CD-ROM Enyusiweyo +Comment[zh_CN]=挂载的 CD-ROM +Comment[zh_TW]=已掛載的 CD-ROM +Comment[zu]=I-CD-ROM eyenyusiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdrom_mounted_decrypted.desktop b/tdeioslave/media/mimetypes/cdrom_mounted_decrypted.desktop new file mode 100644 index 000000000..d8bd4f199 --- /dev/null +++ b/tdeioslave/media/mimetypes/cdrom_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdrom_mount_decrypt +Type=MimeType +MimeType=media/cdrom_mounted_decrypted +Comment=Mounted Decrypted CD-ROM +Comment[de]=Eingebundene, entschlüsselte CD-ROM +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdrom_unmounted.desktop b/tdeioslave/media/mimetypes/cdrom_unmounted.desktop new file mode 100644 index 000000000..3d35eef32 --- /dev/null +++ b/tdeioslave/media/mimetypes/cdrom_unmounted.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Icon=cdrom_unmount +Type=MimeType +MimeType=media/cdrom_unmounted +Comment=Unmounted CD-ROM +Comment[af]=Ontkoppel CD-ROM +Comment[ar]=قرص مدمج غير محمّل +Comment[az]=Ayrılmış CD-ROM +Comment[be]=Адмацаваны CD-ROM +Comment[bg]=Демонтиран CD-ROM +Comment[bn]=আনমাউন্ট করা সিডি-রম +Comment[br]=CD-ROM divountet +Comment[bs]=Demontiran CD-ROM +Comment[ca]=CD-ROM desmuntat +Comment[cs]=Odpojená CDROM +Comment[csb]=Òdmòntowóny nëk CD +Comment[cy]=CD-ROM wedi'i ddadosod +Comment[da]=Afmonteret cd-rom +Comment[de]=Nicht eingebundene CD-ROM +Comment[el]=Αποπροσαρτημένο CD-ROM +Comment[eo]=Demetita nurlegebla LD +Comment[es]=CD-ROM desmontado +Comment[et]=Lahutatud CD-ROM +Comment[eu]=CD-ROM desmuntatua +Comment[fa]=CD-ROM پیادهشده +Comment[fi]=Irrotettu CD-ROM +Comment[fr]=CD-ROM non monté +Comment[fy]=Ofkeppele Kompaktskiif +Comment[ga]=CD-ROM neamhfheistithe +Comment[gl]=CD-ROM Non Montado +Comment[he]=תקליטור מנותק +Comment[hi]=अनमाउन्टेड सीडी-रोम +Comment[hr]=Nepristupljeni CD-ROM +Comment[hsb]=Njemontowany CDnik +Comment[hu]=Leválasztott CD-ROM +Comment[is]=Aftengt geisladrif +Comment[it]=CD-ROM smontato +Comment[ja]=マウントされていない CD-ROM +Comment[ka]=დემონტირებული CD-ROM +Comment[kk]=Тіркеуден шығарған CD-ROM +Comment[km]=CD-ROM មិនបានរៀបចំ +Comment[lo]=ຫັງກາລີ +Comment[lt]=Išmontuotas CD-ROM +Comment[lv]=Nomontēts CD-ROM +Comment[mk]=Одмонтиран ЦДРОМ +Comment[mn]=Салгаатай КД-ROM +Comment[ms]=CD-ROM Nyahlekap +Comment[mt]=CDROM mhux immontat +Comment[nb]=Avmontert CD-plate +Comment[nds]=Afhangt CD-ROM +Comment[ne]=अनमाउन्ट गरिएको सीडी-रोम +Comment[nl]=Afgekoppelde cd-romschijf +Comment[nn]=Avmontert CD-ROM +Comment[nso]=CD-ROM yeo e Theositswego +Comment[pa]=ਅਨਮਾਊਟ ਕੀਤੀ CD-ROM +Comment[pl]=Odmontowany CD-ROM +Comment[pt]=CD-ROM desmontado +Comment[pt_BR]=CD-ROM Desmontado +Comment[ro]=CD-ROM nemontat +Comment[ru]=Отмонтированный CD +Comment[rw]=CD-ROM Yakuwemo +Comment[se]=Gálgajuvvon CD-ROM +Comment[sk]=Nepripojený CD-ROM +Comment[sl]=Odklopljen CD-ROM +Comment[sr]=Демонтиран CD-ROM +Comment[sr@Latn]=Demontiran CD-ROM +Comment[sv]=Avmonterad cd-rom +Comment[ta]=வெளியேற்றிய குறுந்தகடு +Comment[tg]=Ҷудо шудаи CD-ROM +Comment[th]=ซีดีรอมที่ไม่ได้เม้านท์ +Comment[tr]=Ayrılmış CD-ROM +Comment[tt]=Totaşmağan CD-ROM +Comment[uk]=Демонтований КД +Comment[uz]=Ulanmagan kompakt-disk +Comment[uz@cyrillic]=Уланмаган компакт-диск +Comment[ven]=CD-ROM i songo gonyiswaho +Comment[vi]=Ổ CD-ROM đã gỡ ra +Comment[wa]=Plake lazer CD dismontêye +Comment[xh]=CD-ROM Enganyuswanga +Comment[zh_CN]=未挂载的 CD-ROM +Comment[zh_TW]=未掛載的 CD-ROM +Comment[zu]=I-CD-ROM eyehlisiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop b/tdeioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop new file mode 100644 index 000000000..c53abbc82 --- /dev/null +++ b/tdeioslave/media/mimetypes/cdrom_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdrom_unmount_decrypt +Type=MimeType +MimeType=media/cdrom_unmounted_decrypted +Comment=Unmounted Decrypted CD-ROM +Comment[de]=Nicht eingebundene, entschlüsselte CD-ROM +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop b/tdeioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop new file mode 100644 index 000000000..f11e43807 --- /dev/null +++ b/tdeioslave/media/mimetypes/cdrom_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdrom_unmount_encrypt +Type=MimeType +MimeType=media/cdrom_unmounted_encrypted +Comment=Unmounted Encrypted CD-ROM +Comment[de]=Nicht eingebundene, verschlüsselte CD-ROM +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdwriter_mounted.desktop b/tdeioslave/media/mimetypes/cdwriter_mounted.desktop new file mode 100644 index 000000000..88739824f --- /dev/null +++ b/tdeioslave/media/mimetypes/cdwriter_mounted.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Icon=cdwriter_mount +Type=MimeType +MimeType=media/cdwriter_mounted +Comment=Mounted CD Writer +Comment[af]=Gekoppelde Cd Skrywer +Comment[ar]=ناسخ أقراص محمّل +Comment[az]=Bağlanmış CD Yazıcı +Comment[be]=Прымацаваны запісвальнік CD +Comment[bg]=Монтиран компактдиск +Comment[bn]=মাউন্ট করা সিডি-রাইটার +Comment[br]=Engraver CD marc'het +Comment[bs]=Montiran CD pisač +Comment[ca]=CD Writer muntat +Comment[cs]=Připojená vypalovačka CD +Comment[csb]=Zamòntowóny wëpôlôrz CD +Comment[cy]=Ysgrifennwr CD wedi'i osod +Comment[da]=Monteret cd-skriver +Comment[de]=Eingebundener CD-Brenner +Comment[el]=Προσαρτημένο CD Writer +Comment[eo]=Surmetita skribebla LD +Comment[es]=Escritor de CDs montado +Comment[et]=Ühendatud CD kirjutaja +Comment[eu]=CD erretzaile muntatua +Comment[fa]=CD Writer سوارشده +Comment[fi]=Liitetty CD-kirjoitin +Comment[fr]=Graveur de CD monté +Comment[fy]=Oankeppele Kompaktskiif +Comment[ga]=Scríbhneoir Feistithe CDanna +Comment[gl]=Grabadora de CD Montada +Comment[he]=צורב מחובר +Comment[hi]=माउन्टेड सीडी-राइटर +Comment[hr]=Pristupljeni CD snimač +Comment[hsb]=Montowany CD-palak +Comment[hu]=Csatlakoztatott CD-író +Comment[is]=Tengdur geislaskrifari +Comment[it]=Masterizzatore montato +Comment[ja]=マウントされている CD ライター +Comment[ka]=მონტირებული CD Writer +Comment[kk]=Тіркеген CD Writer +Comment[km]=ឧបករណ៍សរសេរស៊ីឌីបានរៀបចំ +Comment[lo]= ຈໍພາບ +Comment[lt]=Sumontuotas CD rašymo įrenginys +Comment[lv]=Piemontēts CD rakstītājs +Comment[mk]=Монтиран ЦД-снимач +Comment[mn]=Залгагдсан КД-шарагч +Comment[ms]=Penulis CD Terlekap +Comment[mt]=CDWriter immontat +Comment[nb]=Montert CD-brenner +Comment[nds]=Inhangt CD-Brenner +Comment[ne]=माउन्ट गरिएको सीडी राइटर +Comment[nl]=Aangekoppelde cd-writer +Comment[nn]=Montert CD-brennar +Comment[nso]=Sengwadi sa CD seo se Nameleditswego +Comment[pa]=ਮਾਊਟ CD ਰਾਇਟਰ +Comment[pl]=Zamontowana nagrywarka CD +Comment[pt]=Gravador de CDs montado +Comment[pt_BR]=Gravador de CD Montado +Comment[ro]=CD Writer montat +Comment[ru]=Смонтированный CD (с возможностью записи) +Comment[rw]=Mwandika CD Yashyizwemo +Comment[se]=Čatnon CD-čálli +Comment[sk]=Pripojená napaľovacia mechanika CD +Comment[sl]=Priklopljen zapisovalnik CD-jev +Comment[sr]=Монтиран CD резач +Comment[sr@Latn]=Montiran CD rezač +Comment[sv]=Monterad cd-brännare +Comment[ta]=ஏற்றப்பட்ட குறுந்தகடு எழுதி +Comment[tg]=Монтажшудаи CD Writer +Comment[th]=เครื่องเขียนซีดีที่เม้านท์แล้ว +Comment[tr]=Bağlı CD Yazıcı +Comment[tt]=Totaşqan CD Yazdırğıç +Comment[uk]=Змонтований гравер КД +Comment[uz]=Ulangan kompakt-disk yozuvchi +Comment[uz@cyrillic]=Уланган компакт-диск ёзувчи +Comment[ven]=Tshinwali tsha CD tsho gonyiswaho +Comment[vi]=Ổ ghi CD đã kết nối +Comment[wa]=Plake lazer CD sol broûleu montêye +Comment[xh]=CD Writer Enyusiweyo +Comment[zh_CN]=挂载的刻录机 +Comment[zh_TW]=已掛載的 CD Writer +Comment[zu]=I-CD-Writer eyenyusiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop b/tdeioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop new file mode 100644 index 000000000..e3e8877d1 --- /dev/null +++ b/tdeioslave/media/mimetypes/cdwriter_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdwriter_mount_decrypt +Type=MimeType +MimeType=media/cdwriter_mounted_decrypted +Comment=Mounted Decrypted CD Writer +Comment[de]=Eingebundener, entschlüsselter CD-Brenner +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdwriter_unmounted.desktop b/tdeioslave/media/mimetypes/cdwriter_unmounted.desktop new file mode 100644 index 000000000..357e197d4 --- /dev/null +++ b/tdeioslave/media/mimetypes/cdwriter_unmounted.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Icon=cdwriter_unmount +Type=MimeType +MimeType=media/cdwriter_unmounted +Comment=Unmounted CD Writer +Comment[af]=Ontkoppelde CD Skrywer +Comment[ar]=ناسخ أقراص غير محمّل +Comment[az]=Ayrılmış CD Yazıcı +Comment[be]=Адмацаваны запісвальнік CD +Comment[bg]=Демонтиран компактдиск +Comment[bn]=আনমাউন্ট করা সিডি-রাইটার +Comment[br]=Engraver CD divarc'het +Comment[bs]=Demontiran CD pisač +Comment[ca]=CD Writer desmuntat +Comment[cs]=Odpojená vypalovačka CD +Comment[csb]=Òdmòntowóny wëpôlôrz CD +Comment[cy]=Ysgrifennwr CD wedi'i ddadosod +Comment[da]=Afmonteret cd-skriver +Comment[de]=Nicht eingebundener CD-Brenner +Comment[el]=Αποπροσαρτημένο CD Writer +Comment[eo]=Demetita skribebla LD +Comment[es]=Escritor de CDs desmontado +Comment[et]=Lahutatud CD kirjutaja +Comment[eu]=CD erretzaile desmuntatua +Comment[fa]=CD Writer پیادهشده +Comment[fi]=Irrotettu CD-kirjoitin +Comment[fr]=Graveur de CD non monté +Comment[fy]=Ofkeppele Kompaktskiif +Comment[ga]=Scríbhneoir Neamhfheistithe CDanna +Comment[gl]=Grabadora de CD Non Montada +Comment[he]=צורב מנותק +Comment[hi]=अनमाउन्टेड सीडी-राइटर +Comment[hr]=Nepristupljeni CD snimač +Comment[hsb]=Njemontowany CD-palak +Comment[hu]=Leválasztott CD-író +Comment[is]=Aftengdur geislaskrifari +Comment[it]=Masterizzatore smontato +Comment[ja]=マウントされていない CD ライター +Comment[ka]=დემონტირებული CD Writer +Comment[kk]=Ажыратылған CD Writer +Comment[km]=ឧបករណ៍សរសេរស៊ីឌីមិនបានរៀបចំ +Comment[lo]= ຫັງກາລີ +Comment[lt]=Išmontuotas CD rašymo įrenginys +Comment[lv]=Nomontēts CD rakstītājs +Comment[mk]=Одмонтиран ЦД-снимач +Comment[mn]=Салгагдсан КД-шарагч +Comment[ms]=Penulis CD Nyahlekap +Comment[mt]=CDWriter mhux immontat +Comment[nb]=Avmontert CD-brenner +Comment[nds]=Afhangt CD-Brenner +Comment[ne]=अनमाउन्ट गरिएको सीडी राइटर +Comment[nl]=Afgekoppelde cd-writer +Comment[nn]=Avmontert CD-brennar +Comment[nso]=Sengwadi sa CD seo se Theositswego +Comment[pa]=ਅਨਮਾਊਟ CD ਰਾਇਟਰ +Comment[pl]=Odmontowana nagrywarka CD +Comment[pt]=Gravador de CDs desmontado +Comment[pt_BR]=Gravador de CD Desmontado +Comment[ro]=CD Writer nemontat +Comment[ru]=Отмонтированный CD (с возможностью записи) +Comment[rw]=Mwandika CD Yakuwemo +Comment[se]=Gálgajuvvon CD-čálli +Comment[sk]=Nepripojená napaľovacia mechanika CD +Comment[sl]=Odklopljen zapisovalnik CD-jev +Comment[sr]=Демонтиран CD резач +Comment[sr@Latn]=Demontiran CD rezač +Comment[sv]=Avmonterad cd-brännare +Comment[ta]=வெளியேற்றிய குறுந்தகடு எழுதி +Comment[tg]=Ҷудо шудаи CD Writer +Comment[th]=เครื่องเขียนซีดีที่ไม่ได้กเม้านท์ +Comment[tr]=Ayrılmış CD Yazıcı +Comment[tt]=Totaşmağan CD Yazdırğıç +Comment[uk]=Демонтований гравер КД +Comment[uz]=Ulanmagan kompakt-disk yozuvchi +Comment[uz@cyrillic]=Уланмаган компакт-диск ёзувчи +Comment[ven]=Tshinwali tsha CD tshi songo gonyiswaho +Comment[vi]=Ổ ghi CD đã gỡ ra +Comment[wa]=Plake lazer CD sol broûleu dismontêye +Comment[xh]=CD Writer Enganyuswanga +Comment[zh_CN]=未挂载的刻录机 +Comment[zh_TW]=未掛載的 CD Writer +Comment[zu]=I-CD-Writer eyehlisiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop b/tdeioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop new file mode 100644 index 000000000..e81c0b857 --- /dev/null +++ b/tdeioslave/media/mimetypes/cdwriter_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdwriter_unmount_decrypt +Type=MimeType +MimeType=media/cdwriter_unmounted_decrypted +Comment=Unmounted Decrypted CD Writer +Comment[de]=Nicht eingebundener, entschlüsselter CD-Brenner +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop b/tdeioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop new file mode 100644 index 000000000..5eb9f3396 --- /dev/null +++ b/tdeioslave/media/mimetypes/cdwriter_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=cdwriter_unmount_encrypt +Type=MimeType +MimeType=media/cdwriter_unmounted_encrypted +Comment=Unmounted Encrypted CD Writer +Comment[de]=Nicht eingebundener, entschlüsselter CD-Brenner +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/dvd_mounted.desktop b/tdeioslave/media/mimetypes/dvd_mounted.desktop new file mode 100644 index 000000000..7e0ff307b --- /dev/null +++ b/tdeioslave/media/mimetypes/dvd_mounted.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Icon=dvd_mount +Type=MimeType +MimeType=media/dvd_mounted +Comment=Mounted DVD +Comment[af]=Gekoppelde DVD +Comment[ar]=DVD محمّل +Comment[az]=Bağlanmış DVD +Comment[be]=Прымацаваны DVD +Comment[bg]=Монтиран DVD диск +Comment[bn]=মাউন্ট করা ডিভিডি +Comment[br]=DVD marc'het +Comment[bs]=Montiran DVD +Comment[ca]=DVD muntat +Comment[cs]=Připojené DVD +Comment[csb]=Zamòntowóny nëk DVD +Comment[cy]=DVD wedi'i osod +Comment[da]=Monteret dvd +Comment[de]=Eingebundene DVD +Comment[el]=Προσαρτημένο DVD +Comment[eo]=Surmetita DVD +Comment[es]=DVD montado +Comment[et]=Ühendatud DVD +Comment[eu]=DVD muntatua +Comment[fa]=DVD سوارشده +Comment[fi]=Liitetty DVD-levy +Comment[fr]=DVD-ROM monté(s) +Comment[fy]=Oankeppele Dûbelskiif +Comment[ga]=DVD feistithe +Comment[gl]=DVD Montado +Comment[he]=כונן DVD מחובר +Comment[hi]=माउन्टेड डीवीडी +Comment[hr]=Pristupljeni DVD +Comment[hu]=Csatlakoztatott DVD +Comment[is]=Tengt DVD +Comment[it]=DVD montato +Comment[ja]=マウントされた DVD +Comment[ka]=მონტირებული DVD +Comment[kk]=Тіркеген DVD +Comment[km]=ឌីវីឌីដែលបានរៀបចំ +Comment[lo]=ຈໍພາບ +Comment[lt]=Sumontuotas DVD +Comment[lv]=Piemontēts DVD +Comment[mk]=Монтиран DVD +Comment[mn]=Залгагдсан DVD +Comment[ms]=DVD Terlekap +Comment[mt]=DVD immontat +Comment[nb]=Montert DVD +Comment[nds]=Inhangt DVD +Comment[ne]=माउन्ट गरिएको डी भी डी +Comment[nl]=Aangekoppelde dvd-romschijf +Comment[nn]=Montert DVD +Comment[pa]=ਮਾਊਟ ਕੀਤੀ DVD +Comment[pl]=Zamontowany DVD +Comment[pt]=DVD montado +Comment[pt_BR]=DVD Montado +Comment[ro]=DVD montat +Comment[ru]=Смонтированный DVD +Comment[rw]=DVD Yashyizwemo +Comment[se]=Čatnon DVD +Comment[sk]=Pripojené DVD +Comment[sl]=Priklopljen DVD +Comment[sr]=Монтиран DVD +Comment[sr@Latn]=Montiran DVD +Comment[sv]=Monterad dvd +Comment[ta]=ஏற்றப்பட்ட சிடிராம் +Comment[tg]=Монтажшудаи DVD +Comment[th]=ดีวีดีที่เม้านท์แล้ว +Comment[tr]=Bağlı DVD +Comment[tt]=Totaşqan DVD +Comment[uk]=Змонтований DVD +Comment[uz]=Ulangan DVD +Comment[uz@cyrillic]=Уланган DVD +Comment[vi]=DVD đã kết nối +Comment[wa]=Plake lazer DVD montêye +Comment[zh_CN]=挂载的 DVD +Comment[zh_TW]=已掛載的 DVD-ROM +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/dvd_mounted_decrypted.desktop b/tdeioslave/media/mimetypes/dvd_mounted_decrypted.desktop new file mode 100644 index 000000000..ac5f34db9 --- /dev/null +++ b/tdeioslave/media/mimetypes/dvd_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=dvd_mount_decrypt +Type=MimeType +MimeType=media/dvd_mounted_decrypted +Comment=Mounted Decrypted DVD +Comment[de]=Eingebundene, entschlüsselte DVD +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/dvd_unmounted.desktop b/tdeioslave/media/mimetypes/dvd_unmounted.desktop new file mode 100644 index 000000000..4b6785e34 --- /dev/null +++ b/tdeioslave/media/mimetypes/dvd_unmounted.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Icon=dvd_unmount +Type=MimeType +MimeType=media/dvd_unmounted +Comment=Unmounted DVD +Comment[af]=Ontkoppelde DVD +Comment[ar]=DVD غير محمّل +Comment[az]=Ayrılmış DVD +Comment[be]=Адмацаваны DVD +Comment[bg]=Демонтиран DVD диск +Comment[bn]=আনমাউন্ট করা ডিভিডি +Comment[br]=DVD-ROM divountet +Comment[bs]=Demontiran DVD +Comment[ca]=DVD desmuntat +Comment[cs]=Odpojené DVD +Comment[csb]=Òdmòntowóny nëk DVD +Comment[cy]=DVD wedi'i ddadosod +Comment[da]=Afmonteret dvd +Comment[de]=Nicht eingebundene DVD +Comment[el]=Αποπροσαρτημένο DVD +Comment[eo]=Demetita DVD +Comment[es]=DVD desmontado +Comment[et]=Lahutatud DVD +Comment[eu]=DVD desmuntatua +Comment[fa]=DVD پیادهشده +Comment[fi]=Irrotettu DVD-levy +Comment[fr]=DVD-ROM non monté(s) +Comment[fy]=Ofkeppele Dûbelskiif +Comment[ga]=DVD neamhfheistithe +Comment[gl]=DVD non Montado +Comment[he]=כונן DVD מנותק +Comment[hi]=अनमाउन्टेड डीवीडी +Comment[hr]=Nepristupljeni DVD +Comment[hu]=Leválasztott DVD +Comment[is]=Aftengt DVD +Comment[it]=DVD smontato +Comment[ja]=マウントされていない DVD +Comment[ka]=დემონტირებული DVD +Comment[kk]=Тіркеуден шығарған DVD +Comment[km]=ឌីវីឌីដែលមិនបានរៀបចំ +Comment[lo]=ຫັງກາລີ +Comment[lt]=Išmontuotas DVD +Comment[lv]=Nomontēts DVD +Comment[mk]=Одмонтиран DVD +Comment[mn]=Салгаатай DVD +Comment[ms]=DVD Nyahlekap +Comment[mt]=DVD mhux immontat +Comment[nb]=Avmontert DVD +Comment[nds]=Afhangt DVD +Comment[ne]=अनमाउन्ट गरिएको डी भी डी +Comment[nl]=Afgekoppelde dvd-romschijf +Comment[nn]=Avmontert DVD +Comment[pa]=ਅਨਮਾਊਟ ਕੀਤੀ DVD +Comment[pl]=Odmontowany DVD +Comment[pt]=DVD desmontado +Comment[pt_BR]=DVD Desmontado +Comment[ro]=DVD nemontat +Comment[ru]=Отмонтированный DVD +Comment[rw]=DVD Yakuwemo +Comment[se]=Gálgajuvvon DVD +Comment[sk]=Nepripojené DVD +Comment[sl]=Odklopljen DVD +Comment[sr]=Демонтиран DVD +Comment[sr@Latn]=Demontiran DVD +Comment[sv]=Avmonterad dvd +Comment[ta]=இறக்கப்பட்ட சிடிராம் +Comment[tg]=Ғайри монтажшудаи DVD +Comment[th]=ดีวีดีที่ไม่ได้เม้านท์ +Comment[tr]=Ayrılmış DVD +Comment[tt]=Totaşmağan DVD +Comment[uk]=Демонтований DVD +Comment[uz]=Ulanmagan DVD +Comment[uz@cyrillic]=Уланмаган DVD +Comment[vi]=DVD đã gỡ ra +Comment[wa]=Plake lazer DVD dismontêye +Comment[zh_CN]=未挂载的 DVD +Comment[zh_TW]=未掛載的 DVD-ROM +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/dvd_unmounted_decrypted.desktop b/tdeioslave/media/mimetypes/dvd_unmounted_decrypted.desktop new file mode 100644 index 000000000..a34f174ea --- /dev/null +++ b/tdeioslave/media/mimetypes/dvd_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=dvd_unmount_decrypt +Type=MimeType +MimeType=media/dvd_unmounted_decrypted +Comment=Unmounted Decrypted DVD +Comment[de]=Nicht eingebundene, entschlüsselte DVD +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/dvd_unmounted_encrypted.desktop b/tdeioslave/media/mimetypes/dvd_unmounted_encrypted.desktop new file mode 100644 index 000000000..e6eba099d --- /dev/null +++ b/tdeioslave/media/mimetypes/dvd_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=dvd_unmount_encrypt +Type=MimeType +MimeType=media/dvd_unmounted_encrypted +Comment=Unmounted Encrypted DVD +Comment[de]=Nicht eingebundene, verschlüsselte DVD +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/dvdvideo.desktop b/tdeioslave/media/mimetypes/dvdvideo.desktop new file mode 100644 index 000000000..8a7d44c52 --- /dev/null +++ b/tdeioslave/media/mimetypes/dvdvideo.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Type=MimeType +MimeType=media/dvdvideo +Comment=DVD Video Disk +Comment[af]=DVD Video skyf +Comment[ar]=قرص رقمي مرئي للمرئيات +Comment[be]=Відэадыск DVD +Comment[bg]=Видео DVD диск +Comment[bn]=ডিভিডি ভিডিও ডিস্ক +Comment[br]=Pladenn DVD Video +Comment[bs]=DVD video disk +Comment[ca]=Vídeo disc DVD +Comment[cs]=DVD video +Comment[csb]=Disk DVD Video +Comment[da]=Dvd video-disk +Comment[de]=DVD Video-Disk +Comment[el]=Δίσκος DVD (βίντεο) +Comment[eo]=DVDa videodisko +Comment[es]=Disco de video DVD +Comment[et]=DVD videoplaat +Comment[eu]=DVD bideo diska +Comment[fa]=دیسک ویدیویی DVD +Comment[fi]=DVD-videolevy +Comment[fr]=DVD vidéo +Comment[fy]=Dûbelskiif Fideoskiif +Comment[ga]=Físdiosca DVD +Comment[gl]=DVD de vídeo +Comment[he]=תקליטור וידאו של DVD +Comment[hi]=डीवीडी वीडियो डिस्क +Comment[hr]=DVD video disk +Comment[hu]=DVD-videolemez +Comment[is]=DVD vídeódiskur +Comment[it]=Disco video DVD +Comment[ja]=DVD ビデオディスク +Comment[ka]=ვიდეო DVD დისკი +Comment[kk]=DVD бейне дискі +Comment[km]=ថាសវីដេអូ ឌីវីឌី +Comment[lt]=DVD video diskas +Comment[lv]=DVD Video Disks +Comment[mk]=DVD Видеодиск +Comment[ms]=Cakera Video DVD +Comment[nb]=DVD-videoplate +Comment[nds]=DVD-Videodisk +Comment[ne]=डी भी डी भिडियो डिस्क +Comment[nl]=DVD Videodisk +Comment[nn]=DVD-videoplate +Comment[pa]=DVD ਵੀਡਿਓ ਡਿਸਕ +Comment[pl]=Płyta DVD Video +Comment[pt]=Disco DVD de Vídeo +Comment[pt_BR]=DVD de vídeo +Comment[ro]=Disc video DVD +Comment[ru]=DVD с видео +Comment[rw]=Disiki Videwo DVD +Comment[se]=DVD-videoskearru +Comment[sk]=DVD Video disk +Comment[sl]=DVD Video disk +Comment[sr]=DVD видео диск +Comment[sr@Latn]=DVD video disk +Comment[sv]=Dvd-videoskiva +Comment[ta]=டிவிடி படக்காட்சி வட்டு +Comment[te]=డివిడి విడియొ డిస్క్ +Comment[th]=แผ่นดีวีดีภาพยนตร์ +Comment[tr]=DVD Video +Comment[uk]=Відео диск DVD +Comment[uz]=DVD video-disk +Comment[uz@cyrillic]=DVD видео-диск +Comment[vi]=Đĩa Video DVD +Comment[wa]=Plake videyo DVD +Comment[zh_CN]=DVD 影碟 +Comment[zh_TW]=DVD 視訊光碟 +Icon=dvd_unmount + +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/floppy5_mounted.desktop b/tdeioslave/media/mimetypes/floppy5_mounted.desktop new file mode 100644 index 000000000..8439720a2 --- /dev/null +++ b/tdeioslave/media/mimetypes/floppy5_mounted.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Icon=5floppy_mount +Type=MimeType +MimeType=media/floppy5_mounted +Comment=Mounted 5¼" Floppy +Comment[af]=Gekoppelde 5¼" Sagteskyf +Comment[ar]=قرص مرن 5.25 محمّل +Comment[az]=Bağlanmış 5¼" Floppi +Comment[be]=Прымацаваная дыскета 5¼" +Comment[bg]=Монтирано 5¼" флопи +Comment[bn]=মাউন্ট করা 5¼" ফ্লপি +Comment[br]=Pladennig 5¼" marc'het +Comment[bs]=Montirana 5?" disketa +Comment[ca]=Disquet 5¼" muntat +Comment[cs]=Připojená disketa 5¼" +Comment[csb]=Zamòntowónô disczétka 5¼" +Comment[cy]=Disg meddal 5.25" wedi'i osod +Comment[da]=Monteret 5¼"-floppy +Comment[de]=Eingebundene 5¼"-Diskette +Comment[el]=Προσαρτημένη δισκέτα 5¼" +Comment[eo]=Surmetita 5¼"-Disketo +Comment[es]=Disquete 5¼" montado +Comment[et]=Ühendatud 5¼" flopi +Comment[eu]=5¼"ko diskete muntatua +Comment[fa]=فلاپی 5¼" سوارشده +Comment[fi]=Liitetty 5¼"-levyke +Comment[fr]=Disquette 5¼" montée +Comment[fy]=Oankeppele 5¼" Skiif +Comment[ga]=Diosca flapach 5¼" feistithe +Comment[gl]=Disquete 5¼" Montado +Comment[he]=תקליטון "¼5 מחובר +Comment[hi]=माउन्टेड 5¼" फ़्लॉपी +Comment[hr]=Pristupljena 5¼" disketa +Comment[hu]=Csatlakoztatott 5¼"-es floppy +Comment[is]=Tengdur 5¼" disklingur +Comment[it]=Dischetto da 5¼" montato +Comment[ja]=マウントされた 5 インチフロッピー +Comment[ka]=მონტირებული დისკწამყვანი 5¼" +Comment[kk]=Тіркеген 5¼" иілгіш диск +Comment[km]=5¼" Floppy បានរៀបចំ +Comment[lo]=ຟໍແມດຟອປີ້ - K +Comment[lt]=Sumontuotas 5¼" lankstus diskelis +Comment[lv]=Piemontēta 5¼" diskete +Comment[mk]=Монтирана 5¼" дискета +Comment[mn]=Залгагдсан 5¼"-Уян диск +Comment[ms]=Liut 5¼" Terlekap +Comment[mt]=Flopi 5¼" immontat +Comment[nb]=Montert 5¼" diskett +Comment[nds]=Inhangt 5¼"-Diskett +Comment[ne]=माउन्ट गरिएको 5¼" फ्लपी +Comment[nl]=Aangekoppelde 5¼" diskette +Comment[nn]=Montert 5¼"-diskett +Comment[nso]=Floppy yeo e Nameleditswego ya 5¼" +Comment[pa]=ਮਾਊਟ 5¼" ਫਲਾਪੀ +Comment[pl]=Zamontowana dyskietka 5¼" +Comment[pt]=Disquete de 5¼" montada +Comment[pt_BR]=Disquete 5¼" Montado +Comment[ro]=Dischetă 5¼" montată +Comment[ru]=Смонтированная дискета 5¼" +Comment[rw]=Disikete 5¼" Yashyizwemo +Comment[se]=Čatnon 5¼-dibmaskearru +Comment[sk]=Pripojená disketa 5¼" +Comment[sl]=Priklopljena disketna enota 5¼" +Comment[sr]=Монтиран 5¼" флопи +Comment[sr@Latn]=Montiran 5¼" flopi +Comment[sv]=Monterad 5¼"-diskett +Comment[ta]=ஏற்றப்பட்ட 5¼" நெகிழ்வட்டு +Comment[tg]=Монтажшудаи 5¼" Флоппи +Comment[th]=ฟล็อปปี 5" ที่เม้านท์แล้ว +Comment[tr]=Bağlı 5¼" Disket +Comment[tt]=Totaşqan 5¼" Floppy +Comment[uk]=Змонтований флопі 5¼" +Comment[uz]=Ulangan 5¼"disket +Comment[uz@cyrillic]=Уланган 5¼"дискет +Comment[ven]=5¼" Floppy yo gonyiswaho +Comment[vi]=Đĩa mềm 5¼" đã kết nối +Comment[wa]=Plakete 5" ¼ montêye +Comment[xh]=Elayishiweyo 5¼" Floppy +Comment[zh_CN]=挂载的 5.25 英寸软驱 +Comment[zh_TW]=已掛載的軟碟機 +Comment[zu]=I-5¼" Floppy eyenyusiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/floppy5_unmounted.desktop b/tdeioslave/media/mimetypes/floppy5_unmounted.desktop new file mode 100644 index 000000000..2e23cd6eb --- /dev/null +++ b/tdeioslave/media/mimetypes/floppy5_unmounted.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Icon=5floppy_unmount +Type=MimeType +MimeType=media/floppy5_unmounted +Comment=Unmounted 5¼" Floppy +Comment[af]=Ontkoppelde 5¼" Sagteskyf +Comment[ar]=قرص مرن 5.25 غير محمّل +Comment[az]=Ayrılmış 5¼" Floppi +Comment[be]=Адмацаваная дыскета 5¼" +Comment[bg]=Демонтирано 5¼" флопи +Comment[bn]=আনমাউন্ট করা 5¼" ফ্লপি +Comment[br]=Pladennig 5¼" divountet +Comment[bs]=Demontirana 5?" disketa +Comment[ca]=Disquet 5¼" desmuntat +Comment[cs]=Odpojená disketa 5¼" +Comment[csb]=Òdmòntowónô disczétka 5¼" +Comment[cy]=Disg meddal 5.25" wedi'i ddadosod +Comment[da]=Afmonteret 5¼"-floppy +Comment[de]=Nicht eingebundene 5¼"-Diskette +Comment[el]=Αποπροσαρτημένη δισκέτα 5¼" +Comment[eo]=Demetita 5¼"-Disketo +Comment[es]=Disquete 5¼" desmontado +Comment[et]=Lahutatud 5¼" flopi +Comment[eu]=5¼"ko diskete desmuntatua +Comment[fa]=فلاپی 5¼" پیادهشده +Comment[fi]=Irrotettu 5¼"-levyke +Comment[fr]=Disquette 5¼" non montée +Comment[fy]=Ofkeppele 5¼" Skiif +Comment[ga]=Diosca flapach 5¼" neamhfheistithe +Comment[gl]=Disquete 5¼" Non Montado +Comment[he]=תקליטון "¼5 מנותק +Comment[hi]=अनमाउन्टेड 5¼" फ़्लॉपी +Comment[hr]=Nepristupljena 5¼" disketa +Comment[hu]=Leválasztott 5¼"-es floppy +Comment[is]=Aftengdur 5¼" disklingur +Comment[it]=Dischetto da 5¼" non montato +Comment[ja]=マウントされていない 5 インチフロッピー +Comment[ka]=დემონტირებული დისკწამყვანი 5¼" +Comment[kk]=Тіркеуден шығарған 5¼" иілгіш дискі +Comment[km]=5¼" Floppy មិនបានរៀបចំ +Comment[lo]=ຫັງກາລີ +Comment[lt]=Išmontuotas 5¼" lankstus diskelis +Comment[lv]=Nomontēta 5¼" diskete +Comment[mk]=Одмонтирана 5¼" дискета +Comment[mn]=Салгагдсан 5¼"-Уян диск +Comment[ms]=Liut 5¼" Terlekap +Comment[mt]=Flopi 5¼" mhux immontat +Comment[nb]=Avmontert 5¼" diskett +Comment[nds]=Afhangt 5¼"-Diskett +Comment[ne]=अनमाउन्ट गरिएको 5¼" फ्लपी +Comment[nl]=Afgekoppelde 5¼" diskette +Comment[nn]=Avmontert 5¼"-diskett +Comment[nso]=Floppy yeo e Theositswego ya 5¼" +Comment[pa]=ਅਨਮਾਊਟ 5¼" ਫਲਾਪੀ +Comment[pl]=Odmontowana dyskietka 5¼" +Comment[pt]=Disquete de 5¼" desmontada +Comment[pt_BR]=Disquete 5¼" Desmontado +Comment[ro]=Dischetă 5¼" nemontată +Comment[ru]=Отмонтированная дискета 5¼" +Comment[rw]=Disikete 5¼" Yakuwemo +Comment[se]=Gálgajuvvon 5¼-dibmaskearru +Comment[sk]=Nepripojená disketa 5¼" +Comment[sl]=Odklopljena disketna enota 5¼" +Comment[sr]=Демонтиран 5¼" флопи +Comment[sr@Latn]=Demontiran 5¼" flopi +Comment[sv]=Avmonterad 5¼"-diskett +Comment[ta]=வெளியேற்றிய 5¼" நெகிழ்வட்டு +Comment[tg]=Ҷудо шудаи 5¼" Флоппи +Comment[th]=ฟล็อปปี 5" ที่ไม่ได้เม้านท์ +Comment[tr]=Bağlı olmayan 5¼" Disket +Comment[tt]=Totaşqan 5¼" Floppy +Comment[uk]=Демонтований флопі 5¼" +Comment[uz]=Ulanmagan 5¼"disket +Comment[uz@cyrillic]=Уланмаган 5¼"дискет +Comment[ven]=5¼" Floppy i songo gonyiswaho +Comment[vi]=Đĩa mềm 5¼" đã gỡ ra +Comment[wa]=Plakete 5" ¼ dismontêye +Comment[xh]=Enganyuswanga 5¼" Floppy +Comment[zh_CN]=未挂载的 5.25 英寸软驱 +Comment[zh_TW]=未掛載的軟碟機 +Comment[zu]=I-5¼" Floppy Yehlisiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/floppy_mounted.desktop b/tdeioslave/media/mimetypes/floppy_mounted.desktop new file mode 100644 index 000000000..ee0c1075c --- /dev/null +++ b/tdeioslave/media/mimetypes/floppy_mounted.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Icon=3floppy_mount +Type=MimeType +MimeType=media/floppy_mounted +Comment=Mounted Floppy +Comment[af]=Gekoppelde Sagteskyf +Comment[ar]=قرص مرن محمّل +Comment[az]=Bağlanmış Floppi +Comment[be]=Прымацаваная дыскета +Comment[bg]=Монтирано флопи +Comment[bn]=মাউন্ট করা ফ্লপি +Comment[br]=Pladennig marc'het +Comment[bs]=Montirana disketa +Comment[ca]=Disquet muntat +Comment[cs]=Připojená disketa +Comment[csb]=Zamòntowónô disczétka +Comment[cy]=Disg meddal wedi'i osod +Comment[da]=Monteret floppy +Comment[de]=Eingebundene Diskette +Comment[el]=Προσαρτημένη δισκέτα +Comment[eo]=Surmetita Disketo +Comment[es]=Disquete montado +Comment[et]=Ühendatud flopi +Comment[eu]=Diskete muntatua +Comment[fa]=فلاپی سوارشده +Comment[fi]=Liitetty levyke +Comment[fr]=Disquette montée +Comment[fy]=Oankeppele Skiif +Comment[ga]=Diosca flapach feistithe +Comment[gl]=Disquete Montado +Comment[he]=תקליטון מחובר +Comment[hi]=माउन्टेड फ़्लॉपी +Comment[hr]=Pristupljena disketa +Comment[hu]=Csatlakoztatott floppy +Comment[is]=Tengdur disklingur +Comment[it]=Dischetto montato +Comment[ja]=マウントされたフロッピー +Comment[ka]=მონტირებული დრეკადი დისკი +Comment[kk]=Тііркеген иілгіш диск +Comment[km]=Floppy បានរៀបចំ +Comment[lo]=ຟໍແມດຟອບປິ້້ - K +Comment[lt]=Sumontuotas lankstus diskelis +Comment[lv]=Piemontēta diskete +Comment[mk]=Монтирана дискета +Comment[mn]=Залгаатай уян диск +Comment[ms]=Liut Terlekap +Comment[mt]=Flopi mmontat +Comment[nb]=Montert diskett +Comment[nds]=Inhangt Diskett +Comment[ne]=माउन्ट गरिएको फ्लपी +Comment[nl]=Aangekoppelde diskette +Comment[nn]=Montert diskett +Comment[nso]=Floppy yeo e Nameleditswego +Comment[pa]=ਮਾਊਟ ਕੀਤੀ ਫਲਾਪੀ +Comment[pl]=Zamontowana dyskietka +Comment[pt]=Disquete montada +Comment[pt_BR]=Disquete Montado +Comment[ro]=Dischetă montată +Comment[ru]=Смонтированная дискета +Comment[rw]=Disikete Yashyizwemo +Comment[se]=Čatnon dibmaskearru +Comment[sk]=Pripojená disketa +Comment[sl]=Priklopljena disketna enota +Comment[sr]=Монтиран флопи +Comment[sr@Latn]=Montiran flopi +Comment[sv]=Monterad diskett +Comment[ta]=இறக்கப்பட்ட நெகிழ்வட்டு +Comment[tg]=Монтажшудаи Floppy +Comment[th]=ฟล็อปปีที่เม้านท์แล้ว +Comment[tr]=Bağlı Disket +Comment[tt]=Totaşqan Floppy +Comment[uk]=Змонтований флопі +Comment[uz]=Ulangan disket +Comment[uz@cyrillic]=Уланган дискет +Comment[ven]=Floppy yo gonyiswaho +Comment[vi]=Đĩa mềm đã kết nối +Comment[wa]=Plakete montêye +Comment[xh]=Floppy Enyusiweyo +Comment[zh_CN]=挂载的软驱 +Comment[zh_TW]=已掛載的軟碟機 +Comment[zu]=I-Floppy eyenyusiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/floppy_unmounted.desktop b/tdeioslave/media/mimetypes/floppy_unmounted.desktop new file mode 100644 index 000000000..c413cbc03 --- /dev/null +++ b/tdeioslave/media/mimetypes/floppy_unmounted.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Icon=3floppy_unmount +Type=MimeType +MimeType=media/floppy_unmounted +Comment=Unmounted Floppy +Comment[af]=Ontkoppelde Sagteskyf +Comment[ar]=قرص مرن غير محمّل +Comment[az]=Ayrılmış FLoppi +Comment[be]=Адмацаваная дыскета +Comment[bg]=Демонтирано флопи +Comment[bn]=আনমাউন্ট করা ফ্লপি +Comment[br]=Pladennig divountet +Comment[bs]=Demontirana disketa +Comment[ca]=Disquet desmuntat +Comment[cs]=Odpojená disketa +Comment[csb]=Òdmòntowónô disczétka +Comment[cy]=Disg meddal wedi'i ddadosod +Comment[da]=Afmonteret floppy +Comment[de]=Nicht eingebundene Diskette +Comment[el]=Αποπροσαρτημένη δισκέτα +Comment[eo]=Demetita Disketo +Comment[es]=Disquete desmontado +Comment[et]=Lahutatud flopi +Comment[eu]=Diskete desmuntatua +Comment[fa]=فلاپی پیادهشده +Comment[fi]=Irrotettu levyke +Comment[fr]=Disquette non montée +Comment[fy]=Ofkeppele Skiif +Comment[ga]=Diosca flapach neamhfheistithe +Comment[gl]=Disquete non Montado +Comment[he]=תקליטון מנותק +Comment[hi]=अनमाउन्टेड फ़्लॉपी +Comment[hr]=Nepristupljena disketa +Comment[hu]=Leválasztott floppy +Comment[is]=Aftengdur disklingur +Comment[it]=Dischetto non montato +Comment[ja]=マウントされていないフロッピー +Comment[ka]=დემონტირებული დრეკადი დისკი +Comment[kk]=Тіркеуден шығарған иілгіш диск +Comment[km]=Floppy មិនបានរៀបចំ +Comment[lo]=ຫັງກາລີ +Comment[lt]=Išmontuotas lankstus diskelis +Comment[lv]=Nomontēta diskete +Comment[mk]=Одмонтирана дискета +Comment[mn]=Салгагдсан уян дискүүд +Comment[ms]=Liut Nyahlekap +Comment[mt]=Flopi mhux immontat +Comment[nb]=Avmontert diskett +Comment[nds]=Afhangt Diskett +Comment[ne]=अनमाउन्ट गरिएको फ्लपी +Comment[nl]=Afgekoppelde diskette +Comment[nn]=Avmontert diskett +Comment[nso]=Floppy yeo e Theositswego +Comment[pa]=ਅਨਮਾਊਟ ਕੀਤੀ ਫਲਾਪੀ +Comment[pl]=Odmontowana dyskietka +Comment[pt]=Disquete desmontada +Comment[pt_BR]=Disquete Desmontado +Comment[ro]=Dischetă nemontată +Comment[ru]=Отмонтированная дискета +Comment[rw]=Disikete Yakuwemo +Comment[se]=Gálgajuvvon dibmaskearru +Comment[sk]=Nepripojená disketa +Comment[sl]=Odklopljena disketna enota +Comment[sr]=Демонтиран флопи +Comment[sr@Latn]=Demontiran flopi +Comment[sv]=Avmonterad diskett +Comment[ta]=வெளியேற்றிய நெகிழ்வட்டு +Comment[tg]=Ҷудо шудаи Floppy +Comment[th]=ฟล็อปปีที่ไม่ถูกเม้านท์ +Comment[tr]=Bağlanmamış Disket +Comment[tt]=Totaşmağan Floppy +Comment[uk]=Демонтований флопі +Comment[uz]=Ulanmagan disket +Comment[uz@cyrillic]=Уланмаган дискет +Comment[ven]=Floppy i songo gonyiswaho +Comment[vi]=Đĩa mềm đã gỡ ra +Comment[wa]=Plakete dismontêye +Comment[xh]=Floppy Enganyuswanga +Comment[zh_CN]=未挂载的软驱 +Comment[zh_TW]=未掛載的軟碟機 +Comment[zu]=I-Floppy eyehlisiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/gphoto2camera.desktop b/tdeioslave/media/mimetypes/gphoto2camera.desktop new file mode 100644 index 000000000..a84f3baf5 --- /dev/null +++ b/tdeioslave/media/mimetypes/gphoto2camera.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=MimeType +MimeType=media/gphoto2camera +Comment=Camera +Comment[af]=Kamera +Comment[ar]=كاميرا +Comment[az]=Kamera +Comment[be]=Камера +Comment[bg]=Фотоапарат +Comment[bn]=ক্যামেরা +Comment[br]=Kamera +Comment[bs]=Kamera +Comment[ca]=Càmera +Comment[cs]=Kamera +Comment[csb]=Òdjimkòwô kamera +Comment[da]=Kamera +Comment[de]=Kamera +Comment[el]=Κάμερα +Comment[eo]=Kamero +Comment[es]=Cámara +Comment[et]=Kaamera +Comment[eu]=Kamara +Comment[fa]=دوربین +Comment[fi]=Kamera +Comment[fr]=Nouvel appareil photo +Comment[fy]=Kamera +Comment[ga]=Ceamara +Comment[gl]=Cámara +Comment[he]=מצלמה +Comment[hi]=कैमरा +Comment[hr]=Kamera +Comment[hu]=Fényképezőgép +Comment[is]=Myndavél +Comment[it]=Macchina fotografica +Comment[ja]=カメラ +Comment[ka]=კამერა +Comment[kk]=Фотокамера +Comment[km]=ម៉ាស៊ីនថត +Comment[lt]=Fotoaparatas +Comment[lv]=Kamera +Comment[mk]=Камера +Comment[ms]=Kamera +Comment[nb]=Kamera +Comment[nds]=Kamera +Comment[ne]=क्यामेरा +Comment[nn]=Kamera +Comment[pa]=ਕੈਮਰਾ +Comment[pl]=Aparat fotograficzny +Comment[pt]=Máquina fotográfica +Comment[pt_BR]=Câmera +Comment[ro]=Aparat foto +Comment[ru]=Камера +Comment[rw]=Kamera +Comment[se]=Govvanaperáhtta +Comment[sk]=Digitálny fotoaparát +Comment[sl]=Fotoaparat +Comment[sr]=Камера +Comment[sr@Latn]=Kamera +Comment[sv]=Kamera +Comment[ta]=புகைப்பட கருவி +Comment[te]=కెమెరా +Comment[tg]=Камера +Comment[th]=กล้องดิจิตอล +Comment[tr]=Kamera +Comment[tt]=Kamera +Comment[uk]=Камера +Comment[uz]=Fotoaparat +Comment[uz@cyrillic]=Фотоапарат +Comment[vi]=Máy chụp ảnh số +Comment[zh_CN]=相机 +Comment[zh_TW]=相機 +Icon=camera_unmount + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory + diff --git a/tdeioslave/media/mimetypes/hdd_mounted.desktop b/tdeioslave/media/mimetypes/hdd_mounted.desktop new file mode 100644 index 000000000..c442b554d --- /dev/null +++ b/tdeioslave/media/mimetypes/hdd_mounted.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Icon=hdd_mount +Type=MimeType +MimeType=media/hdd_mounted +Comment=Mounted Hard Disk Volume +Comment[af]=Gekoppelde Hard Skyf Partisie +Comment[ar]=تجزئة قرص صلب محمّلة +Comment[az]=Bağlanmış Sabit Disk Bölməsi +Comment[be]=Прымацаваны раздзел жорсткага дыска +Comment[bg]=Монтиран дял на твърд диск +Comment[bn]=মাউন্ট করা হার্ড ডিস্ক ভলিউম +Comment[br]=Pladenn marc'het +Comment[bs]=Montirana hard disk particija +Comment[ca]=Disc dur muntat +Comment[cs]=Připojený oddíl pevného disku +Comment[csb]=Zamòntowónô particëjô cwiardi platë +Comment[da]=Monteret harddisk-volumen +Comment[de]=Eingebundene Festplattenpartition +Comment[el]=Προσαρτημένη κατάτμηση σκληρού δίσκου +Comment[eo]=Surmetita subdisko +Comment[es]=Volumen de disco duro montado +Comment[et]=Ühendatud kõvaketta partitsioon +Comment[eu]=Diska gogorraren zatiketa muntatua +Comment[fa]=حجم دیسک سخت سوارشده +Comment[fi]=Liitetty kiintoleyosio +Comment[fr]=Partition de disque dur montée +Comment[fy]=Oankeppele Fêsteskiif folume +Comment[ga]=Imleabhar Feistithe Diosca Crua +Comment[gl]=Partición do Disco Duro Montada +Comment[he]=מחיצת כונן קשיח מחוברת +Comment[hi]=माउन्टेड हार्ड डिस्क वॉल्यूम +Comment[hr]=Pristupljeni volumen tvrdog diska +Comment[hu]=Csatlakoztatott merevlemezes partíció +Comment[is]=Tengd disksneið +Comment[it]=Volume disco rigido montato +Comment[ja]=マウントされたハードディスクボリューム +Comment[ka]=მონტირებული ხისტი დისკის ტომი +Comment[kk]=Тіркеген қатқыл диск томы +Comment[km]=ទំហំថាសរឹងដែលបានរៀបចំ +Comment[lt]=Sumontuotas kieto disko skirsnis +Comment[lv]=Piemontēts cietais disks +Comment[mk]=Монтирана партиција на тврд диск +Comment[ms]=Volum Cakera Keras Terlekap +Comment[mt]=Partizzjoni ta' ħard-disk immuntata +Comment[nb]=Montert harddiskpartisjon +Comment[nds]=Inhangt Fastplaat-Partitschoon +Comment[ne]=माउन्ट गरिएको हार्ड डिस्क भोल्युम +Comment[nl]=Aangekoppelde hardeschijfpartitie +Comment[nn]=Montert harddiskvolum +Comment[pa]=ਮਾਊਟ ਕੀਤਾ ਹਾਰਡ ਡਿਸਕ ਭਾਗ +Comment[pl]=Zamontowana partycja dysku twardego +Comment[pt]=Volume de disco rígido montado +Comment[pt_BR]=Volume do HD Montado +Comment[ro]=Volum de hard disc montat +Comment[ru]=Смонтированный раздел жёсткого диска +Comment[rw]=Ububiko Disiki Bwashyizwemo +Comment[se]=Čatnon garraskearrooassi +Comment[sk]=Pripojený oddiel pevného disku +Comment[sl]=Priklopljen pogon trdega diska +Comment[sr]=Монтирана партиција хард диска +Comment[sr@Latn]=Montirana particija hard diska +Comment[sv]=Monterad hårdiskpartition +Comment[ta]=ஏற்றப்பட்ட வன்தகடு வட்டு பிரிவு +Comment[th]=ฮาร์ดดิสก์ที่เม้านท์แล้ว +Comment[tr]=Bağlanmış Sabit Disk Bölümü +Comment[tt]=Totaşqan Qatı Disk Töpläme +Comment[uk]=Змонтований розділ жорсткого диску +Comment[uz]=Qattiq diskning ulangan qismi +Comment[uz@cyrillic]=Қаттиқ дискнинг уланган қисми +Comment[vi]=Các Phân vùng Ổ cứng đã kết nối +Comment[wa]=Volume del deure plake monté +Comment[zh_CN]=挂载的硬盘卷 +Comment[zh_TW]=已掛載的硬碟分割區 +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/hdd_mounted_decrypted.desktop b/tdeioslave/media/mimetypes/hdd_mounted_decrypted.desktop new file mode 100644 index 000000000..4330b82be --- /dev/null +++ b/tdeioslave/media/mimetypes/hdd_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=hdd_mount_decrypt +Type=MimeType +MimeType=media/hdd_mounted_decrypted +Comment=Mounted Decrypted Hard Disk Volume +Comment[de]=Eingebundene, entschlüsselte Festplattenpartition +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/hdd_unmounted.desktop b/tdeioslave/media/mimetypes/hdd_unmounted.desktop new file mode 100644 index 000000000..cee21730f --- /dev/null +++ b/tdeioslave/media/mimetypes/hdd_unmounted.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Icon=hdd_unmount +Type=MimeType +MimeType=media/hdd_unmounted +Comment=Unmounted Hard Disk Volume +Comment[af]=Ontkoppelde Hard Skyf Partisie +Comment[ar]=تجزئة قرص صلب غير محمّلة +Comment[az]=Ayrılmış Sabit Disk Bölməsi +Comment[be]=Адмацаваны раздзел жорсткага дыска +Comment[bg]=Демонтиран дял на твърд диск +Comment[bn]=আনমাউন্ট করা হার্ড ডিস্ক ভলিউম +Comment[br]=Pladenn divarc'het +Comment[bs]=Demontirana hard disk particija +Comment[ca]=Disc dur desmuntat +Comment[cs]=Odpojený oddíl pevného disku +Comment[csb]=Òdmòntowónô particëjô cwiardi platë +Comment[da]=Afmonteret harddisk-volumen +Comment[de]=Nicht eingebundene Festplattenpartition +Comment[el]=Αποπροσαρτημένη κατάτμηση σκληρού δίσκου +Comment[eo]=Demetita subdisko +Comment[es]=Volumen de disco duro desmontado +Comment[et]=Lahutatud kõvaketta partitsioon +Comment[eu]=Diska gogorraren zatiketa desmuntatua +Comment[fa]=حجم دیسک سخت پیادهشده +Comment[fi]=Irrotettu kiintolevyosio +Comment[fr]=Partition de disque dur non montée +Comment[fy]=Ofkeppele Fêsteskiif folume +Comment[ga]=Imleabhar Diosca Crua Gan Fheistiú +Comment[gl]=Partición do Disco Duro Non Montada +Comment[he]=מחיצת כונן קשיח מנותקת +Comment[hi]=अनमाउन्टेड हार्ड डिस्क वॉल्यूम +Comment[hr]=Nepristupljeni volumen tvrdog diska +Comment[hu]=Leválasztott merevlemezes partíció +Comment[is]=Aftengd disksneið +Comment[it]=Volume disco rigido non montato +Comment[ja]=マウントされていないハードディスクボリューム +Comment[ka]=დემონტირებული ხისტი დისკის ტომი +Comment[kk]=Тіркеуден шығарған қатқыл диск томы +Comment[km]=ទំហំថាសរឹងដែលមិនបានរៀបចំ +Comment[lt]=Išmontuotas kieto disko skirsnis +Comment[lv]=Nomontēts cietais disks +Comment[mk]=Одмонтирана партиција на тврд диск +Comment[ms]=Volum Cakera Keras Nyahlekap +Comment[mt]=Partizzjoni ta' ħard-disk mhux immuntata +Comment[nb]=Avmontert harddiskpartisjon +Comment[nds]=Afhangt Fastplaat-Partitschoon +Comment[ne]=अनमाउन्ट गरिएको हार्ड डिस्क भोल्युम +Comment[nl]=Afgekoppelde hardeschijfpartitie +Comment[nn]=Umontert harddiskvolum +Comment[pa]=ਅਨਮਾਊਟ ਕੀਤੀ ਹਾਰਡ ਡਿਸਕ ਭਾਗ +Comment[pl]=Odmontowana partycja dysku twardego +Comment[pt]=Volume de disco rígido desmontado +Comment[pt_BR]=Volume do HD Desmontado +Comment[ro]=Volum de hard disc nemontat +Comment[ru]=Отмонтированный раздел жёсткого диска +Comment[rw]=Ububiko Disiki Bwakuwemo +Comment[se]=Gálgajuvvon garraskearrooassi +Comment[sk]=Odpojený oddiel pevného disku +Comment[sl]=Odklopljen pogon trdega diska +Comment[sr]=Демонтирана партиција хард диска +Comment[sr@Latn]=Demontirana particija hard diska +Comment[sv]=Avmonterad hårdiskpartition +Comment[ta]=வெளியேற்றப்பட்ட வன்வட்டு பகுதி +Comment[th]=ฮาร์ดดิสก์ที่ไม่ได้เม้านท์ +Comment[tr]=Ayrılmış Sabit Disk Bölümü +Comment[tt]=Totaşmağan Qatı Disk Töpläme +Comment[uk]=Демонтований розділ жорсткого диску +Comment[uz]=Qattiq diskning ulanmagan qismi +Comment[uz@cyrillic]=Қаттиқ дискнинг уланмаган қисми +Comment[vi]=Các Phân vùng Ổ cứng đã gỡ ra +Comment[wa]=Volume del deure plake dismonté +Comment[zh_CN]=未挂载的硬盘卷 +Comment[zh_TW]=未掛載的硬碟分割區 +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/hdd_unmounted_decrypted.desktop b/tdeioslave/media/mimetypes/hdd_unmounted_decrypted.desktop new file mode 100644 index 000000000..cd2e387ce --- /dev/null +++ b/tdeioslave/media/mimetypes/hdd_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=hdd_unmount_decrypt +Type=MimeType +MimeType=media/hdd_unmounted_decrypted +Comment=Unmounted Decrypted Hard Disk Volume +Comment[de]=Nicht eingebundene, entschlüsselte Festplattenpartition +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/hdd_unmounted_encrypted.desktop b/tdeioslave/media/mimetypes/hdd_unmounted_encrypted.desktop new file mode 100644 index 000000000..ecc744974 --- /dev/null +++ b/tdeioslave/media/mimetypes/hdd_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=hdd_unmount_encrypt +Type=MimeType +MimeType=media/hdd_unmounted_encrypted +Comment=Unmounted Encrypted Hard Disk Volume +Comment[de]=Nicht eingebundene, verschlüsselte Festplattenpartition +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/mycomputer.desktop b/tdeioslave/media/mimetypes/mycomputer.desktop new file mode 100644 index 000000000..886d95aed --- /dev/null +++ b/tdeioslave/media/mimetypes/mycomputer.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Icon=system +Type=MimeType +MimeType=media/builtin-mycomputer +Comment=My Computer +Patterns=My_Computer + +X-TDE-AutoEmbed=false diff --git a/tdeioslave/media/mimetypes/mydocuments.desktop b/tdeioslave/media/mimetypes/mydocuments.desktop new file mode 100644 index 000000000..1e3cf8d03 --- /dev/null +++ b/tdeioslave/media/mimetypes/mydocuments.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Icon=folder_wordprocessing +Type=MimeType +MimeType=media/builtin-mydocuments +Comment=My Documents +Patterns=My_Documents + +X-TDE-AutoEmbed=false diff --git a/tdeioslave/media/mimetypes/mynetworkplaces.desktop b/tdeioslave/media/mimetypes/mynetworkplaces.desktop new file mode 100644 index 000000000..30294890c --- /dev/null +++ b/tdeioslave/media/mimetypes/mynetworkplaces.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Icon=network +Type=MimeType +MimeType=media/builtin-mynetworkplaces +Comment=My Network Places +Patterns=My_Network_Places + +X-TDE-AutoEmbed=false diff --git a/tdeioslave/media/mimetypes/nfs_mounted.desktop b/tdeioslave/media/mimetypes/nfs_mounted.desktop new file mode 100644 index 000000000..3de6c0303 --- /dev/null +++ b/tdeioslave/media/mimetypes/nfs_mounted.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Icon=nfs_mount +Type=MimeType +MimeType=media/nfs_mounted +Comment=Mounted NFS Share +Comment[af]=Gekoppelde NFS Hulpbron +Comment[ar]=مشاركة NFS مركبة +Comment[az]=Bağlanmış NFS Sahəsi +Comment[be]=Прымацаваная агульная тэчка NFS +Comment[bg]=Монтиран NFS ресурс +Comment[bn]=মাউন্ট করা এন-এফ-এস শেয়ার +Comment[br]=Rennad NFS marc'het +Comment[bs]=Montiran NFS resurs +Comment[ca]=Recurs NFS muntat +Comment[cs]=Připojený zdroj NFS +Comment[csb]=Zamòntowónô systema lopków NFS +Comment[da]=Monteret NFS-share +Comment[de]=Eingebundene NFS-Freigabe +Comment[el]=Προσαρτημένος πόρος NFS +Comment[eo]=Surmetita NFS-opuzaĵo +Comment[es]=Recurso NFS montado +Comment[et]=Ühendatud NFS ressurss +Comment[eu]=NFS baliabide muntatua +Comment[fa]=مشترک NFS سوارشده +Comment[fi]=Liitetty NFS-jako +Comment[fr]=Ressource NFS montée +Comment[fy]=Oankeppele NFS-boarne +Comment[ga]=Comhroinn Fheistithe NFS +Comment[gl]=Compartición NFS Montada +Comment[he]=משאב NFS מחובר +Comment[hi]=माउन्टेड एनएफ़एस साझा +Comment[hr]=Pristupljeno NFS dijeljenje +Comment[hu]=Csatlakoztatott NFS-megosztás +Comment[is]=Tengd NFS auðlind +Comment[it]=Risorsa NFS montata +Comment[ja]=マウントされた NFS 共有 +Comment[ka]=მონტირებული NFS რესურსი +Comment[kk]=Тіркеген NFS ресурсы +Comment[km]=NFS Share បានរៀបចំ +Comment[lt]=Sumontuotas NFS bendro naudojimo resursas +Comment[lv]=Piemontēta NFS šāre +Comment[mk]=Монтиран NFS-ресурс +Comment[ms]=Perkongsian NFS Terlekap +Comment[mt]=Riżors NFS immuntat +Comment[nb]=Montert NFS-ressurs +Comment[nds]=Inhangt NFS-Freegaav +Comment[ne]=माउन्ट गरिएको NFS साझेदारी +Comment[nl]=Aangekoppelde NFS-gegevensbron +Comment[nn]=Montert delt NFS-ressurs +Comment[pa]=ਮਾਊਟ ਕੀਤੀ NFS ਸਾਂਝ +Comment[pl]=Zamontowany system plików NFS +Comment[pt]=Partilha de NFS montada +Comment[pt_BR]=Volume NFS Montado +Comment[ro]=Partajare NFS montată +Comment[ru]=Смонтированный ресурс NFS +Comment[rw]=Umugabane NFS Washyizwemo +Comment[se]=Čatnon NFS-resursa +Comment[sk]=Pripojený zdroj NFS +Comment[sl]=Priklopljen vir NFS +Comment[sr]=Монтирано NFS дељење +Comment[sr@Latn]=Montirano NFS deljenje +Comment[sv]=Monterad NFS-resurs +Comment[ta]=ஏற்றப்பட்ட NFS பங்கு +Comment[th]=ทรัพยากร NFS ที่ถูกเม้านท์ +Comment[tr]=Bağlı NFS Paylaşımı +Comment[tt]=Totaşqan NFS Urtağı +Comment[uk]=Змонтований ресурс NFS +Comment[uz]=Ulangan NFS manba +Comment[uz@cyrillic]=Уланган NFS манба +Comment[vi]=Chia sẻ NFS đã kết nối +Comment[wa]=Pårtaedje NFS monté +Comment[zh_CN]=挂载的 NFS 共享 +Comment[zh_TW]=已掛載的 NFS 資源 +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/nfs_unmounted.desktop b/tdeioslave/media/mimetypes/nfs_unmounted.desktop new file mode 100644 index 000000000..d2bb456b6 --- /dev/null +++ b/tdeioslave/media/mimetypes/nfs_unmounted.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Icon=nfs_unmount +Type=MimeType +MimeType=media/nfs_unmounted +Comment=Unmounted NFS Share +Comment[af]=Ontkoppelde NFS Hulpbron +Comment[ar]=مشاركة NFS غير مركبة +Comment[az]=Ayrılmış NFS Sahəsi +Comment[be]=Адмацаваная агульная тэчка NFS +Comment[bg]=Демонтиран NFS ресурс +Comment[bn]=আনমাউন্ট করা এন-এফ-এস শেয়ার +Comment[br]=Rennad NFS divarc'het +Comment[bs]=Demontiran NFS resurs +Comment[ca]=Recurs NFS desmuntat +Comment[cs]=Odpojený zdroj NFS +Comment[csb]=Òdmòntowónô systema lopków NFS +Comment[da]=Afmonteret NFS-share +Comment[de]=Nicht eingebundene NFS-Freigabe +Comment[el]=Αποπροσαρτημένος πόρος NFS +Comment[eo]=Demetita NFS-opuzaĵo +Comment[es]=Recurso NFS desmontado +Comment[et]=Lahutatud NFS ressurss +Comment[eu]=NFS baliabide desmuntatua +Comment[fa]=مشترک NFS پیادهشده +Comment[fi]=Irrotettu NFS-jako +Comment[fr]=Ressource NFS non montée +Comment[fy]=Oankeppele NFS-boarne +Comment[ga]=Comhroinn NFS Gan Fheistiú +Comment[gl]=Compartición NFS non Montada +Comment[he]=משאב NFS מנותק +Comment[hi]=अनमाउन्टेड एनएफ़एस साझा +Comment[hr]=Nepristupljeno NFS dijeljenje +Comment[hu]=Leválasztott NFS-megosztás +Comment[is]=Aftengd NFS auðlind +Comment[it]=Risorsa NFS non montata +Comment[ja]=マウントされていない NFS 共有 +Comment[ka]=დემონტირებული NFS რესურსი +Comment[kk]=Тіркеуден шығарған NFS ресурсы +Comment[km]=NFS Share មិនបានរៀបចំ +Comment[lt]=Išmontuotas NFS bendro naudojimo resursas +Comment[lv]=Nomontēta NFS šāre +Comment[mk]=Одмонтиран NFS-ресурс +Comment[ms]=Perkongsian NFS Nyahlekap +Comment[mt]=Riżors NFS mhux immuntat +Comment[nb]=Avmontert NFS-ressurs +Comment[nds]=Afhangt NFS-Freegaav +Comment[ne]=अनमाउन्ट गरिएको NFS साझेदारी +Comment[nl]=Afgekoppelde NFS-gegevensbron +Comment[nn]=Umontert delt NFS-ressurs +Comment[pa]=ਅਨਮਾਊਟ ਕੀਤੀ NFS ਸਾਂਝ +Comment[pl]=Odmontowany system plików NFS +Comment[pt]=Partilha de NFS desmontada +Comment[pt_BR]=Volume NFS Desmontado +Comment[ro]=Partajare NFS nemontată +Comment[ru]=Отмонтированный ресурс NFS +Comment[rw]=Umugabane NFS Wakuwemo +Comment[se]=Gálgajuvvon NFS-resursa +Comment[sk]=Odpojený zdroj NFS +Comment[sl]=Odklopljen vir NFS +Comment[sr]=Демонтирано NFS дељење +Comment[sr@Latn]=Demontirano NFS deljenje +Comment[sv]=Avmonterad NFS-resurs +Comment[ta]=இறக்கப்பட்ட NFS பங்கு +Comment[th]=ทรัพยากร NFS ที่ไม่ถูกเม้านท์ +Comment[tr]=Bağlanmamış NFS Paylaşımı +Comment[tt]=Totaşmağan NFS Urtağı +Comment[uk]=Демонтований ресурс NFS +Comment[uz]=Ulanmagan NFS manba +Comment[uz@cyrillic]=Уланмаган NFS манба +Comment[vi]=Chia sẻ NFS đã gỡ ra +Comment[wa]=Pårtaedje NFS dismonté +Comment[zh_CN]=未挂载的 NFS 共享 +Comment[zh_TW]=未掛載的 NFS 資源 +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/printers.desktop b/tdeioslave/media/mimetypes/printers.desktop new file mode 100644 index 000000000..cb808e522 --- /dev/null +++ b/tdeioslave/media/mimetypes/printers.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Icon=kjobviewer +Type=MimeType +MimeType=media/builtin-printers +Comment=Printers +Patterns=Printers + +X-TDE-AutoEmbed=false diff --git a/tdeioslave/media/mimetypes/removable_mounted.desktop b/tdeioslave/media/mimetypes/removable_mounted.desktop new file mode 100644 index 000000000..8371af6ac --- /dev/null +++ b/tdeioslave/media/mimetypes/removable_mounted.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Icon=usbpendrive_mount +Type=MimeType +MimeType=media/removable_mounted +Comment=Mounted Removable Medium +Comment[af]=Gekoppelde Verwyderbare Medium +Comment[ar]=وسيط قابل للإزالة مركب +Comment[az]=Bağlanmış Çıxarıla Bilən Mediyum +Comment[be]=Прымацаваны зменны носьбіт +Comment[bg]=Монтиран преносим носител +Comment[bn]=মাউন্ট করা অপসারণযোগ্য মিডিয়াম +Comment[br]=Medium lem-laka marc'het +Comment[bs]=Montiran izmjenjivi uređaj +Comment[ca]=Suport extraïble muntat +Comment[cs]=Připojené výměnné médium +Comment[csb]=Zamòntowóné òdłączalné medium +Comment[da]=Monteret medie der kan fjernes +Comment[de]=Eingebundenes Wechsellaufwerk +Comment[el]=Προσαρτημένος αφαιρούμενο μέσο +Comment[eo]=Surmetita forigebla datumportilo +Comment[es]=Recurso extraíble montado +Comment[et]=Ühendatud eemaldatav andmekandja +Comment[eu]=Euskarri aldagarria muntatua +Comment[fa]=رسانۀ برداشتنی سوارشده +Comment[fi]=Liitetty irrotettava resurssi +Comment[fr]=Média amovible monté +Comment[fy]=Oankeppele ferwiderber medium +Comment[ga]=Meán Feistithe Inbhainte +Comment[gl]=Dispositivo Extraíbel Montado +Comment[he]=מדיה חיצונית מחוברת +Comment[hi]=माउन्टेड रीमूवेबल माध्यम +Comment[hr]=Pristupljen izmjenjiv medij +Comment[hu]=Csatlakoztatott adathordozó +Comment[is]=Tengdur útskiptanlegur miðill +Comment[it]=Supporto rimovibile montato +Comment[ja]=マウントされたリムーバブルメディア +Comment[ka]=მონტირებული პორტატიული მოწყობილობა +Comment[kk]=Тіркеген ауыстырмалы тасушы +Comment[km]=ឧបករណ៍ចល័តដែលបានរៀបចំ +Comment[lt]=Sumontuotas pašalinamas diskas +Comment[lv]=Piemontēts noņemamais datu nesējs +Comment[mk]=Монтиран отстранлив носач +Comment[ms]=Medium Boleh Buang Terlekap +Comment[mt]=Riżors NFS immuntat +Comment[nb]=Montert flyttbart medium +Comment[nds]=Inhangt tuuschbor Loopwark +Comment[ne]=माउन्ट गरिएको हटाउन सकिने मेडिअम +Comment[nl]=Aangekoppeld verwijderbaar medium +Comment[nn]=Montert flyttbart medium +Comment[pa]=ਮਾਊਟ ਕੀਤੇ ਹਟਾਉਣਯੋਗ ਮਾਧਿਅਮ +Comment[pl]=Zamontowany nośnik wymienny +Comment[pt]=Dispositivo amovível montado +Comment[pt_BR]=Mídia Removível Montada +Comment[ro]=Mediu amovibil montat +Comment[ru]=Смонтированный внешний диск +Comment[rw]=Igitangazamakuru Kivanwamo Cyashyizwemo +Comment[se]=Čátnon sirdehahtti medium +Comment[sk]=Pripojené vyberateľné médium +Comment[sl]=Priklopljen odstranljiv medij +Comment[sr]=Монтиран уклоњиви медијум +Comment[sr@Latn]=Montiran uklonjivi medijum +Comment[sv]=Monterad flyttbar enhet +Comment[ta]=ஏற்றப்பட்ட நீக்கக்கூடிய மீடியம் +Comment[th]=สื่อบันทึกแบบถอดออกได้ถูกเม้านท์ +Comment[tr]=Bağlı Ayrılabilir Ortam +Comment[tt]=Totaşqan Çığarulı Media +Comment[uk]=Змонтований переносний носій +Comment[uz]=Ulangan saqlash uskunasi +Comment[uz@cyrillic]=Уланган сақлаш ускунаси +Comment[vi]=Ổ lưu trữ Di động đã kết nối +Comment[wa]=Oiståve mediom monté +Comment[zh_CN]=挂载的可移动介质 +Comment[zh_TW]=已掛載的可攜式媒體 +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/removable_mounted_decrypted.desktop b/tdeioslave/media/mimetypes/removable_mounted_decrypted.desktop new file mode 100644 index 000000000..88298712e --- /dev/null +++ b/tdeioslave/media/mimetypes/removable_mounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=usbpendrive_mount_decrypt +Type=MimeType +MimeType=media/removable_mounted_decrypted +Comment=Mounted Decrypted Removable Medium +Comment[de]=Eingebundenes, entschlüsseltes Wechsellaufwerk +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/removable_unmounted.desktop b/tdeioslave/media/mimetypes/removable_unmounted.desktop new file mode 100644 index 000000000..0fe53d898 --- /dev/null +++ b/tdeioslave/media/mimetypes/removable_unmounted.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Icon=usbpendrive_unmount +Type=MimeType +MimeType=media/removable_unmounted +Comment=Unmounted Removable Medium +Comment[af]=Ontkoppel Verwyderbare Medium +Comment[ar]=وسيط قابل للإزالة غير مركب +Comment[az]=Ayrılmış Çıxarıla Bilən Mediyum +Comment[be]=Адмацаваны зменны носьбіт +Comment[bg]=Демонтиран преносим носител +Comment[bn]=আনমাউন্ট করা অপসারণযোগ্য মিডিয়াম +Comment[br]=Medium ar skoroù lem/laka divarc'het +Comment[bs]=Demontiran izmjenjivi uređaj +Comment[ca]=Suport extraïble desmuntat +Comment[cs]=Odpojené výměnné médium +Comment[csb]=Òdmòntowóné òdłączalné medium +Comment[da]=Afmonteret medie der kan fjernes +Comment[de]=Nicht eingebundenes Wechsellaufwerk +Comment[el]=Αποπροσαρτημένο αφαιρούμενο μέσο +Comment[eo]=Demetita forigebla datumportilo +Comment[es]=Recurso extraíble desmontado +Comment[et]=Lahutatud eemaldatav andmekandja +Comment[eu]=Euskarri aldagarria desmuntatua +Comment[fa]=رسانۀ برداشتنی پیادهشده +Comment[fi]=Irrotettu irrotettava resurssi +Comment[fr]=Média amovible non monté +Comment[fy]=Ofkeppele ferwiderber medium +Comment[ga]=Meán Inbhainte Gan Fheistiú +Comment[gl]=Dispositivo Extraíbel Non Montado +Comment[he]=מדייה חיצונית מנותקת +Comment[hi]=अनमाउन्टेड रीमूवेबल माध्यम +Comment[hr]=Nepristupljen izmjenjiv medij +Comment[hu]=Leválasztott adathordozó +Comment[is]=Aftengdur útskiptanlegur miðill +Comment[it]=Supporto rimovibile non montato +Comment[ja]=マウントされていないリムーバブルメディア +Comment[ka]=დემონტირებული პორტატიული მოწყობილობა +Comment[kk]=Тіркеуден шығарған ауыстырмалы тасушы +Comment[km]=ឧបករណ៍ចល័តដែលមិនបានរៀបចំ +Comment[lt]=Išmontuotas pašalinamas diskas +Comment[lv]=Nomontēts noņemamais datu nesējs +Comment[mk]=Одмонтиран отстранлив носач +Comment[ms]=Medium Boleh Buang Nyahlekap +Comment[mt]=Riżors għall-ħażna tad-data mhux immuntat +Comment[nb]=Avmontert flyttbart medium +Comment[nds]=Afhangt tuuschbor Loopwark +Comment[ne]=अनमाउन्ट गरिएको हटाउन सकिने मेडिअम +Comment[nl]=Afgekoppeld verwijderbaar medium +Comment[nn]=Umontert flyttbart medium +Comment[pa]=ਅਨਮਾਊਟ ਕੀਤੀ ਹਟਾਉਣਯੋਗ ਮਾਧਿਅਮ +Comment[pl]=Odmontowany nośnik wymienny +Comment[pt]=Dispositivo amovível desmontado +Comment[pt_BR]=Mídia Removível Desmontada +Comment[ro]=Mediu amovibil nemontat +Comment[ru]=Отмонтированный внешний диск +Comment[rw]=Igitangazamakuru Kivanwamo Cyavanwemo +Comment[se]=Gálgaduvvon sirdehahtti medium +Comment[sk]=Odpojené vyberateľné médium +Comment[sl]=Odklopljen odstranljiv medij +Comment[sr]=Демонтиран уклоњиви медијум +Comment[sr@Latn]=Demontiran uklonjivi medijum +Comment[sv]=Avmonterad flyttbar enhet +Comment[ta]=ஏற்றாத நீக்கக்கூடிய சாதனம் +Comment[th]=สื่อบันทึกแบบถอดออกได้ไม่ได้เเม้านท์ +Comment[tr]=Bağlanmamış Ayrılabilir Ortam +Comment[tt]=Totaşmağan Çığarulı Medium +Comment[uk]=Демонтований переносний носій +Comment[uz]=Ulanmagan saqlash uskunasi +Comment[uz@cyrillic]=Уланмаган сақлаш ускунаси +Comment[vi]=Ổ lưu trữ Di động đã gỡ ra +Comment[wa]=Oiståve mediom dismonté +Comment[zh_CN]=未挂载的可移动介质 +Comment[zh_TW]=未掛載的可攜式媒體 +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/removable_unmounted_decrypted.desktop b/tdeioslave/media/mimetypes/removable_unmounted_decrypted.desktop new file mode 100644 index 000000000..3af682050 --- /dev/null +++ b/tdeioslave/media/mimetypes/removable_unmounted_decrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=usbpendrive_unmount_decrypt +Type=MimeType +MimeType=media/removable_unmounted_decrypted +Comment=Unmounted Decrypted Removable Medium +Comment[de]=Nicht eingebundenes, entschlüsseltes Wechsellaufwerk +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/removable_unmounted_encrypted.desktop b/tdeioslave/media/mimetypes/removable_unmounted_encrypted.desktop new file mode 100644 index 000000000..f904eb9ec --- /dev/null +++ b/tdeioslave/media/mimetypes/removable_unmounted_encrypted.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Icon=usbpendrive_unmount_encrypt +Type=MimeType +MimeType=media/removable_unmounted_encrypted +Comment=Unmounted Encrypted Removable Medium +Comment[de]=Nicht eingebundenes, verschlüsseltes Wechsellaufwerk +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/smb_mounted.desktop b/tdeioslave/media/mimetypes/smb_mounted.desktop new file mode 100644 index 000000000..16ee7c815 --- /dev/null +++ b/tdeioslave/media/mimetypes/smb_mounted.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +Icon=nfs_mount +Type=MimeType +MimeType=media/smb_mounted +Comment=Mounted Samba (Microsoft Network) Share +Comment[af]=Gekoppelde Samba (Microsoft Netwerk) Hulpbron +Comment[ar]=مشاركة Samba محمّلة +Comment[az]=Bağlanmış Samba (Microsoft Şəbəkəsi) Sahəsi +Comment[be]=Прымацаваная агульная тэчка Samba (Сетка Microsoft) +Comment[bg]=Монтиран ресурс Samba (Microsoft Network) +Comment[bn]=মাউন্ট করা সাম্বা (মাইক্রোসফট নেটওয়ার্ক) শেয়ার +Comment[br]=Rennad Samba (rouedad Microsoft) marc'het +Comment[bs]=Montiran Samba (Microsoft Network) Share +Comment[ca]=Recurs de Samba (xarxa Microsoft) muntat +Comment[cs]=Připojený Samba (Microsoft Network) prostředek +Comment[csb]=Zamòntowóné ùdzélenié Sambë (Microsoft Network) +Comment[cy]=Cydranniad Samba (Rhwydwaith Microsoft) wedi'i osod +Comment[da]=Monteret Samba-share (Microsoft-netværk) +Comment[de]=Eingebundene Samba-Freigabe (Microsoft-Netzwerk) +Comment[el]=Προσαρτημένος κοινόχρηστος πόρος Samba (Δίκτυο Microsoft) +Comment[eo]=Surmetita Sambo-opuzaĵo +Comment[es]=Recurso de Samba montado (Red de Microsoft) +Comment[et]=Ühendatud Samba (Microsoft Network) ressurss +Comment[eu]=Samba (Microsoft sarea) partekaketa muntatua +Comment[fa]=مشترک Samba (Microsoft Network) سوارشده +Comment[fi]=Liitetty Samba-jako (Microsoft-verkko) +Comment[fr]=Partage Samba (réseau Microsoft) monté +Comment[fy]=Oankeppele Samba-netwurkboarne (Microsoft-netwurken) +Comment[ga]=Comhroinn Fheistithe Samba (Microsoft Network) +Comment[gl]=Compartición Samba Montada (Rede de Microsoft) +Comment[he]=שיתוף Microsoft Network) Samba) מחובר +Comment[hi]=माउन्टेड साम्बा (माइक्रोसाफ्ट नेटवर्क) साझेदारी +Comment[hr]=Pristupljeno Samba dijeljenje (Microsoft mreža) +Comment[hsb]=Montowany Samba-(Microsoft syć)-zapisk +Comment[hu]=Csatlakoztatott Samba-megosztás +Comment[is]=Tengd Samba (Microsoft Network) sameign +Comment[it]=Condivisione samba (Rete Microsoft) montata +Comment[ja]=マウントされた Samba (マイクロソフトのネットワーク) 共有 +Comment[ka]=მონტირებული Samba რესურსი (Microsoft-ის ქსელი) +Comment[kk]=Тіркеген Samba ресурсы (Microsoft желісі) +Comment[km]=Samba (បណ្ដាញ Microsoft) Share បានរៀបចំ +Comment[lt]=Sumontuotas Samba (Microsoft Network) bendro naudojimo diskas +Comment[lv]=Piemontēta Samba (Microsoft tīkla) šāre +Comment[mk]=Монтиран Samba заеднички ресурс (Microsoft мрежа) +Comment[mn]=Залгагдсан Samba-Нөөцүүд (Microsoft-Сүлжээ) +Comment[ms]=Perkongsian Samba Terlekap (Rangkaian Microsoft) +Comment[mt]=Riżors Samba (Microsoft Network) immuntat +Comment[nb]=Montert Samba-katalog (Microsoft nettverk) +Comment[nds]=Inhangt Samba-Freegaav (Microsoft-Nettwark) +Comment[ne]=माउन्ट गरिएको साम्बा (माइक्रो सफ्ट सञ्जाल) साझेदारी +Comment[nl]=Aangekoppelde Samba-netwerkbron (Microsoft-netwerken) +Comment[nn]=Montert Samba-ressurs (Microsoft-nettverk) +Comment[nso]=Kabagano yeo e Nameleditswego ya Samba (Kgokagano ya Microsoft) +Comment[pa]=ਮਾਊਟ ਕੀਤੀ ਸਾਂਬਾ (ਮਾਈਕਰੋਸਾਫਟ ਨੈੱਟਵਰਕ) ਸਾਂਝ +Comment[pl]=Zamontowany udział Samby (sieci typu Microsoft Network) +Comment[pt]=Partilha de Samba (Microsoft Network) montada +Comment[pt_BR]=Compartilhamento do Samba (Rede Microsoft) montado +Comment[ro]=Partajare Samba (rețea Microsoft) montată +Comment[ru]=Смонтированный ресурс сети Microsoft +Comment[rw]=Umugabane Samba (Urusobemiyoboro Microsoft) Washyizwemo +Comment[se]=Čatnojuvvon Samba-resursa (Microsoft-fierbmi) +Comment[sk]=Pripojený disk Samba (Microsoft Network) +Comment[sl]=Priklopljen deljeni vir Sambe (Microsoftovo omrežje) +Comment[sr]=Монтирано Samba дељење (Microsoft-ова мрежа) +Comment[sr@Latn]=Montirano Samba deljenje (Microsoft-ova mreža) +Comment[sv]=Monterad utdelad Samba-katalog (Microsoft-nätverk) +Comment[ta]=சம்பா ஏற்றப்பட்டது (மைக்ரேசாப்ட் வலை) பகிர்வு +Comment[tg]=Монтажшудаи манбаъи Samba (шабакаи Microsoft) +Comment[th]=ทรัพยากร Samba (เครือข่ายวินโดว์ส) ที่ถูกเม้านท์ +Comment[tr]=Bağlanmış Samba (Microsoft Network) Paylaşımı +Comment[tt]=Totaşqan Samba (Microsoft Çeltäre) Urtağı +Comment[uk]=Змонтований спільний ресурс Samba (мережа Microsoft) +Comment[ven]=Samba yo gonyaho (Vhukwamani ha Microsoft) U kovhekana +Comment[vi]=Chia sẻ SAMBA (mạng của Microsoft) đã kết nối +Comment[wa]=Pårtaedje Samba (Rantoele Microsoft) monté +Comment[xh]=Samba Enyusiweyo (Umsebenzi womnatha we Microsoft) Ulwahlulo +Comment[zh_CN]=挂载的 Samba (Microsoft 网络)共享 +Comment[zh_TW]=已掛載的 Samba (Microsoft 網路) 分享 +Comment[zu]=Isabelo se-Samba esinyusiwe (Uxhumano olusakazekile le-Network) +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/smb_unmounted.desktop b/tdeioslave/media/mimetypes/smb_unmounted.desktop new file mode 100644 index 000000000..98adf4332 --- /dev/null +++ b/tdeioslave/media/mimetypes/smb_unmounted.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Icon=nfs_unmount +Type=MimeType +MimeType=media/smb_unmounted +Comment=Unmounted Samba (Microsoft Network) Share +Comment[af]=Ontkoppelde Samba (Microsoft Netwerk) Hulpbron +Comment[ar]=مشاركة Samba غير محمّلة +Comment[az]=Ayrılmış Samba (Microsoft Şəbəkəsi) Sahəsi +Comment[be]=Адмацаваная агульная тэчка Samba (Сетка Microsoft) +Comment[bg]=Демонтиран ресурс Samba (Microsoft Network) +Comment[bn]=আনমাউন্ট করা সাম্বা (মাইক্রোসফট নেটওয়ার্ক) শেয়ার +Comment[br]=Rennad Samba (rouedad Microsoft) divarc'het +Comment[bs]=Demontiran Samba (Microsoft Network) Share +Comment[ca]=Recurs de Samba (xarxa Microsoft) desmuntat +Comment[cs]=Odpojený Samba (Microsoft Network) prostředek +Comment[csb]=Òdmòntowóné ùdzélenié Sambë (Microsoft Network) +Comment[cy]=Cydranniad Samba (Rhwydwaith Microsoft) wedi'i ddadosod +Comment[da]=Afmonteret Samba-share (Microsoft-netværk) +Comment[de]=Nicht eingebundene Samba-Freigabe (Microsoft-Netzwerk) +Comment[el]=Αποπροσαρτημένος κοινόχρηστος πόρος Samba (Δίκτυο Microsoft) +Comment[eo]=Demetita Sambo-opuzaĵo +Comment[es]=Recurso de Samba desmontado (Red de Microsoft) +Comment[et]=Lahutatud Samba (Microsoft Network) ressurss +Comment[eu]=Samba (Microsoft sarea) partekaketa desmuntatua +Comment[fa]=مشترک Samba (Microsoft Network) پیادهشده +Comment[fi]=Irrotettu Samba-jako (Microsoft-verkko) +Comment[fr]=Partage Samba (réseau Microsoft) non monté +Comment[fy]=Ofkeppele Samba-netwurkboarne (Microsoft-netwurken) +Comment[ga]=Comhroinn Samba (Microsoft Network) Gan Fheistiú +Comment[gl]=Compartición Samba Non Montada (Rede de Microsoft) +Comment[he]=שיתוף Microsoft Network) Samba) מנותק +Comment[hi]=अनमाउन्टेड साम्बा (माइक्रोसाफ्ट नेटवर्क) साझेदारी +Comment[hr]=Nepristupljeno Samba dijeljenje (Microsoft mreža) +Comment[hsb]=Njemontowany Samba-(Microsoft syć)-zapisk +Comment[hu]=Leválasztott Samba-megosztás +Comment[is]=Aftengd Samba (Microsoft Network) sameign +Comment[it]=Condivisione samba (Rete Microsoft) non montata +Comment[ja]=マウントされていない Samba (マイクロソフトのネットワーク) 共有 +Comment[ka]=დემონტირებული Samba რესურსი (Microsoft-ის ქსელი) +Comment[kk]=Тіркеуден шығарған Samba ресурсы (Microsoft желісі) +Comment[km]=Samba (បណ្ដាញ Microsoft) Share មិនទាន់រៀបចំ +Comment[lo]= ຫັງກາລີ +Comment[lt]=Išmontuotas Samba (Microsoft Network) bendro naudojimo diskas +Comment[lv]=Nomontēta Samba (Microsoft tīkla) šāre +Comment[mk]=Одмонтиран Samba заеднички ресурс (Microsoft мрежа) +Comment[mn]=Залгагдаагүй Samba-Нөөцүүд (Microsoft-Сүлжээ) +Comment[ms]=Perkongsian Samba Nyahlekap (Rangkaian Microsoft) +Comment[mt]=Riżors Samba (Microsoft Network) mhux immuntat +Comment[nb]=Avmontert Samba-katalog (Microsoft nettverk) +Comment[nds]=Afhangt Samba-Freegaav (Microsoft-Nettwark) +Comment[ne]=अनमाउन्ट गरिएको साम्बा (माइक्रो सफ्ट सञ्जाल) साझेदारी +Comment[nl]=Afgekoppelde Samba-netwerkbron (Microsoft-netwerkbron) +Comment[nn]=Avmontert Samba-ressurs (Microsoft-nettverk) +Comment[nso]=Kabagano yeo e Theositswego ya Samba (Kgokagano ya Microsoft) +Comment[pa]=ਅਨਮਾਊਟ ਕੀਤੀ ਸਾਂਬਾ (ਮਾਈਕਰੋਸਾਫਟ ਨੈੱਟਵਰਕ) ਸਾਂਝ +Comment[pl]=Odmontowany udział Samby (sieci typu Microsoft Network) +Comment[pt]=Partilha de Samba (Microsoft Network) desmontada +Comment[pt_BR]=Compartilhamento do Samba (Rede Microsoft) desmontado +Comment[ro]=Partajare Samba (rețea Microsoft) nemontată +Comment[ru]=Отмонтированный ресурс сети Microsoft +Comment[rw]=Umugabane Samba (Urusobemiyoboro Microsoft) Wakuwemo +Comment[se]=Gálgajuvvon Samba-resursa (Microsoft-fierbmi) +Comment[sk]=Nepripojený disk Samba (Microsoft Network) +Comment[sl]=Odklopljen deljeni vir Sambe (Microsoftovo omrežje) +Comment[sr]=Демонтирано Samba дељење (Microsoft-ова мрежа) +Comment[sr@Latn]=Demontirano Samba deljenje (Microsoft-ova mreža) +Comment[sv]=Avmonterad utdelad Samba-katalog (Microsoft-nätverk) +Comment[ta]=சம்பாவை வெளியேற்று(மைக்ரேசாப்ட் வலை) பகிர்வு +Comment[tg]=Ҷудо шудаи манбаъи Samba (шабакаи Microsoft) +Comment[th]=ทรัพยากร Samba (เครือข่ายวินโดว์ส) ที่ไม่ถูกเม้านท์ +Comment[tr]=Bağlanmış Samba (Microsoft Network) Paylaşımı +Comment[tt]=Totaşmağan Samba (Microsoft Çeltäre) Urtağı +Comment[uk]=Демонтований спільний ресурс Samba (мережа Microsoft) +Comment[ven]=Samba i songo gonyaho (Vhukamani ha Microsoft) U kovhekana +Comment[vi]=Chia sẻ SAMBA (mạng của Microsoft) đã gỡ ra +Comment[wa]=Pårtaedje Samba (Rantoele Microsoft) dismonté +Comment[xh]=Samba Enganyuswanga (Umsebenzi womnatha we Microsoft) Ulwahlulo +Comment[zh_CN]=未挂载的 Samba (Microsoft 网络)共享 +Comment[zh_TW]=未掛載的 Samba (Microsoft 網路) 分享 +Comment[zu]=Isabelo se-Samba esehlisiwe (Uxhumano olusakazekile lwe-Microsoft) +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/svcd.desktop b/tdeioslave/media/mimetypes/svcd.desktop new file mode 100644 index 000000000..68c965a6f --- /dev/null +++ b/tdeioslave/media/mimetypes/svcd.desktop @@ -0,0 +1,50 @@ +[Desktop Entry] +Type=MimeType +MimeType=media/svcd +Comment=Super Video CD +Comment[ar]=قرص مدمج مرئي Super +Comment[bg]=Супер VCD диск +Comment[bn]=সুপার ভিডিও সিডি +Comment[ca]=CD Súper Vídeo +Comment[da]=Super Video-cd +Comment[eo]=Supervidea lumdisko +Comment[fa]=دیسک فشردۀ ابرویدیویی +Comment[fr]=Super CD vidéo +Comment[fy]=Super Fideo-kompaktskiif +Comment[gl]=Super Vídeo CD +Comment[hi]=सुपर वीडियो सीडी +Comment[hu]=Super Video-CD +Comment[is]=Súper vídeó CD +Comment[it]=Super video CD +Comment[ja]=スーパービデオ CD +Comment[ka]=სუპერ ვიდეო CD +Comment[km]=ស៊ីឌីវីដេអូគុណភាពខ្ពស់ +Comment[mk]=Супер видео ЦД +Comment[ms]=CD Supervideo +Comment[nb]=Super video CD +Comment[nds]=Super-Video-CD +Comment[ne]=सुपर भिडियो सीडी +Comment[nl]=Super Video-cd +Comment[nn]=Super Video-CD +Comment[pa]=ਸੁਪਰ ਵੀਡਿਓ CD +Comment[pl]=Płyta Super Video CD +Comment[pt]=Super Vídeo CD +Comment[pt_BR]=Super vídeo CD (SVCD) +Comment[ro]=CD Super Video +Comment[rw]=CD Videwo Ihebuje +Comment[sr]=Супер видео CD +Comment[sr@Latn]=Super video CD +Comment[sv]=Supervideo-cd +Comment[ta]=சூப்பர் படக்காட்சி குறுந்தகடு +Comment[te]=సూపర్ విడియొ సిడి +Comment[tg]=Супер Видео CD +Comment[th]=ซุเปอร์วิดีโอซีดี +Comment[tr]=Süper Video CD'si +Comment[uk]=Супер відео КД +Comment[uz]=Super-video kompakt-disk +Comment[uz@cyrillic]=Супер-видео компакт-диск +Comment[vi]=Đĩa siêu video CD +Comment[wa]=Super plake lazer CD videyo +Comment[zh_CN]=超级 VCD +Comment[zh_TW]=超級視訊 CD +Icon=cdrom_unmount diff --git a/tdeioslave/media/mimetypes/trash.desktop b/tdeioslave/media/mimetypes/trash.desktop new file mode 100644 index 000000000..340bdccb7 --- /dev/null +++ b/tdeioslave/media/mimetypes/trash.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Icon=trashcan_full +EmptyIcon=trashcan_empty +Type=MimeType +MimeType=media/builtin-trash +Comment=Trash +Patterns=Trash + +X-TDE-AutoEmbed=false diff --git a/tdeioslave/media/mimetypes/vcd.desktop b/tdeioslave/media/mimetypes/vcd.desktop new file mode 100644 index 000000000..dae4ddcaf --- /dev/null +++ b/tdeioslave/media/mimetypes/vcd.desktop @@ -0,0 +1,50 @@ +[Desktop Entry] +Type=MimeType +MimeType=media/vcd +Comment=Video CD +Comment[ar]=قرص مدمج مرئي +Comment[bg]=VCD диск +Comment[bn]=ভিডিও সিডি +Comment[br]=CD Video +Comment[ca]=CD Vídeo +Comment[da]=Video-cd +Comment[el]=Βίντεο CD +Comment[eo]=Video-LD +Comment[fa]=دیسک فشردۀ ویدیویی +Comment[fr]=CD vidéo +Comment[fy]=Fideo-kompaktskiif +Comment[ga]=Dlúthdhiosca Físe +Comment[gl]=Vídeo CD +Comment[hi]=वीडियो सीडी +Comment[hu]=Video-CD +Comment[is]=Vídeó CD +Comment[ja]=ビデオ CD +Comment[kk]=Бейне CD +Comment[km]=ស៊ីឌីវីដេអូ +Comment[mk]=Видео ЦД +Comment[ms]=CD Video +Comment[nds]=Video-CD +Comment[ne]=भिडियो सीडी +Comment[nl]=Video-cd +Comment[nn]=Video-CD +Comment[pa]=ਵੀਡਿਓ CD +Comment[pl]=Płyta Video CD +Comment[pt]=Vídeo CD +Comment[pt_BR]=Vídeo CD (VCD) +Comment[ro]=CD Video +Comment[rw]=CD Videwo +Comment[sr]=Видео CD +Comment[sv]=Video-cd +Comment[ta]=படக்காட்சி குறுந்தகடு +Comment[te]=విడియొ సిడి +Comment[tg]=Видео CD +Comment[th]=วิดีโอซีดี +Comment[tr]=Video CD'si +Comment[uk]=Відео КД +Comment[uz]=Video kompakt-disk +Comment[uz@cyrillic]=Видео компакт-диск +Comment[vi]=Đĩa video CD +Comment[wa]=Plake lazer CD videyo +Comment[zh_CN]=VCD +Comment[zh_TW]=視訊 CD +Icon=cdrom_unmount diff --git a/tdeioslave/media/mimetypes/webbrowser.desktop b/tdeioslave/media/mimetypes/webbrowser.desktop new file mode 100644 index 000000000..0134b05ef --- /dev/null +++ b/tdeioslave/media/mimetypes/webbrowser.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Icon=konqueror +Type=MimeType +MimeType=media/builtin-webbrowser +Comment=Web Browser +Patterns=Web_Browser + +X-TDE-AutoEmbed=false diff --git a/tdeioslave/media/mimetypes/zip_mounted.desktop b/tdeioslave/media/mimetypes/zip_mounted.desktop new file mode 100644 index 000000000..ce82fe968 --- /dev/null +++ b/tdeioslave/media/mimetypes/zip_mounted.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Icon=zip_mount +Type=MimeType +MimeType=media/zip_mounted +Comment=Mounted Zip Disk +Comment[af]=Gekoppelde Zip Disket +Comment[ar]=قرص Zip محمّل +Comment[az]=Bağlanmış Zip Disk +Comment[be]=Прымацаваны дыск Zip +Comment[bg]=Монтиран Zip диск +Comment[bn]=মাউন্ট করা জিপ (Zip) ডিস্ক +Comment[br]=Pladenn Zip marc'het +Comment[bs]=Montiran Zip disk +Comment[ca]=Disc Zip muntat +Comment[cs]=Připojený disk Zip +Comment[csb]=Zamòntowóny disk Zip +Comment[cy]=Disg Zip wedi'i osod +Comment[da]=Monteret zip-disk +Comment[de]=Eingebundenes Zip-Medium +Comment[el]=Προσαρτημένος δίσκος Zip +Comment[eo]=Surmetita ZIP-disko +Comment[es]=Disco Zip montado +Comment[et]=Ühendatud Zip-ketas +Comment[eu]=Zip diska muntatua +Comment[fa]=دیسک فشردۀ سوارشده +Comment[fi]=Liitetty Zip-levy +Comment[fr]=Disque Zip monté +Comment[fy]=Oankeppelee Zip-skiif +Comment[ga]=Diosca Zip feistithe +Comment[gl]=Disco Zip Montado +Comment[he]=תקליטון Zip מחובר +Comment[hi]=माउन्टेड जिप डिस्क +Comment[hr]=Pristupljeni Zip disk +Comment[hu]=Csatlakoztatott Zip-lemez +Comment[is]=Tengdur Zip diskur +Comment[it]=Disco Zip montato +Comment[ja]=マウントされた Zip ディスク +Comment[ka]=მონტირებული диск Zip +Comment[kk]=Тіркеген Zip дискі +Comment[km]=ថាស Zip បានរៀបចំ +Comment[lo]=ຈໍພາບ +Comment[lt]=Sumontuotas Zip diskas +Comment[lv]=Piemontēts Zip disks +Comment[mk]=Монтиран Зип-диск +Comment[mn]=Залгагдсан Zip-Диск +Comment[ms]=Cakera Zip Terlekap +Comment[mt]=Diska Zip immuntata +Comment[nb]=Montert Zip-disk +Comment[nds]=Inhangt Zip-Diskett +Comment[ne]=माउन्ट गरिएको जिप डिस्क +Comment[nl]=Aangekoppelde Zip-diskette +Comment[nn]=Montert Zip-disk +Comment[nso]=Disk yeo e Nameleditswego ya ZIP +Comment[pa]=ਮਾਊਟ ਕੀਤੀ ਜਿਪ ਡਿਸਕ +Comment[pl]=Zamontowana dyskietka Zip +Comment[pt]=Disco ZIP montado +Comment[pt_BR]=Disco Zip Montado +Comment[ro]=Disc ZIP montat +Comment[ru]=Смонтированный диск Zip +Comment[rw]=Disiki Zipu Yashyizwemo +Comment[se]=Čatnojuvvon Zip-skearru +Comment[sk]=Pripojený disk Zip +Comment[sl]=Priklopljen disk Zip +Comment[sr]=Монтиран Zip диск +Comment[sr@Latn]=Montiran Zip disk +Comment[sv]=Monterad Zip-diskett +Comment[ta]=இறக்கப்பட்ட சுருக்க வட்டு +Comment[tg]=Монтажшудаи диски Zip +Comment[th]=ดิสก์ Zip ที่ถูกเม้านท์ +Comment[tr]=Bağlı Zip Diski +Comment[tt]=Totaşqan Zip Disk +Comment[uk]=Змонтований диск Zip +Comment[uz]=Ulangan ZIP-disk +Comment[uz@cyrillic]=Уланган ZIP-диск +Comment[ven]=Disk ya Zip yo gonyiswaho +Comment[vi]=Đĩa ZIP đã kết nối +Comment[wa]=Plakete ZIP montêye +Comment[xh]=Diski Yoqokelelo ndawonye Kwediski +Comment[zh_CN]=挂载的 Zip 磁盘 +Comment[zh_TW]=已掛載的 Zip 磁碟 +Comment[zu]=I-disk yokuhlanganiselwe ndawonye eyenyusiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/zip_unmounted.desktop b/tdeioslave/media/mimetypes/zip_unmounted.desktop new file mode 100644 index 000000000..eaa35577f --- /dev/null +++ b/tdeioslave/media/mimetypes/zip_unmounted.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Icon=zip_unmount +Type=MimeType +MimeType=media/zip_unmounted +Comment=Unmounted Zip Disk +Comment[af]=Ontkoppel Zip Disket +Comment[ar]=قرص Zip غير محمّل +Comment[az]=Ayrılmış Zip Disk +Comment[be]=Адмацаваны дыск Zip +Comment[bg]=Демонтиран Zip диск +Comment[bn]=আনমাউন্ট করা জিপ (Zip) ডিস্ক +Comment[br]=Pladenn Zip divountet +Comment[bs]=Demontiran Zip disk +Comment[ca]=Disc Zip desmuntat +Comment[cs]=Odpojený disk Zip +Comment[csb]=Òdmòntowóny disk Zip +Comment[cy]=Disg Zip wedi'i ddadosod +Comment[da]=Afmonteret zip-disk +Comment[de]=Nicht eingebundenes Zip-Medium +Comment[el]=Αποπροσαρτημένος δίσκος Zip +Comment[eo]=Demetita ZIP-disko +Comment[es]=Disco Zip desmontado +Comment[et]=Lahutatud Zip-ketas +Comment[eu]=Zip diska desmuntatua +Comment[fa]=دیسک فشردۀ پیادهشده +Comment[fi]=Irrotettu Zip-levy +Comment[fr]=Disque Zip non monté +Comment[fy]=Ofkeppele Zip-skiif +Comment[ga]=Diosca Zip neamhfheistithe +Comment[gl]=Disco Zip non Montado +Comment[he]=תקליטון Zip מנותק +Comment[hi]=अनमाउन्टेड जिप डिस्क +Comment[hr]=Nepristupljeni Zip disk +Comment[hu]=Leválasztott Zip-lemez +Comment[is]=Aftengdur Zip diskur +Comment[it]=Disco Zip non montato +Comment[ja]=マウントされていない Zip ディスク +Comment[ka]=დემონტირებული диск Zip +Comment[kk]=Тіркеуден шығарған Zip дискі +Comment[km]=ថាស Zip មិនបានរៀបចំ +Comment[lo]= ຫັງກາລີ +Comment[lt]=Išmontuotas Zip diskas +Comment[lv]=Nomontēts Zip disks +Comment[mk]=Одмонтиран Зип-диск +Comment[mn]=Салгагдсан Zip-Диск +Comment[ms]=Cakera Zip Nyahlekap +Comment[mt]=Diska Zip mhux immuntata +Comment[nb]=Avmontert Zip-disk +Comment[nds]=Afhangt Zip-Diskett +Comment[ne]=अनमाउन्ट गरिएको जिप डिस्क +Comment[nl]=Afgekoppelde Zip-diskette +Comment[nn]=Avmontert Zip-disk +Comment[nso]=Disk yeo e Theositswego ya ZIP +Comment[pa]=ਅਨਮਾਊਟ ਕੀਤੀ ਜ਼ਿਪ ਡਿਸਕ +Comment[pl]=Odmontowana dyskietka Zip +Comment[pt]=Disco ZIP desmontado +Comment[pt_BR]=Disco Zip Desmontado +Comment[ro]=Disc ZIP nemontat +Comment[ru]=Отмонтированный диск Zip +Comment[rw]=Disiki Zipu Yakuwemo +Comment[se]=Gálgajuvvon Zip-skearru +Comment[sk]=Nepripojený disk Zip +Comment[sl]=Odklopljen disk Zip +Comment[sr]=Демонтиран Zip диск +Comment[sr@Latn]=Demontiran Zip disk +Comment[sv]=Avmonterad Zip-diskett +Comment[ta]=வெளியேற்றிய சுருக்க தகடு +Comment[tg]=Ҷудо шудаи диски Zip +Comment[th]=ดิสก์ Zip ที่ไม่ได้เม้านท์ +Comment[tr]=Ayrılmış Zip Diski +Comment[tt]=Totaşmağan Zip Disk +Comment[uk]=Демонтований диск Zip +Comment[uz]=Ulanmagan ZIP-disk +Comment[uz@cyrillic]=Уланмаган ZIP-диск +Comment[ven]=Disk ya Zip i songo gonyiswaho +Comment[vi]=Đĩa ZIP đã gỡ ra +Comment[wa]=Plakete ZIP dismontêye +Comment[xh]=Diski Yoqokelelo ndawone Enganyuswanga +Comment[zh_CN]=挂载的 Zip 磁盘 +Comment[zh_TW]=未掛載的 Zip 磁碟 +Comment[zu]=I-disk yokuhlanganiselwe ndawonye eyehlisiwe +Patterns= + +X-TDE-AutoEmbed=true +X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mounthelper/CMakeLists.txt b/tdeioslave/media/mounthelper/CMakeLists.txt new file mode 100644 index 000000000..ea06278a8 --- /dev/null +++ b/tdeioslave/media/mounthelper/CMakeLists.txt @@ -0,0 +1,36 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/tdeioslave/media/libmediacommon + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### kio_media_mounthelper (executable) ######## + +set( target kio_media_mounthelper ) + +set( ${target}_SRCS + kio_media_mounthelper.cpp decryptdialog.ui dialog.cpp +) + +tde_add_executable( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK mediacommon-static tdeio-shared + DESTINATION ${BIN_INSTALL_DIR} +) diff --git a/tdeioslave/media/mounthelper/Makefile.am b/tdeioslave/media/mounthelper/Makefile.am new file mode 100644 index 000000000..934559d40 --- /dev/null +++ b/tdeioslave/media/mounthelper/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS = kio_media_mounthelper + +INCLUDES = -I$(srcdir)/../libmediacommon $(all_includes) +AM_LDFLAGS = $(all_libraries) + +kio_media_mounthelper_SOURCES = kio_media_mounthelper.cpp decryptdialog.ui dialog.cpp + +kio_media_mounthelper_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor +kio_media_mounthelper_LDADD = ../libmediacommon/libmediacommon.la $(LIB_KIO) $(LIB_TDEUI) + +METASOURCES = AUTO + diff --git a/tdeioslave/media/mounthelper/decryptdialog.ui b/tdeioslave/media/mounthelper/decryptdialog.ui new file mode 100644 index 000000000..939f0a36a --- /dev/null +++ b/tdeioslave/media/mounthelper/decryptdialog.ui @@ -0,0 +1,201 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>DecryptDialog</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>DecryptDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>207</width> + <height>172</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Decrypting Storage Device</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>encryptedIcon</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + <property name="alignment"> + <set>AlignTop</set> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>31</width> + <height>41</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>descLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><p><b>%1</b> is an encrypted storage device.</p> +<p>Please enter the password to decrypt the storage device.</p></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Password:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>passwordEdit</cstring> + </property> + </widget> + <widget class="TQLineEdit"> + <property name="name"> + <cstring>passwordEdit</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + </hbox> + </widget> + <widget class="TQGroupBox" row="2" column="0"> + <property name="name"> + <cstring>errorBox</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Error</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>errorLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/tdeioslave/media/mounthelper/dialog.cpp b/tdeioslave/media/mounthelper/dialog.cpp new file mode 100644 index 000000000..40e99a84d --- /dev/null +++ b/tdeioslave/media/mounthelper/dialog.cpp @@ -0,0 +1,68 @@ +/* This file is part of the KDE project + * Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de> + * + * Based on kryptomedia- Another KDE cryto media application. + * Copyright (C) 2006 Daniel Gollub <dgollub@suse.de> + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "dialog.h" + +Dialog::Dialog(TQString url, TQString iconName) : + KDialogBase(NULL, "Dialog", true, "Decrypt Storage Device", (Cancel|User1), User1, false, KGuiItem(i18n("Decrypt"), "decrypted" )) +{ + decryptDialog = new DecryptDialog(this); + + decryptDialog->errorBox->hide(); + decryptDialog->descLabel->setText(decryptDialog->descLabel->text().arg(url)); + decryptDialog->descLabel->adjustSize(); + decryptDialog->adjustSize(); + + enableButton( User1, false ); + + TQPixmap pixmap = TDEGlobal::iconLoader()->loadIcon(iconName, KIcon::NoGroup, KIcon::SizeLarge); + decryptDialog->encryptedIcon->setPixmap( pixmap ); + + connect(decryptDialog->passwordEdit, TQT_SIGNAL (textChanged(const TQString &)), this, TQT_SLOT (slotPasswordChanged(const TQString &))); + + setMainWidget(decryptDialog); +} + +Dialog::~Dialog() +{ + delete decryptDialog; +} + +TQString Dialog::getPassword() +{ + return decryptDialog->passwordEdit->text(); +} + +void Dialog::slotDialogError(TQString errorMsg) +{ + kdDebug() << __func__ << "(" << errorMsg << " )" << endl; + + decryptDialog->errorLabel->setText(TQString("<b>%1</b>").arg(errorMsg)); + decryptDialog->errorBox->show(); +} + +void Dialog::slotPasswordChanged(const TQString &text) +{ + enableButton( User1, !text.isEmpty() ); +} + +#include "dialog.moc" diff --git a/tdeioslave/media/mounthelper/dialog.h b/tdeioslave/media/mounthelper/dialog.h new file mode 100644 index 000000000..dc1d552d8 --- /dev/null +++ b/tdeioslave/media/mounthelper/dialog.h @@ -0,0 +1,61 @@ +/* This file is part of the KDE project + * Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de> + * + * Based on kryptomedia- Another KDE cryto media application. + * Copyright (C) 2006 Daniel Gollub <dgollub@suse.de> + * + * This library 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 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef DIALOG_H_ +#define DIALOG_H_ + +#include <kmessagebox.h> +#include <klocale.h> +#include <tdeconfig.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <kiconloader.h> + +#include <tqlineedit.h> +#include <tqlabel.h> +#include <tqgroupbox.h> + +#include "decryptdialog.h" + +class KryptoMedia; + +class Dialog : public KDialogBase +{ + +Q_OBJECT + +public: + Dialog(TQString url, TQString iconName); + ~Dialog(); + + TQString getPassword(); + +public slots: + void slotDialogError(TQString errorMsg); + void slotPasswordChanged(const TQString &text); + +private: + DecryptDialog *decryptDialog; +}; + +#endif // DIALOG_H_ + diff --git a/tdeioslave/media/mounthelper/kio_media_mounthelper.cpp b/tdeioslave/media/mounthelper/kio_media_mounthelper.cpp new file mode 100644 index 000000000..f321293d6 --- /dev/null +++ b/tdeioslave/media/mounthelper/kio_media_mounthelper.cpp @@ -0,0 +1,282 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + Parts of this file are + Copyright 2003 Waldo Bastian <bastian@kde.org> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <kcmdlineargs.h> +#include <klocale.h> +#include <kapplication.h> +#include <kurl.h> +#include <kmessagebox.h> +#include <dcopclient.h> +#include <dcopref.h> +#include <tqtimer.h> +#include <stdlib.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kprocess.h> +#include <kstartupinfo.h> +#include <kmimetype.h> + +#include "dialog.h" +#include "kio_media_mounthelper.h" + +const Medium MountHelper::findMedium(const KURL &url) +{ + DCOPRef mediamanager("kded", "mediamanager"); + + // Try filename first + DCOPReply reply = mediamanager.call( "properties", url.fileName() ); + if ( !reply.isValid() ) { + m_errorStr = i18n("The TDE mediamanager is not running.")+"\n"; + return Medium(TQString::null, TQString::null, TQString::null); + } + const Medium& medium = Medium::create(reply); + if ( medium.id().isEmpty() ) { + // Try full URL now + reply = mediamanager.call( "properties", url.prettyURL() ); + if ( !reply.isValid() ) { + m_errorStr = i18n("Internal Error"); + return Medium(TQString::null, TQString::null, TQString::null); + } + return Medium::create(reply); + } else { + return medium; + } +} + +MountHelper::MountHelper() : TDEApplication() +{ + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + + m_errorStr = TQString::null; + + KURL url(args->url(0)); + const Medium medium = findMedium(url); + + if ( medium.id().isEmpty() ) + { + if (m_errorStr.isEmpty()) + m_errorStr+= i18n("%1 cannot be found.").arg(url.prettyURL()); + TQTimer::singleShot(0, this, TQT_SLOT(error()) ); + return; + } + + if ( !medium.isMountable() && !args->isSet("e") && !args->isSet("s")) + { + m_errorStr = i18n("%1 is not a mountable media.").arg(url.prettyURL()); + TQTimer::singleShot(0, this, TQT_SLOT(error()) ); + return; + } + + TQString device = medium.deviceNode(); + TQString mount_point = medium.mountPoint(); + + m_isCdrom = medium.mimeType().find("dvd")!=-1 + || medium.mimeType().find("cd")!=-1; + + if (args->isSet("d")) + { + if (!medium.isEncrypted()) + { + m_errorStr = i18n("%1 is not an encrypted media.").arg(url.prettyURL()); + TQTimer::singleShot(0, this, TQT_SLOT(error()) ); + return; + } + if (!medium.needDecryption()) + { + m_errorStr = i18n("%1 is already decrypted.").arg(url.prettyURL()); + TQTimer::singleShot(0, this, TQT_SLOT(error()) ); + return; + } + + TQString iconName = medium.iconName(); + if (iconName.isEmpty()) + { + TQString mime = medium.mimeType(); + iconName = KMimeType::mimeType(mime)->icon(mime, false); + } + + m_mediumId = medium.id(); + dialog = new Dialog(url.prettyURL(), iconName); + dialog->show(); + + connect(dialog, TQT_SIGNAL (user1Clicked()), this, TQT_SLOT (slotSendPassword())); + connect(dialog, TQT_SIGNAL (cancelClicked()), this, TQT_SLOT (slotCancel())); + connect(this, TQT_SIGNAL (signalPasswordError(TQString)), dialog, TQT_SLOT (slotDialogError(TQString))); + } + else if (args->isSet("u")) + { + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "unmount", medium.id()); + if (reply.isValid()) + reply.get(m_errorStr); + kdDebug() << "medium unmount " << m_errorStr << endl; + if (m_errorStr.isNull()) + ::exit(0); + else + error(); + } + else if (args->isSet("s") || args->isSet("e")) + { + DCOPRef mediamanager("kded", "mediamanager"); + + /* + * We want to call mediamanager unmount before invoking eject. That's + * because unmount would provide an informative error message in case of + * failure. However, there are cases when unmount would fail + * (supermount, slackware, see bug#116209) but eject would succeed. + * Thus if unmount fails, save unmount error message and invokeEject() + * anyway. Only if both unmount and eject fail, notify the user by + * displaying the saved error message (see ejectFinished()). + */ + if (medium.isMounted()) + { + DCOPReply reply = mediamanager.call( "unmount", medium.id()); + if (reply.isValid()) + reply.get(m_errorStr); + } + + /* If this is a decrypted volume and there is no error yet + * we try to teardown the decryption */ + if (m_errorStr.isNull() && medium.isEncrypted() && !medium.clearDeviceUdi().isNull()) + { + DCOPReply reply = mediamanager.call( "undecrypt", medium.id()); + if (reply.isValid()) + reply.get(m_errorStr); + } + + if (m_errorStr.isNull()) + invokeEject(device, true); + else + error(); + } + else + { + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "mount", medium.id()); + if (reply.isValid()) + reply.get(m_errorStr); + if (m_errorStr.isNull()) + ::exit(0); + else + error(); + } +} + +void MountHelper::invokeEject(const TQString &device, bool quiet) +{ + TDEProcess *proc = new TDEProcess(TQT_TQOBJECT(this)); + *proc << "kdeeject"; + if (quiet) + { + *proc << "-q"; + } + *proc << device; + connect( proc, TQT_SIGNAL(processExited(TDEProcess *)), + this, TQT_SLOT( ejectFinished(TDEProcess *) ) ); + proc->start(); +} + +void MountHelper::ejectFinished(TDEProcess* proc) +{ + /* + * If eject failed, report the error stored in m_errorStr + */ + if (proc->normalExit() && proc->exitStatus() == 0) { + ::exit(0); + } else { + if (m_errorStr.isEmpty()) { + if (m_isCdrom) + m_errorStr = i18n("The device was successfully unmounted, but the tray could not be opened"); + else + m_errorStr = i18n("The device was successfully unmounted, but could not be ejected"); + } +//X Comment this because the error is useless as long as the unmount is successful. +//X TQTimer::singleShot(0, this, TQT_SLOT(error())); + ::exit(0); + } +} + +void MountHelper::error() +{ + TQString prettyErrorString = m_errorStr; + if (m_errorStr.contains("<") && m_errorStr.contains(">")) { + if (!m_errorStr.contains("<qt>")) { + prettyErrorString = TQString("<qt>%1</qt>").arg(m_errorStr); + } + } + KMessageBox::error(0, prettyErrorString); + ::exit(1); +} + +void MountHelper::slotSendPassword() +{ + DCOPRef mediamanager("kded", "mediamanager"); + + DCOPReply reply = mediamanager.call( "decrypt", m_mediumId, dialog->getPassword() ); + if (!reply.isValid()) { + m_errorStr = i18n("The TDE mediamanager is not running."); + error(); + } else { + TQString errorMsg = reply; + if (errorMsg.isNull()) { + exit(0); + } else { + emit signalPasswordError(errorMsg); + } + } +} + +void MountHelper::slotCancel() +{ + exit(0); +} + +static KCmdLineOptions options[] = +{ + { "d", I18N_NOOP("Decrypt given URL"), 0 }, + { "u", I18N_NOOP("Unmount given URL"), 0 }, + { "m", I18N_NOOP("Mount given URL (default)"), 0 }, + { "e", I18N_NOOP("Eject given URL via kdeeject"), 0}, + { "s", I18N_NOOP("Unmount and Eject given URL (necessary for some USB devices)"), 0}, + {"!+URL", I18N_NOOP("media:/ URL to mount/unmount/eject/remove"), 0 }, + KCmdLineLastOption +}; + + +int main(int argc, char **argv) +{ + TDECmdLineArgs::init(argc, argv, "kio_media_mounthelper", + "kio_media_mounthelper", "kio_media_mounthelper", + "0.1"); + + TDECmdLineArgs::addCmdLineOptions( options ); + TDEGlobal::locale()->setMainCatalogue("kio_media"); + TDEApplication::addCmdLineOptions(); + + if (TDECmdLineArgs::parsedArgs()->count()==0) TDECmdLineArgs::usage(); + TDEApplication *app = new MountHelper(); + + KStartupInfo::appStarted(); + app->dcopClient()->attach(); + return app->exec(); +} + +#include "kio_media_mounthelper.moc" diff --git a/tdeioslave/media/mounthelper/kio_media_mounthelper.h b/tdeioslave/media/mounthelper/kio_media_mounthelper.h new file mode 100644 index 000000000..50ea88b3b --- /dev/null +++ b/tdeioslave/media/mounthelper/kio_media_mounthelper.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kvin Ottens <ervin ipsquad net> + Parts of this file are + Copyright 2003 Waldo Bastian <bastian@kde.org> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _KIO_MEDIA_MOUNTHELPER_H_ +#define _KIO_MEDIA_MOUNTHELPER_H_ + +#include <kapplication.h> +#include <tqstring.h> +#include <tdeio/job.h> + +#include "medium.h" + +class Dialog; + +class MountHelper : public TDEApplication +{ + Q_OBJECT +public: + MountHelper(); + +private: + const Medium findMedium(const KURL &url); + void invokeEject(const TQString &device, bool quiet=false); + TQString m_errorStr; + bool m_isCdrom; + TQString m_mediumId; + Dialog *dialog; + +private slots: + void slotSendPassword(); + void slotCancel(); + void ejectFinished(TDEProcess* proc); + void error(); + +signals: + void signalPasswordError(TQString errorMsg); +}; + +#endif diff --git a/tdeioslave/media/propsdlgplugin/CMakeLists.txt b/tdeioslave/media/propsdlgplugin/CMakeLists.txt new file mode 100644 index 000000000..f029b52ab --- /dev/null +++ b/tdeioslave/media/propsdlgplugin/CMakeLists.txt @@ -0,0 +1,35 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES media_propsdlgplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + + +##### media_propsdlgplugin (module) ############# + +tde_add_kpart( media_propsdlgplugin AUTOMOC + SOURCES + propertiespage.cpp propertiespagegui.ui propsdlgshareplugin.cpp + LINK mediacommon-static tdeio-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/tdeioslave/media/propsdlgplugin/Makefile.am b/tdeioslave/media/propsdlgplugin/Makefile.am new file mode 100644 index 000000000..5e3d8af83 --- /dev/null +++ b/tdeioslave/media/propsdlgplugin/Makefile.am @@ -0,0 +1,12 @@ +METASOURCES = AUTO + +kde_module_LTLIBRARIES = media_propsdlgplugin.la + +media_propsdlgplugin_la_LIBADD = ../libmediacommon/libmediacommon.la $(LIB_KIO) +media_propsdlgplugin_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) + +AM_CPPFLAGS = $(all_includes) + +kde_services_DATA = media_propsdlgplugin.desktop + +media_propsdlgplugin_la_SOURCES = propertiespage.cpp propertiespagegui.ui propsdlgshareplugin.cpp diff --git a/tdeioslave/media/propsdlgplugin/media_propsdlgplugin.desktop b/tdeioslave/media/propsdlgplugin/media_propsdlgplugin.desktop new file mode 100644 index 000000000..2b24348c5 --- /dev/null +++ b/tdeioslave/media/propsdlgplugin/media_propsdlgplugin.desktop @@ -0,0 +1,102 @@ +[Desktop Entry] +Type=Service +Name=Media Properties Page +Name[bg]=Страница с информация за носителя +Name[bn]=মিডিয়া বৈশিষ্ট্যাবলী পৃষ্ঠা +Name[ca]=Pàgina de propietats de suport +Name[cs]=Stránka vlastností média +Name[csb]=Starna swòjiznë media +Name[da]=Medieegenskabsside +Name[de]=Eigenschaften von Medien +Name[el]=Σελίδα ιδιοτήτων μέσων +Name[eo]=Medio-Ecoj Paĝo +Name[es]=Página de propiedades de medios +Name[et]=Andmekandjate omadused +Name[fa]=صفحۀ ویژگیهای رسانه +Name[fi]=Mediaominaisuudet +Name[fr]=Page de propriétés du média +Name[fy]=Media eigenskip side +Name[gl]=Páxina de Propiedades dos Media +Name[he]=דף מאפייני מדיה +Name[hr]=Stranica svojstva medija +Name[hu]=Médiajellemzők lap +Name[is]=Eiginleikar miðils +Name[it]=Pagina delle proprietà dei dispositivi di archiviazione +Name[ja]=メディア属性ページ +Name[kk]=Медиа қасиеттер беті +Name[km]=ទំព័រលក្ខណៈសម្បត្តិមេឌៀ +Name[lt]=Media įrenginio savybių puslapis +Name[nb]=Side for medievarsling +Name[nds]=Medienegenschappen-Siet +Name[ne]=मिडिया विशेषता पृष्ठ +Name[nl]=Pagina met media-eigenschappen +Name[nn]=Side for medieeigenskapar +Name[pa]=ਮੀਡਿਆ ਵਿਸ਼ੇਸ਼ਤਾ ਸਫ਼ਾ +Name[pl]=Strona właściwości nośnika +Name[pt]=Página de Propriedades de Suportes Físicos +Name[pt_BR]=Página de Propriedades da Mídia +Name[ro]=Pagina de proprietăți media +Name[ru]=Свойства диска +Name[sk]=Strana vlastností média +Name[sl]=Stran z lastnostmi nosilca +Name[sr]=Страна са својствима медијума +Name[sr@Latn]=Strana sa svojstvima medijuma +Name[sv]=Sida för mediaegenskaper +Name[te]=మాధ్యమ గుణాల పుట +Name[th]=หน้าคุณสมบัติของสื่อ +Name[tr]=Ortam Özellikleri Sayfası +Name[uk]=Сторінка властивостей носіїв інформації +Name[uz]=Saqlash uskunalarning xossalari +Name[uz@cyrillic]=Сақлаш ускуналарнинг хоссалари +Name[vi]=Trang tài sản phương tiện +Name[wa]=Pådje des prôpietés media +Name[zh_CN]=介质属性页面 +Name[zh_TW]=媒體內容頁 +Comment=Konqueror properties dialog plugin to configure mount behaviour +Comment[bg]=Приставка за настройване на монтирането (Konqueror) +Comment[ca]=Diàleg de propietats de l'endollable Konqueror per a configurar el comportament de muntatge +Comment[cs]=Dialog nastavení chování připojení modulu pro Konqueror +Comment[csb]=Plugins òkna swòjiznë Konquerora do kònfigùracëji zachówaniô mòntowaniô +Comment[da]=Konqueror plugin med egenskabsdialog til at indstille monteringsopførsel +Comment[de]=Konqueror-Modul zum Einstellen des Verhaltens beim Einbinden +Comment[el]=Πρόσθετο διαλόγου ιδιοτήτων του Konqueror για τη ρύθμιση της συμπεριφοράς προσάρτησης +Comment[eo]=Konkeranto eco-dialogo kromaĵo por agordi surmeto-konduton +Comment[es]=Complemento de la ventana de propiedades de Konqueror para configurar el comportamiento del montaje +Comment[et]=Konquerori seadistustedialoogi plugin andmekandjate ühendamise seadistamiseks +Comment[fa]=وصلۀ محاورۀ ویژگیهای Konqueror برای پیکربندی رفتار سوار کردن +Comment[fi]=Konquerorin ominaisuussovelma, joka tarkkailee liitospisteitä +Comment[fr]=Module de Konqueror pour configurer le comportement du montage +Comment[fy]=Konqueror eigenskip-dialooch-plugin om keppelgedrach te konfigurearjen +Comment[gl]=Extensión de diálogo de propiedades para Konqueror para configurar o comportamento das montaxes +Comment[he]=תוסף חלון מאפיינים של Konqueror לקביעת אפשרויות חיבור +Comment[hr]=Konqueror dodatak dijaloga svojstava za konfiguriranje načina pristupanja +Comment[hu]=Konqueror beállítómodul a csatlakoztatási mód megadásához +Comment[is]=Konqueror eiginleikagluggi til að stilla tengihegðun +Comment[it]=Plugin della configurazione di Konqueror per configurare il montaggio +Comment[ja]=mount の挙動を設定する Konqueror プロパティダイアログ プラグイン +Comment[kk]=Жалғау тәртібін баптайтын Konqueror қасиеттер диалогының плагин модулі +Comment[km]=កម្មវិធីជំនួយឲ្យមានប្រអប់លក្ខណៈសម្បត្តិ Konqueror ដើម្បីកំណត់រចនាសម្ព័ន្ធឥរិយាបថម៉ោន +Comment[lt]=Konqueror savybių dialogo priedas, leidžiantis konfigūruoti montavimo elgseną +Comment[nb]=Et programtillegg for å sette opp montering av enheter i Konqueror +Comment[nds]=Egenschappendialoog-Plugin för Konqueror för't Instellen vun't Inhangbedregen +Comment[ne]=माउन्ट व्यवहार कन्फिगर गर्न कन्क्वेरर विशेषता संवाद प्लगइन +Comment[nl]=Dialoogvenster voor Konqueror om het aankoppelgedrag in te stellen +Comment[nn]=Programtillegg for oppsett av montering i Konqueror +Comment[pl]=Wtyczka okna właściwości Konquerora do konfiguracji zachowania montowania +Comment[pt]='Plugin' da janela de propriedades do Konqueror, para configurar o comportamento da montagem +Comment[pt_BR]=Plug-in do diálogo de propriedades do Konqueror para configurar o comportamento da montagem +Comment[ro]=Plugin de dialog al proprietăților Konqueror pentru a configura comportarea lui mount +Comment[ru]=Модуль свойств для Konqueror, отвечающий за поведение при подключении файловых систем +Comment[sk]=Modul Konqueror dialógu vlastností pre konfiguráciu správania pripojenia +Comment[sl]=Vstavek za Konqueror s katerim se nastavlja obnašanje priklopa medijev +Comment[sr]=Прикључак са својствима Konqueror-а за подешавање понашања при монтирању +Comment[sr@Latn]=Priključak sa svojstvima Konqueror-a za podešavanje ponašanja pri montiranju +Comment[sv]=Konqueror insticksprogram med egenskapsdialogruta för att anpassa monteringsbeteende +Comment[th]=ปลั๊กอินกล่องตอบโต้ของ Konqueror ใช้เพื่อปรับแต่งพฤติกรรมการเมานท์สื่อ +Comment[uk]=Втулок вікна властивостей Konqueror для налаштування поведінки монтування +Comment[vi]=bổ sung hộp thoại tài sản Konqueror để cấu hình ứng xử gắn kết +Comment[wa]=Tchôke-divins di dvize di prôpietés Konqueror po-z apontyî l' dujhance do montaedje +Comment[zh_CN]=配置挂载行为的 Konqueror 属性对话框插件 +Comment[zh_TW]=Konqueror 內容對話框外掛程式,用於設定掛載的行為 +X-TDE-Library=media_propsdlgplugin +ServiceTypes=KPropsDlg/Plugin,media/audiocd,media/hdd_mounted,media/hdd_unmounted,media/hdd_mounted_decrypted,media/hdd_unmounted_decrypted,media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_mounted_decrypted,media/cdrom_unmounted_decrypted,media/cdwriter_mounted,media/cdwriter_mounted_decrypted,media/nfs_mounted,media/cdwriter_unmounted,media/cdwriter_unmounted_decrypted,media/nfs_unmounted,media/removable_mounted,media/removable_mounted_decrypted,media/dvd_mounted,media/dvd_mounted_decrypted,media/removable_unmounted,media/removable_unmounted_decrypted,media/dvd_unmounted,media/dvd_unmounted_decrypted,media/smb_mounted,media/dvdvideo,media/smb_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/floppy_mounted,media/zip_mounted,media/floppy_unmounted,media/zip_unmounted,media/camera_mounted,media/camera_unmounted diff --git a/tdeioslave/media/propsdlgplugin/propertiespage.cpp b/tdeioslave/media/propsdlgplugin/propertiespage.cpp new file mode 100644 index 000000000..33d481ef5 --- /dev/null +++ b/tdeioslave/media/propsdlgplugin/propertiespage.cpp @@ -0,0 +1,229 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <tqcheckbox.h> +#include <tqtooltip.h> +#include <tqbuttongroup.h> +#include <tqlineedit.h> +#include <tqfileinfo.h> +#include <tqlabel.h> +#include <tqregexp.h> +#include <kpushbutton.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <tqcombobox.h> +#include <tqtimer.h> +#include <kdebug.h> +#include "propertiespage.h" +#include <dcopref.h> + +// keep in sync with .ui and kded module +const char *short_names[] = {"lower", "win95", "winnt", "mixed", 0 }; +const char *journales[] = {"data", "ordered", "writeback", 0 }; + +PropertiesPage::PropertiesPage(TQWidget* parent, const TQString &_id) + : PropertiesPageGUI(parent), id(_id) +{ + kdDebug() << "props page " << id << endl; + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "mountoptions", id); + + TQStringList list; + + if (reply.isValid()) + list = reply; + + if (list.size()) { + kdDebug() << "list " << list << endl; + + for (TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it) + { + TQString key = (*it).left((*it).find('=')); + TQString value = (*it).mid((*it).find('=') + 1); + kdDebug() << "key '" << key << "' value '" << value << "'\n"; + options[key] = value; + } + + if (!options.contains("ro")) + option_ro->hide(); + else + option_ro->setChecked(options["ro"] == "true"); + connect( option_ro, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + + if (!options.contains("quiet")) + option_quiet->hide(); + else + option_quiet->setChecked(options["quiet"] == "true"); + connect( option_quiet, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + + if (!options.contains("sync")) + option_sync->hide(); + else + option_sync->setChecked(options["sync"] == "true"); + connect( option_sync, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + + if (!options.contains("atime")) + option_atime->hide(); + else + option_atime->setChecked(options["atime"] == "true"); + connect( option_atime, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + + if (!options.contains("flush")) + option_flush->hide(); + else + option_flush->setChecked(options["flush"] == "true"); + connect( option_flush, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + + if (!options.contains("utf8")) + option_utf8->hide(); + else + option_utf8->setChecked(options["utf8"] == "true"); + connect( option_utf8, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + + if (!options.contains("uid")) + option_uid->hide(); + else + option_uid->setChecked(options["uid"] == "true"); + connect( option_uid, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + + if (!options.contains("shortname")) + { + option_shortname->hide(); + text_shortname->hide(); + } + else + { + for (int index = 0; short_names[index]; ++index) + if (options["shortname"] == short_names[index]) + { + option_shortname->setCurrentItem(index); + break; + } + connect( option_shortname, TQT_SIGNAL( activated(int) ), TQT_SIGNAL( changed() ) ); + } + + if (!options.contains("journaling")) + { + text_journaling->hide(); + option_journaling->hide(); + } + else + { + for (int index = 0; journales[index]; ++index) + if (options["journaling"] == journales[index]) + { + option_journaling->setCurrentItem(index); + break; + } + connect( option_journaling, TQT_SIGNAL( activated(int) ), TQT_SIGNAL( changed() ) ); + } + + label_filesystem->setText(i18n("Filesystem: %1").arg(options["filesystem"])); + option_mountpoint->setText(options["mountpoint"]); + connect( option_mountpoint, TQT_SIGNAL( textChanged( const TQString &) ), TQT_SIGNAL( changed() ) ); + option_automount->setChecked(options["automount"] == "true"); + connect( option_automount, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + + bool has_groupbox_specific = true; + if (!options.contains("journaling") && + !options.contains("shortname") && + !options.contains("uid") && + !options.contains("utf8") && + !options.contains("flush")) { + groupbox_specific->hide(); + has_groupbox_specific = false; + } + + // The order is important - we want groupboxes to hide automatically depending on use_defaults + // but don't want to emit changed() until user actually changes something. + connect( option_defaults, TQT_SIGNAL( toggled(bool) ), groupbox_generic, SLOT( setHidden(bool) ) ); + if (has_groupbox_specific) + connect( option_defaults, TQT_SIGNAL( toggled(bool) ), groupbox_specific, SLOT( setHidden(bool) ) ); + option_defaults->setChecked(options["use_defaults"] == "true"); + connect( option_defaults, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + + } else { + + groupbox_generic->setEnabled(false); + groupbox_specific->setEnabled(false); + label_filesystem->hide(); + } +} + +PropertiesPage::~PropertiesPage() +{ +} + +bool PropertiesPage::save() +{ + TQStringList result; + + if (options.contains("ro")) + result << TQString("ro=%1").arg(option_ro->isChecked() ? "true" : "false"); + + if (options.contains("quiet")) + result << TQString("quiet=%1").arg(option_quiet->isChecked() ? "true" : "false"); + + if (options.contains("sync")) + result << TQString("sync=%1").arg(option_sync->isChecked() ? "true" : "false"); + + if (options.contains("atime")) + result << TQString("atime=%1").arg(option_atime->isChecked() ? "true" : "false"); + + if (options.contains("flush")) + result << TQString("flush=%1").arg(option_flush->isChecked() ? "true" : "false"); + + if (options.contains("utf8")) + result << TQString("utf8=%1").arg(option_utf8->isChecked() ? "true" : "false"); + + if (options.contains("uid")) + result << TQString("uid=%1").arg(option_uid->isChecked() ? "true" : "false"); + + if (options.contains("shortname")) + result << TQString("shortname=%1").arg(short_names[option_shortname->currentItem()]); + + if (options.contains("journaling")) + result << TQString("journaling=%1").arg(journales[option_journaling->currentItem()]); + + TQString mp = option_mountpoint->text(); + if (!mp.startsWith("/media/")) + { + KMessageBox::sorry(this, i18n("Mountpoint has to be below /media")); + return false; + } + result << TQString("mountpoint=%1").arg(mp); + result << TQString("automount=%1").arg(option_automount->isChecked() ? "true" : "false"); + result << TQString("use_defaults=%1").arg(option_defaults->isChecked() ? "true" : "false"); + + kdDebug() << result << endl; + + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "setMountoptions", id, result); + + if (reply.isValid()) + return (bool)reply; + else { + KMessageBox::sorry(this, + i18n("Saving the changes failed")); + + return false; + } +} + +#include "propertiespage.moc" diff --git a/tdeioslave/media/propsdlgplugin/propertiespage.h b/tdeioslave/media/propsdlgplugin/propertiespage.h new file mode 100644 index 000000000..50a480719 --- /dev/null +++ b/tdeioslave/media/propsdlgplugin/propertiespage.h @@ -0,0 +1,46 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PROPERTIESPAGE_H +#define PROPERTIESPAGE_H + +#include "propertiespagegui.h" +#include <tqmap.h> + +class TQCheckBox; +class Medium; + +class PropertiesPage : public PropertiesPageGUI +{ + Q_OBJECT + +public: + PropertiesPage(TQWidget* parent, const TQString &_id); + virtual ~PropertiesPage(); + + bool save(); + +protected: + + TQMap<TQString,TQString> options; + TQString id; + +}; + +#endif diff --git a/tdeioslave/media/propsdlgplugin/propertiespagegui.ui b/tdeioslave/media/propsdlgplugin/propertiespagegui.ui new file mode 100644 index 000000000..2a6ff899e --- /dev/null +++ b/tdeioslave/media/propsdlgplugin/propertiespagegui.ui @@ -0,0 +1,385 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>PropertiesPageGUI</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>PropertiesPageGUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>219</width> + <height>446</height> + </rect> + </property> + <property name="caption"> + <string>PropertiesPageGUI</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>option_defaults</cstring> + </property> + <property name="text"> + <string>Use default mount options</string> + </property> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>groupbox_generic</cstring> + </property> + <property name="title"> + <string>Generic Mount Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout15</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>option_ro</cstring> + </property> + <property name="text"> + <string>Read only</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Mount the file system read-only.</string> + </property> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>option_quiet</cstring> + </property> + <property name="text"> + <string>Quiet</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Attempts to chown or chmod files do not return errors, although they fail. Use with caution!</string> + </property> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>option_sync</cstring> + </property> + <property name="text"> + <string>Synchronous</string> + </property> + <property name="whatsThis" stdset="0"> + <string>All I/O to the file system should be done synchronously.</string> + </property> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>option_atime</cstring> + </property> + <property name="text"> + <string>Access time updates</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Update inode access time for each access.</string> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout14</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Mountpoint:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>option_mountpoint</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>Under what directory this file system shall be mounted. Please note that there is no guarantee that the system will respect your wish. For one the directory has to be below /media - and it does not yet have to exist.</string> + </property> + </widget> + <widget class="TQLineEdit"> + <property name="name"> + <cstring>option_mountpoint</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>option_automount</cstring> + </property> + <property name="text"> + <string>Mount automatically</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Mount this file system automatically.</string> + </property> + </widget> + </vbox> + </widget> + </vbox> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>groupbox_specific</cstring> + </property> + <property name="title"> + <string>Filesystem Specific Mount Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>option_flush</cstring> + </property> + <property name="text"> + <string>Flushed IO</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Always flush all data to the hot plug devices immediately and don't cache it.</string> + </property> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>option_utf8</cstring> + </property> + <property name="text"> + <string>UTF-8 charset</string> + </property> + <property name="whatsThis" stdset="0"> + <string>UTF8 is the filesystem safe 8-bit encoding of Unicode that is used by the console. It can be be enabled for the filesystem with this option.</string> + </property> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>option_uid</cstring> + </property> + <property name="text"> + <string>Mount as user</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Mount this file system as user.</string> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>text_journaling</cstring> + </property> + <property name="text"> + <string>Journaling:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>option_journaling</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string><h2>Specifies the journalling mode for file data. Metadata is always journaled. </h2> + +<h3><b>All Data</b></h3> + All data is committed into the journal prior to being written into the main file system. This is the slowest variant with the highest data security. + +<h3><b>Ordered</b></h3> + All data is forced directly out to the main file system prior to its metadata being committed to the journal. + +<h3><b>Write Back</b></h3> + Data ordering is not preserved - data may be written into the main file system after its metadata has been committed to the journal. This is rumoured to be the highest-throughput option. It guarantees internal file system integrity, however it can allow old data to appear in files after a crash and journal recovery.</string> + </property> + </widget> + <widget class="TQComboBox"> + <item> + <property name="text"> + <string>All Data</string> + </property> + </item> + <item> + <property name="text"> + <string>Ordered</string> + </property> + </item> + <item> + <property name="text"> + <string>Write Back</string> + </property> + </item> + <property name="name"> + <cstring>option_journaling</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string><h2>Specifies the journalling mode for file data. Metadata is always journaled. </h2> + +<h3><b>All Data</b></h3> + All data is committed into the journal prior to being written into the main file system. This is the slowest variant with the highest data security. + +<h3><b>Ordered</b></h3> + All data is forced directly out to the main file system prior to its metadata being committed to the journal. + +<h3><b>Write Back</b></h3> + Data ordering is not preserved - data may be written into the main file system after its metadata has been committed to the journal. This is rumoured to be the highest-throughput option. It guarantees internal file system integrity, however it can allow old data to appear in files after a crash and journal recovery.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout14</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>text_shortname</cstring> + </property> + <property name="text"> + <string>Short names:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>option_shortname</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string><h2>Defines the behaviour for creation and display of filenames which fit into 8.3 characters. If a long name for a file exists, it will always be preferred display.</h2> + +<h3><b>Lower</b></h3> +Force the short name to lower case upon display; store a long name when the short name is not all upper case. + +<h3><b>Windows 95</b></h3> +Force the short name to upper case upon display; store a long name when the short name is not all upper case. + +<h3><b>Windows NT</b></h3> +Display the shortname as is; store a long name when the short name is not all lower case or all upper case. + +<h3><b>Mixed</b></h3> +Display the short name as is; store a long name when the short name is not all upper case.</string> + </property> + </widget> + <widget class="TQComboBox"> + <item> + <property name="text"> + <string>Lower</string> + </property> + </item> + <item> + <property name="text"> + <string>Windows 95</string> + </property> + </item> + <item> + <property name="text"> + <string>Windows NT</string> + </property> + </item> + <item> + <property name="text"> + <string>Mixed</string> + </property> + </item> + <property name="name"> + <cstring>option_shortname</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string><h2>Defines the behaviour for creation and display of filenames which fit into 8.3 characters. If a long name for a file exists, it will always be preferred display.</h2> + +<h3><b>Lower</b></h3> +Force the short name to lower case upon display; store a long name when the short name is not all upper case. + +<h3><b>Windows 95</b></h3> +Force the short name to upper case upon display; store a long name when the short name is not all upper case. + +<h3><b>Windows NT</b></h3> +Display the shortname as is; store a long name when the short name is not all lower case or all upper case. + +<h3><b>Mixed</b></h3> +Display the short name as is; store a long name when the short name is not all upper case.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </vbox> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>label_filesystem</cstring> + </property> + <property name="text"> + <string>Filesystem: iso9660</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<connections> + <connection> + <sender>option_ro</sender> + <signal>stateChanged(int)</signal> + <receiver>PropertiesPageGUI</receiver> + <slot>changedSlot()</slot> + </connection> +</connections> +<variables> + <variable>bool m_hasChanged;</variable> +</variables> +<Q_SIGNALS> + <signal>changed()</signal> +</Q_SIGNALS> +<Q_SLOTS> + <slot access="protected">changedSlot()</slot> +</Q_SLOTS> +<functions> + <function returnType="bool">hasChanged()</function> +</functions> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/tdeioslave/media/propsdlgplugin/propertiespagegui.ui.h b/tdeioslave/media/propsdlgplugin/propertiespagegui.ui.h new file mode 100644 index 000000000..45a9ca2d7 --- /dev/null +++ b/tdeioslave/media/propsdlgplugin/propertiespagegui.ui.h @@ -0,0 +1,22 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions or slots use +** Qt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ + + +void PropertiesPageGUI::changedSlot() +{ + m_hasChanged = true; + emit changed(); +} + +bool PropertiesPageGUI::hasChanged() +{ + return m_hasChanged; +} + + diff --git a/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.cpp b/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.cpp new file mode 100644 index 000000000..1ceff0bc1 --- /dev/null +++ b/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.cpp @@ -0,0 +1,101 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <tqstring.h> +#include <tqvbox.h> +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqtimer.h> + +#include <kgenericfactory.h> +#include <kdebug.h> +#include <kpushbutton.h> +#include <tdefileshare.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <kdialog.h> +#include <kglobal.h> +#include <dcopref.h> + +#include "propertiespage.h" +#include "propsdlgshareplugin.h" +#include "../libmediacommon/medium.h" + +typedef KGenericFactory<PropsDlgSharePlugin, KPropertiesDialog> PropsDlgSharePluginFactory; + +K_EXPORT_COMPONENT_FACTORY( media_propsdlgplugin, + PropsDlgSharePluginFactory("media_propsdlgplugin") ) + +class PropsDlgSharePlugin::Private +{ + public: + PropertiesPage* page; +}; + +PropsDlgSharePlugin::PropsDlgSharePlugin( KPropertiesDialog *dlg, + const char *, const TQStringList & ) + : KPropsDlgPlugin(dlg), d(0) +{ + if (properties->items().count() != 1) + return; + + KFileItem *item = properties->items().first(); + + DCOPRef mediamanager("kded", "mediamanager"); + kdDebug() << "properties " << item->url() << endl; + DCOPReply reply = mediamanager.call( "properties", item->url().url() ); + + if ( !reply.isValid() ) + return; + + TQVBox* vbox = properties->addVBoxPage(i18n("&Mounting")); + + d = new Private(); + + d->page = new PropertiesPage(vbox, Medium::create(reply).id()); + connect(d->page, TQT_SIGNAL(changed()), + TQT_SLOT(slotChanged())); + + // TQTimer::singleShot(100, this, TQT_SLOT(slotChanged())); + +} + +void PropsDlgSharePlugin::slotChanged() +{ + kdDebug() << "slotChanged()\n"; + setDirty(true); +} + +PropsDlgSharePlugin::~PropsDlgSharePlugin() +{ + delete d; +} + +void PropsDlgSharePlugin::applyChanges() +{ + kdDebug() << "applychanges\n"; + if (!d->page->save()) { + properties->abortApplying(); + } +} + + +#include "propsdlgshareplugin.moc" + diff --git a/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.h b/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.h new file mode 100644 index 000000000..87b7d1e13 --- /dev/null +++ b/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.h @@ -0,0 +1,44 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KONQFILESHAREPLUGIN_H +#define KONQFILESHAREPLUGIN_H + +#include <kpropertiesdialog.h> + +class PropsDlgSharePlugin : public KPropsDlgPlugin +{ +Q_OBJECT +public: + PropsDlgSharePlugin( KPropertiesDialog *dlg, const char *, const TQStringList & ); + virtual ~PropsDlgSharePlugin(); + virtual void applyChanges(); + +public slots: + void slotChanged(); + +private: + class Private; + Private *d; + +}; + +#endif + + diff --git a/tdeioslave/media/services/CMakeLists.txt b/tdeioslave/media/services/CMakeLists.txt new file mode 100644 index 000000000..055bfdf48 --- /dev/null +++ b/tdeioslave/media/services/CMakeLists.txt @@ -0,0 +1,17 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +##### other data ################################ + +install( FILES + media_decrypt.desktop media_mount.desktop media_unmount.desktop + media_eject.desktop media_safelyremove.desktop + DESTINATION ${DATA_INSTALL_DIR}/konqueror/servicemenus ) diff --git a/tdeioslave/media/services/Makefile.am b/tdeioslave/media/services/Makefile.am new file mode 100644 index 000000000..c744934f2 --- /dev/null +++ b/tdeioslave/media/services/Makefile.am @@ -0,0 +1,3 @@ +servicesdir = $(kde_datadir)/konqueror/servicemenus +services_DATA = media_decrypt.desktop media_mount.desktop media_unmount.desktop media_eject.desktop media_safelyremove.desktop + diff --git a/tdeioslave/media/services/media_decrypt.desktop b/tdeioslave/media/services/media_decrypt.desktop new file mode 100644 index 000000000..dd8dadc39 --- /dev/null +++ b/tdeioslave/media/services/media_decrypt.desktop @@ -0,0 +1,9 @@ +[Desktop Action Decrypt] +Exec=kio_media_mounthelper -d %u +Icon=decrypted +Name=Decrypt +Name[de]=Entschlüsseln + +[Desktop Entry] +Actions=Decrypt +ServiceTypes=media/removable_unmounted_encrypted,media/hdd_unmounted_encrypted,media/cdrom_unmounted_encrypted,media/cdwriter_unmounted_encrypted,media/dvd_unmounted_encrypted diff --git a/tdeioslave/media/services/media_eject.desktop b/tdeioslave/media/services/media_eject.desktop new file mode 100644 index 000000000..af30d1088 --- /dev/null +++ b/tdeioslave/media/services/media_eject.desktop @@ -0,0 +1,90 @@ +[Desktop Entry] +ServiceTypes=media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_mounted_decrypted,media/cdrom_unmounted_decrypted,media/cdrom_unmounted_encrypted,media/cdwriter_mounted,media/cdwriter_unmounted,media/cdwriter_mounted_decrypted,media/cdwriter_unmounted_decrypted,media/cdwriter_unmounted_encrypted,media/dvd_mounted,media/dvd_unmounted,media/dvd_mounted_decrypted,media/dvd_unmounted_decrypted,media/dvd_unmounted_encrypted,media/audiocd,media/blankcd,media/blankdvd,media/dvdvideo,media/svcd,media/vcd +Actions=MediaEject; +X-TDE-Priority=TopLevel +X-TDE-MediaNotifierHide=true + +[Desktop Action MediaEject] +Name=Eject +Name[af]=Uitskiet +Name[ar]=أقذف +Name[az]=Çıxart +Name[be]=Вызваліць +Name[bg]=Изваждане +Name[bn]=ইজেক্ট +Name[br]=Stlepel +Name[bs]=Izbaci +Name[ca]=Expulsa +Name[cs]=Vysunout +Name[csb]=Wësënie +Name[cy]=Allfwrw +Name[da]=Skub ud +Name[de]=Auswerfen +Name[el]=Εξαγωγή +Name[eo]=Eligo +Name[es]=Expulsar +Name[et]=Väljastamine +Name[eu]=Egotzi +Name[fa]=پس زدن +Name[fi]=Poista +Name[fr]=Éjecter +Name[fy]=Utsmytknop +Name[ga]=Díchuir +Name[gl]=Expulsar +Name[he]=הוצא +Name[hi]=बाहर +Name[hr]=Izbaci +Name[hu]=Kidobás +Name[is]=Henda út +Name[it]=Espelli +Name[ja]=取り出し +Name[ka]=CD-ს ამოღება +Name[kk]=Алып-шығару +Name[km]=ច្រានចេញ +Name[ko]=꺼내기 +Name[lo]=ເອົາແຜ່ນອອກ +Name[lt]=Išmesti +Name[lv]=Izņemt +Name[mk]=Извади +Name[mn]=Гаргах +Name[ms]=Lenting +Name[mt]=Iftaħ +Name[nb]=Løs ut +Name[nds]=Rutsmieten +Name[ne]=निकाल्नुहोस् +Name[nl]=Uitwerpen +Name[nn]=Løys ut +Name[nso]=Ntsha +Name[oc]=Expulsa +Name[pa]=ਬਾਹਰ ਕੱਢੋ +Name[pl]=Wysuń +Name[pt]=Ejectar +Name[pt_BR]=Ejetar +Name[ro]=Ejectează +Name[ru]=Извлечь CD +Name[rw]=Gusohora +Name[se]=Bálkes olggos +Name[sk]=Vysunúť +Name[sl]=Izvrzi +Name[sr]=Избаци +Name[sr@Latn]=Izbaci +Name[ss]=Khafuna +Name[sv]=Mata ut +Name[ta]=வெளித்தள் +Name[te]=ఎజెక్ట్ +Name[tg]=Ихроҷ +Name[th]=เอาแผ่นออก +Name[tr]=Çıkart +Name[tt]=Çığar +Name[uk]=Виштовхнути +Name[uz]=Chiqarish +Name[uz@cyrillic]=Чиқариш +Name[ven]=Bvisa +Name[vi]=Đẩy đĩa ra +Name[wa]=Fé rexhe +Name[xh]=Khuphela ngaphandle +Name[zh_CN]=弹出 +Name[zh_TW]=退出 +Name[zu]=Khipha +Exec=kio_media_mounthelper -e %u + diff --git a/tdeioslave/media/services/media_mount.desktop b/tdeioslave/media/services/media_mount.desktop new file mode 100644 index 000000000..8011fe577 --- /dev/null +++ b/tdeioslave/media/services/media_mount.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +ServiceTypes=media/cdrom_unmounted,media/cdrom_unmounted_decrypted,media/cdwriter_unmounted,media/cdwriter_unmounted_decrypted,media/dvd_unmounted,media/dvd_unmounted_decrypted,media/floppy5_unmounted,media/floppy_unmounted,media/hdd_unmounted,media/hdd_unmounted_decrypted,media/nfs_unmounted,media/removable_unmounted,media/removable_unmounted_decrypted,media/smb_unmounted,media/zip_unmounted,media/camera_unmounted +Actions=MediaMount; +X-TDE-Priority=TopLevel +X-TDE-MediaNotifierHide=true + +[Desktop Action MediaMount] +Name=Mount +Name[af]=Koppel +Name[ar]=ركِب +Name[az]=Bağla +Name[be]=Прымацаваць +Name[bg]=Монтиране +Name[bn]=মাউন্ট +Name[br]=Marc'hañ +Name[bs]=Montiraj +Name[ca]=Munta +Name[cs]=Připojit +Name[csb]=Mòntujë +Name[cy]=Gosod +Name[da]=Montér +Name[de]=Laufwerk einbinden +Name[el]=Προσάρτηση +Name[eo]=Surmeti +Name[es]=Montar +Name[et]=Ühenda +Name[eu]=Muntatu +Name[fa]=سوار کردن +Name[fi]=Liitä +Name[fr]=Monter +Name[fy]=Oankeppelje (mount) +Name[ga]=Feistigh +Name[gl]=Montar +Name[he]=חבר +Name[hi]=माउन्ट +Name[hr]=Pristupi +Name[hsb]=montować +Name[hu]=Csatlakoztatás +Name[is]=Tengja +Name[it]=Monta +Name[ja]=マウント +Name[ka]=მონტირება +Name[kk]=Тіркеу +Name[km]=រៀបចំ +Name[lo]=ຈໍພາບ +Name[lt]=Montuoti +Name[lv]=Piemontēt +Name[mk]=Монтирај +Name[mn]=Залгах +Name[ms]=Lekap +Name[mt]=Immonta +Name[nb]=Monter +Name[nds]=Inhangen +Name[ne]=माउन्ट +Name[nl]=Aankoppelen (mount) +Name[nn]=Monter +Name[nso]=Nameletsa +Name[pa]=ਮਾਊਟ +Name[pl]=Zamontuj +Name[pt]=Montar +Name[pt_BR]=Montar +Name[ro]=Montează +Name[ru]=Подключить +Name[rw]=Gushyiramo +Name[se]=Čana +Name[sk]=Pripojiť +Name[sl]=Priklopi +Name[sr]=Монтирај +Name[sr@Latn]=Montiraj +Name[sv]=Montera +Name[ta]=ஏற்று +Name[tg]=Васл кунӣ +Name[th]=เม้านท์ +Name[tr]=Bağla +Name[tt]=Bäyläp quy +Name[uk]=Змонтувати +Name[uz]=Ulash +Name[uz@cyrillic]=Улаш +Name[ven]=Gonya +Name[vi]=Kết nối +Name[wa]=Monter +Name[xh]=Layisha +Name[zh_CN]=挂载 +Name[zh_TW]=掛載 +Name[zu]=Yenyusa +Exec=kio_media_mounthelper -m %u + diff --git a/tdeioslave/media/services/media_safelyremove.desktop b/tdeioslave/media/services/media_safelyremove.desktop new file mode 100644 index 000000000..3dac85f15 --- /dev/null +++ b/tdeioslave/media/services/media_safelyremove.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +ServiceTypes=media/removable_mounted,media/removable_mounted_decrypted,media/removable_unmounted,media/removable_unmounted_decrypted,media/camera_mounted,media/camera_unmounted +Actions=MediaSafelyRemove; +X-TDE-Priority=TopLevel +X-TDE-MediaNotifierHide=true + +[Desktop Action MediaSafelyRemove] +Name=Safely Remove +Name[af]=Verwyder veilig +Name[ar]=أحذف بأمان +Name[be]=Бяспечна адлучыць +Name[bg]=Безопасно изваждане +Name[bn]=নিরাপদভাবে সরাও +Name[bs]=Sigurno ukloni +Name[ca]=Extreu amb seguretat +Name[cs]=Bezpečně odstranit +Name[csb]=Remôj na bezpieczny ôrt +Name[da]=Fjern sikkert +Name[de]=Sicher entfernen +Name[el]=Ασφαλής αφαίρεση +Name[eo]=Sekura Forigo +Name[es]=Extracción segura +Name[et]=Eemalda turvaliselt +Name[eu]=Atera arriskurik gabe +Name[fa]=حذف امن +Name[fi]=Poista turvallisesti +Name[fr]=Enlever en toute sécurité +Name[fy]=Feilich ferwiderje +Name[ga]=Bain Amach go Sábháilte +Name[gl]=Eliminar de Maneira Segura +Name[he]=שליפה בבטחה +Name[hr]=Slobodno uklonite +Name[hu]=Biztonságos leválasztás +Name[is]=Fjarlægja öruggt +Name[it]=Rimozione sicura +Name[ja]=安全に取り除く +Name[ka]=უსაფრთხოდ გამორთვა +Name[kk]=Қауіпсіз алып шығу +Name[km]=យកចេញដោយសុវត្ថិភាព +Name[lt]=Saugiai pašalinti +Name[mk]=Безбедно отстрани +Name[ms]=Buang Dengan Selamat +Name[nb]=Sikker fjerning +Name[nds]=Seker rutnehmen +Name[ne]=सुरक्षीत रुपमा हटाउनुहोस् +Name[nl]=Veilig verwijderen +Name[nn]=Trygg fjerning +Name[pa]=ਸੁਰੱਖਿਅਤ ਹਟਾਓ +Name[pl]=Usuń w sposób bezpieczny +Name[pt]=Retirar com Segurança +Name[pt_BR]=Remover de Modo Seguro +Name[ro]=Scoate în siguranță +Name[ru]=Безопасно извлечь +Name[rw]=Gukuramo Neza +Name[se]=Dorvvošlaš eretváldin +Name[sk]=Bezpečne odpojiť +Name[sl]=Varno odstrani +Name[sr]=Безбедно уклони +Name[sr@Latn]=Bezbedno ukloni +Name[sv]=Säker urkoppling +Name[ta]=பாதுகாப்பாக நீக்கு +Name[te]=జాగరత్తగా తియి +Name[tg]=Баровардани бехетар +Name[th]=ถอดออกอย่างปลอดภัย +Name[tr]=Güvenli Kaldır +Name[tt]=İmin Çığaru +Name[uk]=Безпечно вилучити +Name[uz]=Ehtiyotlik bilan uzish +Name[uz@cyrillic]=Эҳтиётлик билан узиш +Name[vi]=Gỡ ra An toàn +Name[wa]=Ositer e såvrité +Name[zh_CN]=安全删除 +Name[zh_TW]=安全的移除 +Exec=kio_media_mounthelper -s %u + diff --git a/tdeioslave/media/services/media_unmount.desktop b/tdeioslave/media/services/media_unmount.desktop new file mode 100644 index 000000000..04ced9d0d --- /dev/null +++ b/tdeioslave/media/services/media_unmount.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +ServiceTypes=media/cdrom_mounted,media/cdrom_mounted_decrypted,media/cdwriter_mounted,media/cdwriter_mounted_decrypted,media/dvd_mounted,media/dvd_mounted_decrypted,media/floppy5_mounted,media/floppy_mounted,media/hdd_mounted,media/hdd_mounted_decrypted,media/nfs_mounted,media/smb_mounted,media/zip_mounted,media/vcd,media/svcd,media/dvdvideo +Actions=MediaUnmount; +X-TDE-Priority=TopLevel +X-TDE-MediaNotifierHide=true + +[Desktop Action MediaUnmount] +Name=Unmount +Name[af]=Ontkoppel +Name[ar]=أزل التركيب +Name[az]=Ayır +Name[be]=Адмацаваць +Name[bg]=Демонтиране +Name[bn]=আনমাউন্ট +Name[br]=Divarc'hañ +Name[bs]=Demontiraj +Name[ca]= Desmunta +Name[cs]=Odpojit +Name[csb]=Òdmòntujë +Name[cy]=Dadosod +Name[da]=Afmontér +Name[de]=Laufwerkeinbindung lösen +Name[el]=Αποπροσάρτηση +Name[eo]=Demeti +Name[es]=Desmontar +Name[et]=Lahuta +Name[eu]=Desmuntatu +Name[fa]=پیاده کردن +Name[fi]=Irrota +Name[fr]=Libérer +Name[fy]=Ofkeppelje (unmount) +Name[ga]=Dífheistigh +Name[gl]=Desmontar +Name[he]=נתק +Name[hi]=अनमाउन्ट +Name[hr]=Napusti +Name[hsb]=Wotmontować +Name[hu]=Leválasztás +Name[is]=Aftengja +Name[it]=Smonta +Name[ja]=マウント解除 +Name[ka]=დემონტირება +Name[kk]=Тіркеуден шығару +Name[km]=មិនរៀបចំ +Name[lo]=ຫັງກາລີ +Name[lt]=Išmontuoti +Name[lv]=Nomontēt +Name[mk]=Одмонтирај +Name[mn]=Салгах +Name[ms]=Nyahlekap +Name[mt]=Żmonta +Name[nb]=Avmonter +Name[nds]=Afhangen +Name[ne]=अनमाउन्ट +Name[nl]=Afkoppelen (unmount) +Name[nn]=Avmonter +Name[nso]=Theosa +Name[pa]=ਅਨਮਾਉਟ +Name[pl]=Odmontuj +Name[pt]=Desmontar +Name[pt_BR]=Desmontar +Name[ro]=Demontează +Name[ru]=Отключить +Name[rw]=Gukuramo +Name[se]=Gálgga +Name[sk]=Odpojiť +Name[sl]=Odklopi +Name[sr]=Демонтирај +Name[sr@Latn]=Demontiraj +Name[sv]=Avmontera +Name[ta]=வெளியேற்று +Name[tg]=Ҷудо кунӣ +Name[th]=เลิกเม้านท์ +Name[tr]=Ayır +Name[tt]=Bäyläwne çiş +Name[uk]=Демонтувати +Name[uz]=Uzish +Name[uz@cyrillic]=Узиш +Name[ven]=Usa gonya +Name[vi]=Gỡ ra +Name[wa]=Dismonter +Name[xh]=Sukuyilayisha +Name[zh_CN]=卸载 +Name[zh_TW]=卸載 +Name[zu]=Yehlisa +Exec=kio_media_mounthelper -u %u + diff --git a/tdeioslave/media/tdecmodule/CMakeLists.txt b/tdeioslave/media/tdecmodule/CMakeLists.txt new file mode 100644 index 000000000..80128471e --- /dev/null +++ b/tdeioslave/media/tdecmodule/CMakeLists.txt @@ -0,0 +1,45 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdeioslave/media/libmediacommon + ${CMAKE_SOURCE_DIR}/tdeioslave/media/libmediacommon + ${CMAKE_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES media.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) + + +##### kcm_media (module) ######################## + +set( target kcm_media ) + +set( ${target}_SRCS + notifiermodule.cpp notifiermoduleview.ui serviceconfigdialog.cpp + serviceview.ui mimetypelistboxitem.cpp managermodule.cpp + managermoduleview.ui main.cpp +) + +tde_add_kpart( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK mediacommon-static tdeio-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/tdeioslave/media/tdecmodule/Makefile.am b/tdeioslave/media/tdecmodule/Makefile.am new file mode 100644 index 000000000..72f9f385c --- /dev/null +++ b/tdeioslave/media/tdecmodule/Makefile.am @@ -0,0 +1,21 @@ +INCLUDES = -I$(srcdir)/../libmediacommon -I../libmediacommon $(all_includes) +METASOURCES = AUTO + +kde_module_LTLIBRARIES = kcm_media.la +kcm_media_la_SOURCES = notifiermodule.cpp notifiermoduleview.ui \ + serviceconfigdialog.cpp serviceview.ui \ + mimetypelistboxitem.cpp \ + managermodule.cpp managermoduleview.ui \ + main.cpp + +kcm_media_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +kcm_media_la_LIBADD = ../libmediacommon/libmediacommon.la $(LIB_KIO) + +noinst_HEADERS = notifiermodule.h managermodule.h \ + serviceconfigdialog.h mimetypelistboxitem.h \ + main.h + +xdg_apps_DATA = media.desktop + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kcmmedia.pot diff --git a/tdeioslave/media/tdecmodule/main.cpp b/tdeioslave/media/tdecmodule/main.cpp new file mode 100644 index 000000000..9036583df --- /dev/null +++ b/tdeioslave/media/tdecmodule/main.cpp @@ -0,0 +1,104 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "main.h" + +#include <tqtabwidget.h> +#include <tqlayout.h> + +#include <klocale.h> +#include <kaboutdata.h> +#include <kdialog.h> + +#include <kgenericfactory.h> + +#include "notifiermodule.h" +#include "managermodule.h" + + +typedef KGenericFactory<MediaModule, TQWidget> MediaFactory; +K_EXPORT_COMPONENT_FACTORY( kcm_media, MediaFactory( "kcmmedia" ) ) + + +MediaModule::MediaModule( TQWidget *parent, const char *name, const TQStringList& ) + : TDECModule(MediaFactory::instance(), parent, name ) +{ + TDEGlobal::locale()->insertCatalogue("kio_media"); + TQVBoxLayout *layout = new TQVBoxLayout( this, 0, KDialog::spacingHint() ); + TQTabWidget *tab = new TQTabWidget( this ); + + layout->addWidget( tab ); + + + + m_notifierModule = new NotifierModule( this, "notifier" ); + tab->addTab( m_notifierModule, i18n( "&Notifications" ) ); + connect( m_notifierModule, TQT_SIGNAL( changed( bool ) ), + this, TQT_SLOT( moduleChanged( bool ) ) ); + + m_managerModule = new ManagerModule( this, "manager" ); + tab->addTab( m_managerModule, i18n( "&Advanced" ) ); + connect( m_managerModule, TQT_SIGNAL( changed( bool ) ), + this, TQT_SLOT( moduleChanged( bool ) ) ); + + + + TDEAboutData * about = new TDEAboutData("kcmmedia", + I18N_NOOP("Storage Media"), + "0.6", + I18N_NOOP("Storage Media Control Panel Module"), + TDEAboutData::License_GPL_V2, + I18N_NOOP("(c) 2005 Jean-Remy Falleri")); + about->addAuthor("Jean-Remy Falleri", I18N_NOOP("Maintainer"), "jr.falleri@laposte.net"); + about->addAuthor("Kevin Ottens", 0, "ervin ipsquad net"); + about->addAuthor("Valentine Sinitsyn", 0, "e_val@inbox.ru"); + about->addCredit("Achim Bohnet", I18N_NOOP("Help for the application design")); + + setAboutData( about ); +} + +void MediaModule::load() +{ + m_notifierModule->load(); + m_managerModule->load(); +} + +void MediaModule::save() +{ + m_notifierModule->save(); + m_managerModule->save(); +} + +void MediaModule::defaults() +{ + m_notifierModule->defaults(); + m_managerModule->defaults(); +} + +void MediaModule::moduleChanged( bool state ) +{ + emit changed( state ); +} + +TQString MediaModule::quickHelp() const +{ + return i18n("FIXME : Write me..."); +} + +#include "main.moc" diff --git a/tdeioslave/media/tdecmodule/main.h b/tdeioslave/media/tdecmodule/main.h new file mode 100644 index 000000000..5052d58eb --- /dev/null +++ b/tdeioslave/media/tdecmodule/main.h @@ -0,0 +1,45 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#include <tdecmodule.h> + +class MediaModule : public TDECModule +{ + Q_OBJECT + +public: + MediaModule( TQWidget *parent, const char *name, const TQStringList& ); + + virtual void load(); + virtual void save(); + virtual void defaults(); + virtual TQString quickHelp() const; + +protected slots: + void moduleChanged( bool state ); + +private: + TDECModule *m_notifierModule; + TDECModule *m_managerModule; +}; + +#endif diff --git a/tdeioslave/media/tdecmodule/managermodule.cpp b/tdeioslave/media/tdecmodule/managermodule.cpp new file mode 100644 index 000000000..3a44c446e --- /dev/null +++ b/tdeioslave/media/tdecmodule/managermodule.cpp @@ -0,0 +1,213 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + Copyright (c) 2006 Valentine Sinitsyn <e_val@inbox.ru> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <config.h> + +#include "managermodule.h" + +#include <tdeconfig.h> +#include <klocale.h> +#include <dcopref.h> +#include <tqbutton.h> +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqobjectlist.h> +#include <kdirnotify_stub.h> + +#include "managermoduleview.h" +#include "mediamanagersettings.h" + +ManagerModule::ManagerModule( TQWidget* parent, const char* name ) + : TDECModule( parent, name ) +{ + view = new ManagerModuleView( this ); + + addConfig( MediaManagerSettings::self(), view ); + +#ifndef COMPILE_HALBACKEND + TQString hal_text = view->kcfg_HalBackendEnabled->text(); + hal_text += " ("+i18n("No support for HAL on this system")+")"; + view->kcfg_HalBackendEnabled->setText( hal_text ); +#endif + view->kcfg_HalBackendEnabled->setEnabled( false ); + +#ifndef COMPILE_LINUXCDPOLLING + TQString poll_text = view->kcfg_CdPollingEnabled->text(); + poll_text += " ("+i18n("No support for CD polling on this system")+")"; + view->kcfg_CdPollingEnabled->setText( poll_text ); +#endif + view->kcfg_CdPollingEnabled->setEnabled( false ); + + connect( view->option_automount, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_ro, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_quiet, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_flush, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_uid, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_utf8, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_sync, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_atime, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_shortname, SIGNAL( activated(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_journaling, SIGNAL( activated(int) ), this, SLOT( emitChanged() ) ); + + load(); +} + + +void ManagerModule::load() +{ + TDECModule::load(); + + TDEConfig config("mediamanagerrc"); + config.setGroup("DefaultOptions"); + + view->option_automount->setChecked( config.readBoolEntry("automount", false) ); + view->option_ro->setChecked( config.readBoolEntry("ro", false) ); + view->option_quiet->setChecked( config.readBoolEntry("quiet", false) ); + if (config.hasKey("flush")) + view->option_flush->setChecked( config.readBoolEntry("flush") ); + else + view->option_flush->setNoChange(); + view->option_uid->setChecked( config.readBoolEntry("uid", true) ); + view->option_utf8->setChecked( config.readBoolEntry("utf8", true) ); + if (config.hasKey("sync")) + view->option_sync->setChecked( config.readBoolEntry("sync") ); + else + view->option_sync->setNoChange(); + if (config.hasKey("atime")) + view->option_atime->setChecked( config.readBoolEntry("atime") ); + else + view->option_atime->setNoChange(); + + QString value; + + value = config.readEntry("shortname", "lower").lower(); + for (int i = 0; i < view->option_shortname->count(); i++) + if (view->option_shortname->text(i).lower() == value) view->option_shortname->setCurrentItem(i); + + value = config.readEntry("journaling", "ordered").lower(); + for (int i = 0; i < view->option_journaling->count(); i++) + if (view->option_journaling->text(i).lower() == value) view->option_journaling->setCurrentItem(i); + + rememberSettings(); +} + +void ManagerModule::save() +{ + TDECModule::save(); + + TDEConfig config("mediamanagerrc"); + config.setGroup("DefaultOptions"); + + config.writeEntry("automount", view->option_automount->isChecked()); + config.writeEntry("ro", view->option_ro->isChecked()); + config.writeEntry("quiet", view->option_quiet->isChecked()); + if (view->option_flush->state() == TQButton::NoChange) + config.deleteEntry("flush"); + else + config.writeEntry("flush", view->option_flush->isChecked()); + config.writeEntry("uid", view->option_uid->isChecked()); + config.writeEntry("utf8", view->option_utf8->isChecked()); + if (view->option_sync->state() == TQButton::NoChange) + config.deleteEntry("sync"); + else + config.writeEntry("sync", view->option_sync->isChecked()); + if (view->option_atime->state() == TQButton::NoChange) + config.deleteEntry("atime"); + else + config.writeEntry("atime", view->option_atime->isChecked()); + config.writeEntry("journaling", view->option_journaling->currentText().lower()); + config.writeEntry("shortname", view->option_shortname->currentText().lower()); + + rememberSettings(); + + //Well... reloadBackends is buggy with HAL, it seems to be linked + //to a bug in the unmaintained Qt3 DBUS binding ;-/ + //DCOPRef mediamanager( "kded", "mediamanager" ); + //DCOPReply reply = mediamanager.call( "reloadBackends" ); + + // So we use this hack instead... + DCOPRef kded( "kded", "kded" ); + kded.call( "unloadModule", "mediamanager" ); + kded.call( "loadModule", "mediamanager" ); + + KDirNotify_stub notifier( "*", "*" ); + notifier.FilesAdded( "media:/" ); +} + +void ManagerModule::defaults() +{ + TDECModule::defaults(); + + view->option_automount->setChecked(false); + view->option_ro->setChecked(false); + view->option_quiet->setChecked(false); + view->option_flush->setNoChange(); + view->option_uid->setChecked(true); + view->option_utf8->setChecked(true); + view->option_sync->setNoChange(); + view->option_atime->setNoChange(); + view->option_journaling->setCurrentItem(1); + view->option_shortname->setCurrentItem(0); +} + +void ManagerModule::rememberSettings() +{ + TQObjectList *options = view->queryList(0, "^option_"); + TQObject *current = 0; + TQObjectListIterator it(*options); + + settings.clear(); + while ( (current = it.current()) != 0 ) { + if (current->isA("TQCheckBox")) + settings[current] = ((TQCheckBox *)current)->state(); + else if (current->isA("TQComboBox")) + settings[current] = ((TQComboBox *)current)->currentItem(); + ++it; + } + delete options; + +} + +void ManagerModule::emitChanged() +{ + TQObjectList *options = view->queryList(0, "^option_"); + TQObject *current = 0; + TQObjectListIterator it(*options); + int value = -1; + bool somethingChanged = false; + + while ( (current = it.current()) != 0 ) { + if (current->isA("TQCheckBox")) + value = ((TQCheckBox *)current)->state(); + else if (current->isA("TQComboBox")) + value = ((TQComboBox *)current)->currentItem(); + + if (settings[current] != value) { + somethingChanged = true; + break; + } + + ++it; + } + delete options; + + emit changed(somethingChanged); +} + +#include "managermodule.moc" diff --git a/tdeioslave/media/tdecmodule/managermodule.h b/tdeioslave/media/tdecmodule/managermodule.h new file mode 100644 index 000000000..a0a384675 --- /dev/null +++ b/tdeioslave/media/tdecmodule/managermodule.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + Copyright (c) 2006 Valentine Sinitsyn <e_val@inbox.ru> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _MANAGERMODULE_H_ +#define _MANAGERMODULE_H_ + +#include <tqmap.h> +#include <tdecmodule.h> + +class ManagerModuleView; + +class ManagerModule : public TDECModule +{ + Q_OBJECT + +public: + ManagerModule( TQWidget* parent = 0, const char* name = 0); + + void load(); + void save(); + void defaults(); + +private: + void rememberSettings(); + + ManagerModuleView *view; + TQMap<TQObject *, int> settings; + +private slots: + void emitChanged(); +}; + +#endif diff --git a/tdeioslave/media/tdecmodule/managermoduleview.ui b/tdeioslave/media/tdecmodule/managermoduleview.ui new file mode 100644 index 000000000..afde70c75 --- /dev/null +++ b/tdeioslave/media/tdecmodule/managermoduleview.ui @@ -0,0 +1,343 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ManagerModuleView</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>ManagerModuleView</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>480</height> + </rect> + </property> + <property name="caption"> + <string>ManagerModuleView</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>kcfg_HalBackendEnabled</cstring> + </property> + <property name="text"> + <string>Enable HAL backend</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Select this if you want to enable the Hardware Abstraction Layer (http://hal.freedesktop.org/wiki/Software/hal) support.</string> + </property> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>kcfg_CdPollingEnabled</cstring> + </property> + <property name="text"> + <string>Enable CD polling</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Select this to enable the CD polling.</string> + </property> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>kcfg_AutostartEnabled</cstring> + </property> + <property name="text"> + <string>Enable medium application autostart after mount</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Select this if you want to enable application autostart after mounting a device.</string> + </property> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>groupbox_mount</cstring> + </property> + <property name="title"> + <string>Mount options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Here you can specify default mount options for your storage media. Please note that some options are not supported for certain filesystems and/or medium. You will be able to redefine all these options on per-volume basis later, using Properties dialog of the corresponding volume.<br> +Some of the options are tristate. Leave them "undefined" to let KDE choose the best value depending on your media.</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout30</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox" row="1" column="0"> + <property name="name"> + <cstring>option_ro</cstring> + </property> + <property name="text"> + <string>Read only</string> + </property> + <property name="whatsThis" stdset="0"> + <string>By default, mount all file systems read-only.</string> + </property> + </widget> + <widget class="TQCheckBox" row="2" column="1"> + <property name="name"> + <cstring>option_uid</cstring> + </property> + <property name="text"> + <string>Mount as user</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Mount this file system as user.</string> + </property> + </widget> + <widget class="TQCheckBox" row="0" column="1"> + <property name="name"> + <cstring>option_flush</cstring> + </property> + <property name="text"> + <string>Flushed IO</string> + </property> + <property name="tristate"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Always flush all data to the hot plug devices immediately and don't cache it.</string> + </property> + </widget> + <widget class="TQCheckBox" row="3" column="0"> + <property name="name"> + <cstring>option_sync</cstring> + </property> + <property name="text"> + <string>Synchronous</string> + </property> + <property name="tristate"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>All I/O to the file system should be done synchronously.</string> + </property> + </widget> + <widget class="TQCheckBox" row="2" column="0"> + <property name="name"> + <cstring>option_quiet</cstring> + </property> + <property name="text"> + <string>Quiet</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Attempts to chown or chmod files do not return errors, although they fail. Use with caution!</string> + </property> + </widget> + <widget class="TQCheckBox" row="1" column="1"> + <property name="name"> + <cstring>option_utf8</cstring> + </property> + <property name="text"> + <string>UTF-8 charset</string> + </property> + <property name="whatsThis" stdset="0"> + <string>UTF8 is the filesystem safe 8-bit encoding of Unicode that is used by the console. It can be be enabled for the filesystem with this option.</string> + </property> + </widget> + <widget class="TQLayoutWidget" row="3" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>layout29</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>text_shortname</cstring> + </property> + <property name="text"> + <string>Short names:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>option_shortname</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string><h2>Defines the behaviour for creation and display of filenames which fit into 8.3 characters. If a long name for a file exists, it will always be preferred display.</h2> + +<h3><b>Lower</b></h3> +Force the short name to lower case upon display; store a long name when the short name is not all upper case. + +<h3><b>Windows 95</b></h3> +Force the short name to upper case upon display; store a long name when the short name is not all upper case. + +<h3><b>Windows NT</b></h3> +Display the shortname as is; store a long name when the short name is not all lower case or all upper case. + +<h3><b>Mixed</b></h3> +Display the short name as is; store a long name when the short name is not all upper case.</string> + </property> + </widget> + <widget class="TQComboBox" row="0" column="1"> + <item> + <property name="text"> + <string>All Data</string> + </property> + </item> + <item> + <property name="text"> + <string>Ordered</string> + </property> + </item> + <item> + <property name="text"> + <string>Writeback</string> + </property> + </item> + <property name="name"> + <cstring>option_journaling</cstring> + </property> + <property name="currentItem"> + <number>1</number> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>text_journaling</cstring> + </property> + <property name="text"> + <string>Journaling:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>option_journaling</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string><h2>Specifies the journalling mode for file data. Metadata is always journaled. </h2> + +<h3><b>All Data</b></h3> + All data is committed into the journal prior to being written into the main file system. This is the slowest variant with the highest data security. + +<h3><b>Ordered</b></h3> + All data is forced directly out to the main file system prior to its metadata being committed to the journal. + +<h3><b>Write Back</b></h3> + Data ordering is not preserved - data may be written into the main file system after its metadata has been committed to the journal. This is rumoured to be the highest-throughput option. It guarantees internal file system integrity, however it can allow old data to appear in files after a crash and journal recovery.</string> + </property> + </widget> + <widget class="TQComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>Lower</string> + </property> + </item> + <item> + <property name="text"> + <string>Windows 95</string> + </property> + </item> + <item> + <property name="text"> + <string>Windows NT</string> + </property> + </item> + <item> + <property name="text"> + <string>Mixed</string> + </property> + </item> + <property name="name"> + <cstring>option_shortname</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="TQCheckBox" row="0" column="0"> + <property name="name"> + <cstring>option_automount</cstring> + </property> + <property name="text"> + <string>Mount automatically</string> + </property> + <property name="whatsThis" stdset="0"> + <string>By default, mount all file systems automatically.</string> + </property> + </widget> + <widget class="TQCheckBox" row="4" column="0"> + <property name="name"> + <cstring>option_atime</cstring> + </property> + <property name="text"> + <string>Access time updates</string> + </property> + <property name="tristate"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>Update inode access time for each access.</string> + </property> + </widget> + </grid> + </widget> + </vbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>130</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<connections> + <connection> + <sender>kcfg_HalBackendEnabled</sender> + <signal>toggled(bool)</signal> + <receiver>groupbox_mount</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>kcfg_HalBackendEnabled</tabstop> + <tabstop>kcfg_CdPollingEnabled</tabstop> + <tabstop>kcfg_AutostartEnabled</tabstop> + <tabstop>option_automount</tabstop> + <tabstop>option_ro</tabstop> + <tabstop>option_quiet</tabstop> + <tabstop>option_sync</tabstop> + <tabstop>option_atime</tabstop> + <tabstop>option_flush</tabstop> + <tabstop>option_utf8</tabstop> + <tabstop>option_uid</tabstop> + <tabstop>option_journaling</tabstop> + <tabstop>option_shortname</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in implementation">managermoduleview.ui.h</include> +</includes> +<functions> + <function access="private" specifier="non virtual">init()</function> +</functions> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/tdeioslave/media/tdecmodule/media.desktop b/tdeioslave/media/tdecmodule/media.desktop new file mode 100644 index 000000000..d93f876f4 --- /dev/null +++ b/tdeioslave/media/tdecmodule/media.desktop @@ -0,0 +1,197 @@ +[Desktop Entry] +Type=Application +#DocPath= +Icon=system +Exec=tdecmshell media + + +X-TDE-Library=media +X-TDE-FactoryName=media +X-TDE-ParentApp=kcontrol + +Name=Storage Media +Name[af]=Stoor Media +Name[ar]=وسائط التخزين +Name[be]=Носьбіты +Name[bg]=Съхраняващи устройства +Name[bn]=স্টোরেজ মিডিয়া +Name[bs]=Uređaji za smještaj podataka +Name[ca]=Suports d'emmagatzematge +Name[cs]=Úložná zařízení +Name[csb]=Zôpisowné media +Name[da]=Opbevaringsmedie +Name[de]=Speichermedien +Name[el]=Συσκευές αποθήκευσης +Name[eo]=Enmemoriga Medio +Name[es]=Dispositivos de almacenamiento +Name[et]=Andmekandjad +Name[eu]=Biltegiratze-euskarria +Name[fa]=رسانۀ ذخیرهگاه +Name[fi]=Tallennusmedia +Name[fr]=Support de stockage +Name[fy]=Opslachapparaten +Name[ga]=Meán Stórais +Name[gl]=Medios de armacenaxe +Name[he]=התקנים +Name[hi]=भंडार मीडिया +Name[hr]=Mediji za pohranjivanje +Name[hu]=Tárolóeszközök +Name[is]=Geymslumiðlar +Name[it]=Dispositivi di archiviazione +Name[ja]=記憶メディア +Name[ka]=მონაცემთა შენახვის მოწყობილობები +Name[kk]=Жинақтаушы құрылғылар +Name[km]=ឧបករណ៍ផ្ទុក +Name[lt]=Saugojimo įrenginiai +Name[lv]=Datu nesējs +Name[mk]=Медиуми за податоци +Name[ms]=Media Storan +Name[nb]=Lagringsenheter +Name[nds]=Spiekermedien +Name[ne]=भण्डारण मिडिया +Name[nl]=Opslagapparaten +Name[nn]=Lagringsmedium +Name[pa]=ਸਟੋਰੇਜ਼ ਮੀਡਿਆ +Name[pl]=Urządzenia przechowywania danych +Name[pt]=Dispositivos de Armazenamento +Name[pt_BR]=Mídia de Armazenamento +Name[ro]=Mediu de stocare +Name[ru]=Устройства хранения данных +Name[rw]=Uburyo bwo Kubika +Name[se]=Vurkenmedia +Name[sk]=Zálohovacie médiá +Name[sl]=Nosilci za shranjevanje +Name[sr]=Складишни медијуми +Name[sr@Latn]=Skladišni medijumi +Name[sv]=Lagringsmedia +Name[ta]=சேகரிப்பு ஊடகம் +Name[tg]=Захирагоҳи маълумот +Name[th]=สื่อเก็บข้อมูล +Name[tr]=Depolama Ortamı +Name[tt]=Saqlawlı Media +Name[uk]=Пристрої зберігання інформації +Name[uz]=Saqlash uskunalari +Name[uz@cyrillic]=Сақлаш ускуналари +Name[vi]=Ổ chứa Dữ liệu +Name[wa]=Sopoirts di wårdaedje +Name[zh_CN]=存储介质 +Name[zh_TW]=儲存媒體 + +Comment=Configure Storage Media +Comment[af]=Stel Stoor Media op +Comment[ar]=إعداد وسائط التخزين +Comment[be]=Настаўленні носьбітаў +Comment[bg]=Настройване на устройствата за съхранение на информация +Comment[bn]=স্টোরেজ মিডিয়া কনফিগার করুন +Comment[bs]=Podesite prikaz uređaja +Comment[ca]=Configura els suports d'emmagatzematge +Comment[cs]=Nastavení úložných médií +Comment[csb]=Kònfigùracëjô zôpisownëch mediów +Comment[da]=Opsætning af opbevarelsesmedie +Comment[de]=Speichermedien einrichten +Comment[el]=Ρύθμιση μέσων αποθήκευσης +Comment[eo]=Agordo de enmemoriga medio +Comment[es]=Configuración de las medios de almacenamiento +Comment[et]=Salvestusandmekandjate seadistused +Comment[eu]=Konfiguratu biltegiratze-euskarria +Comment[fa]=پیکربندی رسانۀ ذخیرهگاه +Comment[fi]=Aseta tallennusmedia +Comment[fr]=Configurer le média de stockage +Comment[fy]=Opslachmedia ynstelle +Comment[ga]=Cumraigh Meáin Stórála +Comment[gl]=Configurar Medios de Armacenaxe +Comment[he]=שינוי הגדרות מדיות אחסון +Comment[hr]=Konfiguriranje medija za pohranu +Comment[hu]=A tárolóeszközök beállítása +Comment[is]=Stillingar geymslumiðla +Comment[it]=Configura dispositivi di archiviazione +Comment[ja]=記憶メディアの設定 +Comment[ka]=შენახვის მედიის გამართვა +Comment[kk]=Жинақтаушыларды баптау +Comment[km]=កំណត់រចនាសម្ព័ន្ធឧបករណ៍ផ្ទុក +Comment[lt]=Konfigūruoti saugojimo įrenginius +Comment[mk]=Конфигурирајте ги медиумите за податоци +Comment[nb]=Sett opp lagringsmedier +Comment[nds]=Spiekermedien instellen +Comment[ne]=भण्डारण मिडिया कन्फिगर गर्नुहोस् +Comment[nl]=Opslagmedia instellen +Comment[nn]=Set opp lagringsmedium +Comment[pa]=ਸਟੋਰੇਜ਼ ਮੀਡਿਆ ਸੰਰਚਨਾ +Comment[pl]=Konfiguracja nośników danych +Comment[pt]=Configurar os Suportes de Armazenamento +Comment[pt_BR]=Configura as mídias de armazenamento +Comment[ro]=Configurează mediile de stocare +Comment[ru]=Настройка подключаемых устройств хранения +Comment[se]=Heivet vurkenmediaid +Comment[sk]=Nastavenie zálohovacích médií +Comment[sl]=Nastavitve nosilcev za shranjevanje +Comment[sr]=Подешавање медијума за складиштење +Comment[sr@Latn]=Podešavanje medijuma za skladištenje +Comment[sv]=Anpassa lagringsmedia +Comment[th]=ตั้งค่าสื่อบันทึก +Comment[tr]=Depolama Aygıtlarını Yapılandır +Comment[tt]=Saqlaw Cıhazların Caylaw +Comment[uk]=Налаштування пристроїв зберігання інформації +Comment[uz]=Saqlash uskunalarni moslash +Comment[uz@cyrillic]=Сақлаш ускуналарни мослаш +Comment[vi]=Cấu hình Ổ lưu trữ Dữ liệu +Comment[wa]=Apontiaedjes sopoirts di wårdaedje +Comment[zh_CN]=配置存储介质 +Comment[zh_TW]=設定儲存媒體 + +Keywords=storage,media,usb,cdrom,device +Keywords[ar]=تخزين,وسائط,usb,قرص مدمج cdrom,جهاز +Keywords[be]=Носьбіт,Прылада,storage,media,usb,cdrom,device +Keywords[bg]=съхранение, информация, компактдиск, устройство, данни, storage, media, usb, cdrom, device +Keywords[bs]=storage,media,usb,cdrom,device,uređaji,mediji +Keywords[ca]=emmagatzematge,suport,usb,cdrom,dispositiu +Keywords[cs]=úložiště,média,USB,CDROM,zařízení +Keywords[csb]=pòdôwczi,trzëmanié pòdôwków,zôpisowné media,usb,cdrom,ùrządzenié,nëk +Keywords[da]=opbevaring,medie,usb,cdrom,enhed +Keywords[de]=Speicher,Medien,Medium,USB,CD-Rom,cdrom,Gerät +Keywords[el]=αποθήκευση,μέσο,usb,cdrom,συσκευή +Keywords[eo]=memorigilo,medio,usb,lumdisko,aparato +Keywords[es]=almacenamiento,medios,usb,cdrom,dispositivo +Keywords[et]=salvestamine,andmekandja,usb,cd,seade +Keywords[eu]=biltegiratzea,euskarriak,usb,cdrom,gailua +Keywords[fa]=ذخیرهگاه، رسانه، گذرگاه سریال جهانی، دیسک فشرده، دستگاه +Keywords[fi]=varasto,media,usb,cdrom,laite +Keywords[fr]=stockage,media,média,medium,usb,cdrom,périphérique +Keywords[fy]=storage,opslach,media,usb,cd-rom,kompakt-skiif,device,apparaat,mp3-speler,usb-stick,geheugenkaart +Keywords[ga]=stóráil,stóras,meáin,meán,usb,cdrom,dlúthdhiosca,gléas +Keywords[gl]=armacenaxe,medios,usb,cdrom,dispositivo +Keywords[he]=storage,media,usb,cdrom,device,מדיה,התקן,סידירום,תקליטור +Keywords[hr]=storage,media,usb,cdrom,device,pohrana,snimanje,mediji,uređaj +Keywords[hu]=tároló,adathordozó,USB,CD-ROM,eszköz +Keywords[is]=geymsla,miðill,usb,cdrom,tæki +Keywords[it]=storage,media,usb,cdrom,dispositivi,dvd,penna usb,memory stick,stick +Keywords[ja]=記憶,メディア,usb,cdrom,デバイス +Keywords[km]=ឧបករណ៍ផ្ទុក, usb,ស៊ីឌីរ៉ូម,ឧបករណ៍ +Keywords[lt]=storage,media,usb,cdrom,device,saugojimas,media,įrenginiai,usb +Keywords[mk]=storage,media,usb,cdrom,device,медиуми,усб,цдром,уред +Keywords[nb]=lagring,media,usb,CD-spiller,CD-ROM,enheter,minnepinner,harddisker,HD,eksterne harddisker,zip-disker +Keywords[nds]=Spieker,Medien,USB,CDROM,Reedschap +Keywords[ne]=भण्डारण, मिडिया,usb,cdrom, यन्त्र +Keywords[nl]=storage,opslag,media,usb,cd-rom,device,apparaat,mp3-speler,usb-stick,geheugenkaart +Keywords[nn]=lagring,media,usb,CD-spiller,CD-ROM,einingar,minnepinnar,harddiskar,HD,eksterne harddiskar,zip-diskar +Keywords[pa]=ਸਟੋਰੇਜ਼,ਮੀਡਿਆ,ਜੰਤਰ,usb,cdrom +Keywords[pl]=dane,przechowywanie danych,nośnik danych,nośniki danych,usb,cdrom,urządzenie +Keywords[pt]=armazenamento,discos,usb,cdrom,dispositivo +Keywords[pt_BR]=armazenamento,mídia,usb,cd-rom,device,dispositivo +Keywords[ro]=stocare,mediu,usb,cdrom,dispozitiv +Keywords[ru]=storage,media,usb,cdrom,device,устройство хранения +Keywords[sl]=shranjevanje,nosilec,usb,cdrom,naprava +Keywords[sr]=storage,media,usb,cdrom,device,складиштење,медијум,уређај +Keywords[sr@Latn]=storage,media,usb,cdrom,device,skladištenje,medijum,uređaj +Keywords[sv]=lagring,media,usb,cdrom,enhet +Keywords[th]=ที่เก็บข้อมูล,สื่อ,ยูเอสบี,,ซีดีรอม,อุปกรณ์ +Keywords[tr]=depolama,ortam,usb,cdrom,device +Keywords[uk]=зберігання,носій,медіа,usb,cdrom,пристрій +Keywords[uz]=saqlash uskunasi,usb,cdrom,kompakt-disk +Keywords[uz@cyrillic]=сақлаш ускунаси,usb,cdrom,компакт-диск +Keywords[vi]=lưu trữ,ổ,usb,cdrom,thiết bị +Keywords[wa]=wårdaedje,media,usb,cdrom,device,éndjin +Keywords[zh_CN]=storage,media,usb,cdrom,device,存储,介质,设备 +Keywords[zh_TW]=storage,media,usb,cdrom,device,儲存,媒體,光碟機,裝置 + +Categories=Qt;TDE;X-TDE-settings-peripherals; diff --git a/tdeioslave/media/tdecmodule/mimetypelistboxitem.cpp b/tdeioslave/media/tdecmodule/mimetypelistboxitem.cpp new file mode 100644 index 000000000..e7334248a --- /dev/null +++ b/tdeioslave/media/tdecmodule/mimetypelistboxitem.cpp @@ -0,0 +1,35 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "mimetypelistboxitem.h" + +#include <kmimetype.h> + +MimetypeListBoxItem::MimetypeListBoxItem(const TQString &mimetype, TQListBox *parent) + : TQListBoxText(parent), m_mimetype(mimetype) +{ + KMimeType::Ptr mime = KMimeType::mimeType( mimetype ); + setText( mime->comment() ); +} + +const TQString &MimetypeListBoxItem::mimetype() const +{ + return m_mimetype; +} + diff --git a/tdeioslave/media/tdecmodule/mimetypelistboxitem.h b/tdeioslave/media/tdecmodule/mimetypelistboxitem.h new file mode 100644 index 000000000..e02f58b11 --- /dev/null +++ b/tdeioslave/media/tdecmodule/mimetypelistboxitem.h @@ -0,0 +1,37 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 K�vin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _MIMETYPELISTBOXITEM_H_ +#define _MIMETYPELISTBOXITEM_H_ + +#include <tqlistbox.h> +#include <tqstring.h> + +class MimetypeListBoxItem : public TQListBoxText +{ +public: + MimetypeListBoxItem(const TQString &mimetype, TQListBox *parent); + + const TQString &mimetype() const; + +private: + TQString m_mimetype; +}; + +#endif diff --git a/tdeioslave/media/tdecmodule/notifiermodule.cpp b/tdeioslave/media/tdecmodule/notifiermodule.cpp new file mode 100644 index 000000000..4146c514f --- /dev/null +++ b/tdeioslave/media/tdecmodule/notifiermodule.cpp @@ -0,0 +1,230 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "notifiermodule.h" + +#include <klocale.h> + +#include <tqlayout.h> +#include <kcombobox.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> + +#include "notifiersettings.h" +#include "serviceconfigdialog.h" +#include "actionlistboxitem.h" +#include "mimetypelistboxitem.h" + +NotifierModule::NotifierModule(TQWidget *parent, const char *name) + : TDECModule(parent, name) +{ + TQBoxLayout *layout = new TQVBoxLayout( this, 0, KDialog::spacingHint() ); + + m_view = new NotifierModuleView( this ); + layout->addWidget( m_view ); + + m_view->addButton->setGuiItem( KStdGuiItem::add() ); + m_view->editButton->setGuiItem( KStdGuiItem::properties() ); + m_view->deleteButton->setGuiItem( KStdGuiItem::del() ); + + m_view->mimetypesCombo->insertItem( i18n("All Mime Types") ); + + TQStringList mimetypes = m_settings.supportedMimetypes(); + + TQStringList::iterator it = mimetypes.begin(); + TQStringList::iterator end = mimetypes.end(); + + for ( ; it!=end; ++it ) + { + new MimetypeListBoxItem( *it, m_view->mimetypesCombo->listBox() ); + } + + updateListBox(); + + connect( m_view->mimetypesCombo, TQT_SIGNAL( activated(int) ), + this, TQT_SLOT( slotMimeTypeChanged(int) ) ); + connect( m_view->actionsList, TQT_SIGNAL( selectionChanged(TQListBoxItem*) ), + this, TQT_SLOT( slotActionSelected(TQListBoxItem*) ) ); + connect( m_view->addButton, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( slotAdd() ) ); + connect( m_view->editButton, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( slotEdit() ) ); + connect( m_view->deleteButton, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( slotDelete() ) ); + connect( m_view->toggleAutoButton, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( slotToggleAuto() ) ); +} + +NotifierModule::~NotifierModule() +{ +} + +void NotifierModule::load() +{ + m_settings.reload(); + slotMimeTypeChanged( m_view->mimetypesCombo->currentItem() ); +} + +void NotifierModule::save() +{ + m_settings.save(); +} + +void NotifierModule::defaults() +{ + m_settings.clearAutoActions(); + slotMimeTypeChanged( m_view->mimetypesCombo->currentItem() ); +} + +void NotifierModule::updateListBox() +{ + m_view->actionsList->clear(); + slotActionSelected( 0L ); + + TQValueList<NotifierAction*> services; + if ( m_mimetype.isEmpty() ) + { + services = m_settings.actions(); + } + else + { + services = m_settings.actionsForMimetype( m_mimetype ); + } + + TQValueList<NotifierAction*>::iterator it; + + for ( it = services.begin(); it != services.end(); ++it ) + { + new ActionListBoxItem( *it, m_mimetype, m_view->actionsList ); + } +} + +void NotifierModule::slotActionSelected(TQListBoxItem *item) +{ + NotifierAction *action = 0L; + + if ( item!=0L ) + { + ActionListBoxItem *action_item + = static_cast<ActionListBoxItem*>(item); + action = action_item->action(); + } + + bool isWritable = action!=0L && action->isWritable(); + m_view->deleteButton->setEnabled( isWritable ); + m_view->editButton->setEnabled( isWritable ); + m_view->addButton->setEnabled( TRUE ); + m_view->toggleAutoButton->setEnabled( action!=0L && !m_mimetype.isEmpty() ); +} + +void NotifierModule::slotMimeTypeChanged(int index) +{ + if ( index == 0 ) + { + m_mimetype = TQString(); + } + else + { + TQListBoxItem *item = m_view->mimetypesCombo->listBox()->item( index ); + MimetypeListBoxItem *mime_item + = static_cast<MimetypeListBoxItem*>( item ); + m_mimetype = mime_item->mimetype(); + } + + updateListBox(); +} + +void NotifierModule::slotAdd() +{ + NotifierServiceAction *action = new NotifierServiceAction(); + ServiceConfigDialog dialog(action, m_settings.supportedMimetypes(), this); + + int value = dialog.exec(); + + if ( value == TQDialog::Accepted ) + { + m_settings.addAction( action ); + updateListBox(); + emit changed( true ); + } + else + { + delete action; + } +} + +void NotifierModule::slotEdit() +{ + ActionListBoxItem *action_item + = static_cast<ActionListBoxItem*>(m_view->actionsList->selectedItem()); + + NotifierServiceAction * action = dynamic_cast<NotifierServiceAction*>( action_item->action() ); + if ( action ) + { + ServiceConfigDialog dialog(action, m_settings.supportedMimetypes(), this); + + int value = dialog.exec(); + + if ( value == TQDialog::Accepted ) + { + updateListBox(); + emit changed( true ); + } + } +} + +void NotifierModule::slotDelete() +{ + ActionListBoxItem *action_item + = static_cast<ActionListBoxItem*>(m_view->actionsList->selectedItem()); + + NotifierServiceAction *action; + action = dynamic_cast<NotifierServiceAction*>( action_item->action() ); + if ( action ) + { + m_settings.deleteAction( action ); + updateListBox(); + emit changed( true ); + } +} + +void NotifierModule::slotToggleAuto() +{ + ActionListBoxItem *action_item + = static_cast<ActionListBoxItem*>( m_view->actionsList->selectedItem() ); + NotifierAction *action = action_item->action(); + + int index = m_view->actionsList->index( action_item ); + + if ( action->autoMimetypes().contains( m_mimetype ) ) + { + m_settings.resetAutoAction( m_mimetype ); + } + else + { + m_settings.setAutoAction( m_mimetype, action ); + } + + updateListBox(); + emit changed( true ); + + m_view->actionsList->setSelected( index, true ); +} + +#include "notifiermodule.moc" diff --git a/tdeioslave/media/tdecmodule/notifiermodule.h b/tdeioslave/media/tdecmodule/notifiermodule.h new file mode 100644 index 000000000..d5d97a96d --- /dev/null +++ b/tdeioslave/media/tdecmodule/notifiermodule.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 K�vin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _NOTIFIERMODULE_H_ +#define _NOTIFIERMODULE_H_ + +#include <tdecmodule.h> +#include <tqlistbox.h> + +#include "notifiersettings.h" +#include "notifiermoduleview.h" + +class NotifierModule : public TDECModule +{ + Q_OBJECT + +public: + NotifierModule( TQWidget* parent = 0, const char* name = 0); + ~NotifierModule(); + + void load(); + void save(); + void defaults(); + +private slots: + void slotAdd(); + void slotDelete(); + void slotEdit(); + void slotToggleAuto(); + + void slotActionSelected( TQListBoxItem * item ); + void slotMimeTypeChanged( int index ); + +private: + void updateListBox(); + + TQString m_mimetype; + NotifierSettings m_settings; + NotifierModuleView *m_view; +}; + +#endif diff --git a/tdeioslave/media/tdecmodule/notifiermoduleview.ui b/tdeioslave/media/tdecmodule/notifiermoduleview.ui new file mode 100644 index 000000000..ad508c03d --- /dev/null +++ b/tdeioslave/media/tdecmodule/notifiermoduleview.ui @@ -0,0 +1,171 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>NotifierModuleView</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>NotifierModuleView</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>480</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>mediumType</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Medium types:</string> + </property> + </widget> + <widget class="KComboBox"> + <property name="name"> + <cstring>mimetypesCombo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="whatsThis" stdset="0"> + <string>Here is the list of the available types of medium which can be monitored. You can filter the available actions by selecting a type of medium. If you want to see all the actions, select "All Mime Types".</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>addButton</cstring> + </property> + <property name="text"> + <string>&Add...</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Click here to add an action.</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>deleteButton</cstring> + </property> + <property name="text"> + <string>&Delete</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Click here to delete the selected action if possible.</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>editButton</cstring> + </property> + <property name="text"> + <string>&Edit...</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Click here to edit the selected action if possible.</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>toggleAutoButton</cstring> + </property> + <property name="text"> + <string>&Toggle as Auto Action</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Click here to perform this action automatically on detection of the selected medium type (this option is disabled when "All Mime Types" is selected).</string> + </property> + </widget> + </vbox> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>buttonSpacer</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>70</width> + <height>101</height> + </size> + </property> + </spacer> + <widget class="KListBox" row="0" column="0" rowspan="2" colspan="1"> + <property name="name"> + <cstring>actionsList</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>Here is the list of the available actions. You can modify them by using the buttons on your right.</string> + </property> + </widget> + </grid> + </widget> + </vbox> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kcombobox.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klistbox.h</includehint> +</includehints> +</UI> diff --git a/tdeioslave/media/tdecmodule/serviceconfigdialog.cpp b/tdeioslave/media/tdecmodule/serviceconfigdialog.cpp new file mode 100644 index 000000000..61dd060f2 --- /dev/null +++ b/tdeioslave/media/tdecmodule/serviceconfigdialog.cpp @@ -0,0 +1,151 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kévin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "serviceconfigdialog.h" + +#include <klocale.h> +#include <klineedit.h> +#include <kactionselector.h> +#include <kicondialog.h> +#include <tqlistbox.h> +#include <kservice.h> +#include <kopenwith.h> +#include <kpushbutton.h> +#include <kiconloader.h> +#include <tqpixmap.h> +#include <tqiconset.h> + + +#include "mimetypelistboxitem.h" + +ServiceConfigDialog::ServiceConfigDialog(NotifierServiceAction *action, + const TQStringList &mimetypesList, + TQWidget* parent, const char* name) + : KDialogBase(parent, name, true, i18n("Edit Service"), Ok|Cancel, Ok, true), + m_action(action) +{ + m_view = new ServiceView(this); + + m_view->iconButton->setIcon( m_action->iconName() ); + m_view->labelEdit->setText( m_action->label() ); + m_view->commandEdit->setText( m_action->service().m_strExec ); + + TQIconSet iconSet = SmallIconSet("configure"); + TQPixmap pixMap = iconSet.pixmap( TQIconSet::Small, TQIconSet::Normal ); + m_view->commandButton->setIconSet( iconSet ); + m_view->commandButton->setFixedSize( pixMap.width()+8, pixMap.height()+8 ); + + m_iconChanged = false; + + TQStringList all_mimetypes = mimetypesList; + TQStringList action_mimetypes = action->mimetypes(); + + TQStringList::iterator it = all_mimetypes.begin(); + TQStringList::iterator end = all_mimetypes.end(); + + for ( ; it!=end; ++it ) + { + TQListBox *list; + + if ( action_mimetypes.contains( *it ) ) + { + list = m_view->mimetypesSelector->selectedListBox(); + } + else + { + list = m_view->mimetypesSelector->availableListBox(); + } + + new MimetypeListBoxItem( *it, list ); + } + + setMainWidget(m_view); + setCaption( m_action->label() ); + + connect( m_view->iconButton, TQT_SIGNAL( iconChanged(TQString) ), + this, TQT_SLOT( slotIconChanged() ) ); + connect( m_view->commandButton, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( slotCommand() ) ); +} + +bool operator==( KDEDesktopMimeType::Service s1, KDEDesktopMimeType::Service s2 ) +{ + return ( s1.m_strName==s2.m_strName ) + && ( s1.m_strIcon==s2.m_strIcon ) + && ( s1.m_strExec==s2.m_strExec ); +} + +bool operator!=( KDEDesktopMimeType::Service s1, KDEDesktopMimeType::Service s2 ) +{ + return !( s1==s2 ); +} + +void ServiceConfigDialog::slotOk() +{ + KDEDesktopMimeType::Service service; + service.m_strName = m_view->labelEdit->text(); + service.m_strIcon = m_view->iconButton->icon(); + service.m_strExec = m_view->commandEdit->text(); + + TQStringList mimetypes; + + uint list_count = m_view->mimetypesSelector->selectedListBox()->count(); + for( uint i=0; i < list_count; ++i ) + { + TQListBoxItem *item = m_view->mimetypesSelector->selectedListBox()->item(i); + MimetypeListBoxItem *mime_item = static_cast<MimetypeListBoxItem*>( item ); + mimetypes.append( mime_item->mimetype() ); + } + + if ( service!=m_action->service() || mimetypes!=m_action->mimetypes() ) + { + m_action->setService( service ); + m_action->setMimetypes( mimetypes ); + accept(); + } + else + { + reject(); + } +} + +void ServiceConfigDialog::slotIconChanged() +{ + m_iconChanged = true; +} + +void ServiceConfigDialog::slotCommand() +{ + KOpenWithDlg d(this); + int value = d.exec(); + if ( value == TQDialog::Accepted ) + { + KService::Ptr service = d.service(); + if ( service != 0L ) + { + m_view->commandEdit->setText( service->exec() ); + if ( m_iconChanged == false ) + { + m_view->iconButton->setIcon( service->icon() ); + } + } + } +} + +#include "serviceconfigdialog.moc" diff --git a/tdeioslave/media/tdecmodule/serviceconfigdialog.h b/tdeioslave/media/tdecmodule/serviceconfigdialog.h new file mode 100644 index 000000000..24e907205 --- /dev/null +++ b/tdeioslave/media/tdecmodule/serviceconfigdialog.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE Project + Copyright (c) 2005 Jean-Remy Falleri <jr.falleri@laposte.net> + Copyright (c) 2005 Kvin Ottens <ervin ipsquad net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _SERVICECONFIGDIALOG_H_ +#define _SERVICECONFIGDIALOG_H_ + +#include <kdialogbase.h> + +#include "notifierserviceaction.h" +#include "serviceview.h" + +class ServiceConfigDialog : public KDialogBase +{ + Q_OBJECT + +public: + ServiceConfigDialog(NotifierServiceAction *action, + const TQStringList &mimetypesList, + TQWidget* parent = 0, const char* name = 0); + +public slots: + void slotOk(); + void slotIconChanged(); + void slotCommand(); + +private: + ServiceView *m_view; + NotifierServiceAction *m_action; + bool m_iconChanged; +}; + +#endif diff --git a/tdeioslave/media/tdecmodule/serviceview.ui b/tdeioslave/media/tdecmodule/serviceview.ui new file mode 100644 index 000000000..a6c3063f6 --- /dev/null +++ b/tdeioslave/media/tdecmodule/serviceview.ui @@ -0,0 +1,248 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ServiceView</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>ServiceView</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>664</width> + <height>503</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>640</width> + <height>480</height> + </size> + </property> + <property name="caption"> + <string>Edit Service</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Edit Service</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KIconButton"> + <property name="name"> + <cstring>iconButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>40</width> + <height>40</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>40</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="iconSize"> + <number>32</number> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Minimum</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit"> + <property name="name"> + <cstring>labelEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Minimum</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>21</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + <widget class="Line"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="KActionSelector"> + <property name="name"> + <cstring>mimetypesSelector</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="availableLabel"> + <string>Available &medium types:</string> + </property> + <property name="selectedLabel"> + <string>Displa&y service for:</string> + </property> + <property name="showUpDownButtons"> + <bool>false</bool> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KActiveLabel"> + <property name="name"> + <cstring>m_lbCommmand</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Command:</string> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>commandEdit</cstring> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>commandButton</cstring> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </grid> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kicondialog.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kactionselector.h</includehint> + <includehint>kactivelabel.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/tdeioslave/media/tdefile-plugin/CMakeLists.txt b/tdeioslave/media/tdefile-plugin/CMakeLists.txt new file mode 100644 index 000000000..88c9220fa --- /dev/null +++ b/tdeioslave/media/tdefile-plugin/CMakeLists.txt @@ -0,0 +1,40 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +check_include_file( "sys/statvfs.h" HAVE_STATVFS ) + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/tdeioslave/media/libmediacommon + ${CMAKE_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES tdefile_media.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + + +##### tdefile_media (module) ###################### + +set( target tdefile_media ) + +tde_add_kpart( ${target} AUTOMOC + SOURCES tdefilemediaplugin.cpp + LINK mediacommon-static tdeio-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/tdeioslave/media/tdefile-plugin/Makefile.am b/tdeioslave/media/tdefile-plugin/Makefile.am new file mode 100644 index 000000000..15807ea19 --- /dev/null +++ b/tdeioslave/media/tdefile-plugin/Makefile.am @@ -0,0 +1,13 @@ +kde_module_LTLIBRARIES = tdefile_media.la + +tdefile_media_la_SOURCES = tdefilemediaplugin.cpp +tdefile_media_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -module $(KDE_PLUGIN) +tdefile_media_la_LIBADD = $(LIB_KIO) ../libmediacommon/libmediacommon.la + +kdelnkdir = $(kde_servicesdir) +kde_services_DATA = tdefile_media.desktop + +INCLUDES = -I$(srcdir)/../libmediacommon $(all_includes) + +METASOURCES = AUTO +noinst_HEADERS = tdefilemediaplugin.h diff --git a/tdeioslave/media/tdefile-plugin/tdefile_media.desktop b/tdeioslave/media/tdefile-plugin/tdefile_media.desktop new file mode 100644 index 000000000..7d652e09a --- /dev/null +++ b/tdeioslave/media/tdefile-plugin/tdefile_media.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +Type=Service +Name=Medium Information +Name[af]=Medium Informasie +Name[ar]=معلومات عن الوسيط +Name[az]=Mediyum Mə'lumatı +Name[be]=Інфармацыя аб носьбітах +Name[bg]=Информация за устройствата +Name[bn]=মিডিয়া তথ্য +Name[bs]=Informacije o mediju +Name[ca]=Informació de suports +Name[cs]=Informace o médiu +Name[csb]=Wëdowiédzô ò zôpisownëch mediach +Name[da]=Medieinformation +Name[de]=Medium-Information +Name[el]=Πληροφορίες μέσου +Name[eo]=datumportilaj informoj +Name[es]=Información de recursos +Name[et]=Andmekandja info +Name[eu]=Media informazioa +Name[fa]=اطلاعات رسانه +Name[fi]=Tallenteiden tiedot +Name[fr]=Informations sur le média +Name[fy]=Mediumynformaasje +Name[ga]=Eolas faoin Mheán +Name[gl]=Información do Meio +Name[he]=מידע אודות המדיה +Name[hi]=माध्यम जानकारी +Name[hr]=Podaci o mediju +Name[hu]=Adathordozó-jellemzők +Name[is]=Upplýsingar um miðil +Name[it]=Informazioni supporto +Name[ja]=メディア情報 +Name[ka]=ცნობები მატარებლის შესახებ +Name[kk]=Тасушының мәліметі +Name[km]=ព័ត៌មានឧបករណ៍ +Name[ko]=메모리 정보 +Name[lt]=Laikmenos informacija +Name[lv]=Datu nesēju informācija +Name[mk]=Информации за носач +Name[ms]=Maklumat Medium +Name[mt]=Informazzjoni tal-apparat +Name[nb]=Medieinformasjon +Name[nds]=Medium-Informatschoon +Name[ne]=माध्यम सूचना +Name[nl]=Mediuminformatie +Name[nn]=Medieinformasjon +Name[pa]=ਮਾਧਿਅਮ ਜਾਣਕਾਰੀ +Name[pl]=Informacje o nośnikach danych +Name[pt]=Informação do Dispositivo +Name[pt_BR]=Informações sobre a Mídia +Name[ro]=Informații mediu +Name[ru]=Сведения о диске +Name[rw]=Amakuru y'igitangazamakuru +Name[se]=Mediumdieđut +Name[sk]=Informácie o médiu +Name[sl]=Informacije o mediju +Name[sr]=Информације о медијуму +Name[sr@Latn]=Informacije o medijumu +Name[sv]=Mediainformation +Name[ta]=சாதனத் தகவல் +Name[te]=మాధ్యమ సమాచారం +Name[th]=ข้อมูลของสื่อ +Name[tr]=Ortam Bilgisi +Name[tt]=Media Turında +Name[uk]=Інформація про носій +Name[uz]=Saqlash uskuna haqida maʼlumot +Name[uz@cyrillic]=Сақлаш ускуна ҳақида маълумот +Name[vi]=Thông tin về Ổ lưu trữ +Name[wa]=Informåcions sol mediom +Name[zh_CN]=介质信息 +Name[zh_TW]=媒體資訊 +ServiceTypes=KFilePlugin +X-TDE-Library=tdefile_media +MimeType=media/audiocd;media/hdd_mounted;media/hdd_mounted_decrypted;media/blankcd;media/hdd_unmounted;media/hdd_unmounted_decrypted;media/blankdvd;media/cdrom_mounted;media/cdrom_mounted_decrypted;media/cdrom_unmounted;media/cdrom_unmounted_decrypted;media/cdwriter_mounted;media/cdwriter_mounted_decrypted;media/nfs_mounted;media/cdwriter_unmounted;media/cdwriter_unmounted_decrypted;media/nfs_unmounted;media/removable_mounted;media/removable_mounted_decrypted;media/dvd_mounted;media/dvd_mounted_decrypted;media/removable_unmounted;media/removable_unmounted_decrypted;media/dvd_unmounted;media/dvd_unmounted_decrypted;media/smb_mounted;media/dvdvideo;media/smb_unmounted;media/floppy5_mounted;media/svcd;media/floppy5_unmounted;media/vcd;media/floppy_mounted;media/zip_mounted;media/floppy_unmounted;media/zip_unmounted;media/gphoto2camera;media/camera_mounted;media/camera_unmounted diff --git a/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp new file mode 100644 index 000000000..20e68e459 --- /dev/null +++ b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp @@ -0,0 +1,207 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Kevin Ottens <ervin ipsquad net> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "tdefilemediaplugin.h" + +#include <kgenericfactory.h> + +#include <dcopref.h> + +#include <tqpixmap.h> +#include <tqpainter.h> +#include <tqstyle.h> +#include <tqapplication.h> +#include <tqfile.h> + +#ifdef HAVE_STATVFS +# include <sys/statvfs.h> +#else +# include <sys/mount.h> +# define statvfs statfs +# define f_frsize f_bsize +#endif + +typedef KGenericFactory<KFileMediaPlugin> KFileMediaPluginFactory; +K_EXPORT_COMPONENT_FACTORY(tdefile_media, KFileMediaPluginFactory("kio_media")) + +KFileMediaPlugin::KFileMediaPlugin(TQObject *parent, const char *name, + const TQStringList& args) + : KFilePlugin(parent, name, args) +{ + addMimeType( "media/audiocd" ); + addMimeType( "media/hdd_mounted" ); + addMimeType( "media/hdd_mounted_decrypted" ); + addMimeType( "media/blankcd" ); + addMimeType( "media/hdd_unmounted" ); + addMimeType( "media/hdd_unmounted_decrypted" ); + addMimeType( "media/blankdvd" ); + addMimeType( "media/cdrom_mounted" ); + addMimeType( "media/cdrom_mounted_decrypted" ); + addMimeType( "media/cdrom_unmounted" ); + addMimeType( "media/cdrom_unmounted_decrypted" ); + addMimeType( "media/cdwriter_mounted" ); + addMimeType( "media/cdwriter_mounted_decrypted" ); + addMimeType( "media/nfs_mounted" ); + addMimeType( "media/cdwriter_unmounted" ); + addMimeType( "media/cdwriter_unmounted_decrypted" ); + addMimeType( "media/nfs_unmounted" ); + addMimeType( "media/removable_mounted" ); + addMimeType( "media/removable_mounted_decrypted" ); + addMimeType( "media/dvd_mounted" ); + addMimeType( "media/dvd_mounted_decrypted" ); + addMimeType( "media/removable_unmounted" ); + addMimeType( "media/removable_unmounted_decrypted" ); + addMimeType( "media/dvd_unmounted" ); + addMimeType( "media/dvd_unmounted_decrypted" ); + addMimeType( "media/smb_mounted" ); + addMimeType( "media/dvdvideo" ); + addMimeType( "media/smb_unmounted" ); + addMimeType( "media/floppy5_mounted" ); + addMimeType( "media/svcd" ); + addMimeType( "media/floppy5_unmounted" ); + addMimeType( "media/vcd" ); + addMimeType( "media/floppy_mounted" ); + addMimeType( "media/zip_mounted" ); + addMimeType( "media/floppy_unmounted" ); + addMimeType( "media/zip_unmounted" ); + addMimeType( "media/gphoto2camera" ); + addMimeType( "media/camera_mounted" ); + addMimeType( "media/camera_unmounted" ); +} + +bool KFileMediaPlugin::readInfo(KFileMetaInfo &info, uint /*what*/) +{ + const Medium medium = askMedium(info); + + kdDebug() << "KFileMediaPlugin::readInfo " << medium.id() << endl; + + if (medium.id().isNull()) return false; + + TQString mount_point = medium.mountPoint(); + KURL base_url = medium.prettyBaseURL(); + TQString device_node = medium.deviceNode(); + + KFileMetaInfoGroup group = appendGroup(info, "mediumInfo"); + + if (base_url.isValid()) + { + appendItem(group, "baseURL", base_url.prettyURL()); + } + + if (!device_node.isEmpty()) + { + appendItem(group, "deviceNode", device_node); + } + + if (!mount_point.isEmpty() && medium.isMounted()) + { + m_total = 0; + m_used = 0; + m_free = 0; + + struct statvfs vfs; + memset(&vfs, 0, sizeof(vfs)); + + if ( ::statvfs(TQFile::encodeName(mount_point), &vfs) != -1 ) + { + m_total = static_cast<TDEIO::filesize_t>(vfs.f_blocks) * static_cast<TDEIO::filesize_t>(vfs.f_frsize); + m_free = static_cast<TDEIO::filesize_t>(vfs.f_bavail) * static_cast<TDEIO::filesize_t>(vfs.f_frsize); + m_used = m_total - m_free; + + int percent = 0; + int length = 0; + + if (m_total != 0) + { + percent = 100 * m_used / m_total; + length = 150 * m_used / m_total; + } + + appendItem(group, "free", m_free); + appendItem(group, "used", m_used); + appendItem(group, "total", m_total); + + group = appendGroup(info, "mediumSummary"); + + appendItem(group, "percent", TQString("%1%").arg(percent)); + + TQPixmap bar(150, 20); + TQPainter p(&bar); + + p.fillRect(0, 0, length, 20, Qt::red); + p.fillRect(length, 0, 150-length, 20, Qt::green); + + TQColorGroup cg = TQApplication::palette().active(); + + TQApplication::style().tqdrawPrimitive(TQStyle::PE_Panel, &p, + TQRect(0, 0, 150, 20), cg, + TQStyle::Style_Sunken); + + appendItem( group, "thumbnail", bar ); + } + } + + return true; +} + +const Medium KFileMediaPlugin::askMedium(KFileMetaInfo &info) +{ + DCOPRef mediamanager("kded", "mediamanager"); + kdDebug() << "properties " << info.url() << endl; + DCOPReply reply = mediamanager.call( "properties", info.url().url() ); + + if ( !reply.isValid() ) + { + return Medium(TQString::null, TQString::null, TQString::null); + } + + return Medium::create(reply); +} + +void KFileMediaPlugin::addMimeType(const char *mimeType) +{ + KFileMimeTypeInfo *info = addMimeTypeInfo( mimeType ); + + KFileMimeTypeInfo::GroupInfo *group + = addGroupInfo(info, "mediumInfo", i18n("Medium Information")); + + KFileMimeTypeInfo::ItemInfo *item + = addItemInfo(group, "free", i18n("Free"), TQVariant::ULongLong); + setUnit(item, KFileMimeTypeInfo::Bytes); + + item = addItemInfo(group, "used", i18n("Used"), TQVariant::ULongLong); + setUnit(item, KFileMimeTypeInfo::Bytes); + + item = addItemInfo(group, "total", i18n("Total"), TQVariant::ULongLong); + setUnit(item, KFileMimeTypeInfo::Bytes); + + item = addItemInfo(group, "baseURL", i18n("Base URL"), TQVariant::String); + item = addItemInfo(group, "mountPoint", i18n("Mount Point"), TQVariant::String); + item = addItemInfo(group, "deviceNode", i18n("Device Node"), TQVariant::String); + + group = addGroupInfo(info, "mediumSummary", i18n("Medium Summary")); + + item = addItemInfo(group, "percent", i18n("Usage"), TQVariant::String); + + item = addItemInfo( group, "thumbnail", i18n("Bar Graph"), TQVariant::Image ); + setHint( item, KFileMimeTypeInfo::Thumbnail ); +} + +#include "tdefilemediaplugin.moc" diff --git a/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.h b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.h new file mode 100644 index 000000000..e8dc7d26a --- /dev/null +++ b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.h @@ -0,0 +1,47 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Kevin Ottens <ervin ipsquad net> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _KFILE_MEDIA_H_ +#define _KFILE_MEDIA_H_ + +#include <tdefilemetainfo.h> +#include <kurl.h> +#include <tdeio/global.h> + +#include "medium.h" + +class KFileMediaPlugin : public KFilePlugin +{ +Q_OBJECT +public: + KFileMediaPlugin(TQObject *parent, const char *name, + const TQStringList &args); + + bool readInfo(KFileMetaInfo &info, uint what = KFileMetaInfo::Fastest); + +private: + void addMimeType(const char *mimeType); + const Medium askMedium(KFileMetaInfo &info); + + TDEIO::filesize_t m_total; + TDEIO::filesize_t m_used; + TDEIO::filesize_t m_free; +}; + +#endif diff --git a/tdeioslave/media/testmedia.cpp b/tdeioslave/media/testmedia.cpp new file mode 100644 index 000000000..eb0871f6f --- /dev/null +++ b/tdeioslave/media/testmedia.cpp @@ -0,0 +1,69 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kio_media.h" +#include "testmedia.h" + +#include <config.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kcmdlineargs.h> + +#include <stdlib.h> + +static bool check(const TQString& txt, TQString a, TQString b) +{ + if (a.isEmpty()) + a = TQString::null; + if (b.isEmpty()) + b = TQString::null; + if (a == b) { + kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "ok" << endl; + } + else { + kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "KO !" << endl; + exit(1); + } + return true; +} + +int main(int argc, char *argv[]) +{ + TDEApplication::disableAutoDcopRegistration(); + TDECmdLineArgs::init(argc,argv,"testmedia", 0, 0, 0, 0); + TDEApplication app; + + TestMedia test; + test.setup(); + test.runAll(); + kdDebug() << "All tests OK." << endl; + return 0; // success. The exit(1) in check() is what happens in case of failure. +} + +void TestMedia::setup() +{ + +} + +void TestMedia::runAll() +{ + +} + diff --git a/tdeioslave/media/testmedia.h b/tdeioslave/media/testmedia.h new file mode 100644 index 000000000..dd2481bda --- /dev/null +++ b/tdeioslave/media/testmedia.h @@ -0,0 +1,34 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kvin Ottens <ervin ipsquad net> + + This library 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 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef TESTMEDIA_H +#define TESTMEDIA_H + +class TestMedia +{ +public: + TestMedia() {} + void setup(); + void runAll(); + + // tests + +}; + +#endif |