You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tde-guidance/mountconfig/mountconfig.py

3307 lines
136 KiB

#!/usr/bin/python
# -*- coding: UTF-8 -*-
###########################################################################
# mountconfig.py - description #
# ------------------------------ #
# begin : Fri Nov 30 2003 #
# copyright : (C) 2003 by Simon Edwards #
# email : simon@simonzone.com #
# #
###########################################################################
# #
# 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. #
# #
###########################################################################
from qt import *
from tdeui import *
from tdecore import *
from tdefile import *
12 years ago
from tdeio import *
import sys
import os
import os.path
from types import StringType,UnicodeType
import pwd
import grp
import math
import locale
import codecs
import subprocess
import MicroHAL
from SMBShareSelectDialog import *
from SimpleCommandRunner import *
from fuser import *
import sizeview
programname = "Disk & Filesystem Configuration"
version = "0.8.0"
# Are we running as a separate standalone application or in KControl?
standalone = __name__=='__main__'
# Running as the root user or not?
isroot = os.getuid()==0
allowuuid = True
allowlabel = True
"""
Universal Options
-----------------
async/sync
atime/noatime
auto/noauto
dev/nodev
exec/noexec
ro/rw
suid/nosuid
dirsync
nouser/user/users
defaults =>rw, suid, dev, exec, auto, nouser, and async.
Automatically set
=================
_netdev
The filesystem resides on a device that requires network access (used to
prevent the system from attempting to mount these filesystems until the
network has been enabled on the system).
remount
Attempt to remount an already-mounted file system. This is commonly used
to change the mount flags for a file system, especially to make a readonly
file system writeable. It does not change device or mount point.
Supported filesystems
---------------------
nfs
ext2
ext3
ext4
reiserfs
vfat
ntfs
udf
iso9660
supermount
reiser4
xfs
jfs
hfs
hfsplus
cifs (replacement for smbfs)
auto
swap
proc
sysfs
usbdevfs
procbususb
TODO
----
* SMB finished the connection username nad password fields.
* SMB entry: finished writing the config.
* SMBSelector: setting the username and password.
"""
############################################################################
class UserComboBox(KComboBox):
def __init__(self,parent,name=None):
KComboBox.__init__(self,parent,name)
tmplist = []
users = pwd.getpwall()
for user in users:
uid = int(user[2])
username = user[4]
tmplist.append( (int(uid),"%s (%s)" % (username,uid)) )
tmplist.sort(lambda a,b: cmp(a[1],b[1]))
self.userlist = []
for user in tmplist:
self.insertItem(user[1])
self.userlist.append(user[0])
########################################################################
def setUID(self,uid):
if uid in self.userlist:
self.setCurrentItem(self.userlist.index(int(uid)))
return True
else:
return False
########################################################################
def UID(self):
return self.userlist[self.currentItem()]
############################################################################
class GroupComboBox(KComboBox):
def __init__(self,parent,name=None):
KComboBox.__init__(self,parent,name)
self.grouplist = []
groups = grp.getgrall()
tmplist = []
for group in groups:
gid = group[2]
groupname = group[0]
tmplist.append( (int(gid),"%s (%s)" % (groupname,gid)) )
tmplist.sort(lambda a,b: cmp(a[1],b[1]))
self.grouplist = []
for group in tmplist:
self.insertItem(group[1])
self.grouplist.append(group[0])
########################################################################
def setGID(self,gid):
if gid in self.grouplist:
self.setCurrentItem(self.grouplist.index(int(gid)))
return True
else:
return False
########################################################################
def GID(self):
return self.grouplist[self.currentItem()]
############################################################################
class MountEntryExt(object):
use_as_device = "devicenode" # Can be one of "devicenode", "uuid" or "label"
showdevice = True
showlabel = False
showuuid = False
########################################################################
# Base can be either a fstab format line of text, of another MountEntry
# object.
def __init__(self,base=None):
if base==None:
self.device = unicode(i18n("<device>"))
self.mountpoint = unicode(i18n("<mount point>"))
self.mounttype = 'ext2'
self.uuid = ""
self.label = ""
self.extraoptions = "noauto"
self.fs_freq = 0
self.fs_passno = 0
self.enabled = False
self.managed = False
self.device_string = ""
elif isinstance(base,StringType) or isinstance(base,UnicodeType):
parts = base.split()
device_ref = MountEntry.decodeMountEntryString(parts[0])
self.uuid = ""
self.label = ""
if device_ref.startswith("UUID="):
self.uuid = device_ref[5:]
self.setUseAsDevice("uuid")
mapped_device = microhal.getDeviceByUUID(self.uuid)
if mapped_device is not None:
self.device = mapped_device.getDev()
else:
self.device = ""
try:
self.label = mapped_device.getLabel()
except AttributeError:
pass
elif device_ref.startswith("LABEL="):
self.label = device_ref[6:]
self.setUseAsDevice("label")
mapped_device = microhal.getDeviceByLabel(self.label)
if mapped_device is not None:
self.device = mapped_device.getDev()
else:
self.device = ""
else:
self.device = device_ref
self.mountpoint = MountEntry.decodeMountEntryString(parts[1])
self.mounttype = MountEntry.decodeMountEntryString(parts[2])
self.extraoptions = MountEntry.decodeMountEntryString(parts[3])
self.fs_freq = int(parts[4])
self.fs_passno = int(parts[5])
self.enabled = False
options = self.extraoptions.split(",")
self.managed = "managed" in options
try:
options.remove("managed")
except ValueError:
pass
self.extraoptions = ",".join(options)
else:
# This is a new entry, but it's based on another one.
self.device = base.device
self.mountpoint = base.mountpoint
self.mounttype = base.mounttype
self.extraoptions = base.extraoptions
self.fs_freq = base.fs_freq
self.fs_passno = base.fs_passno
self.uuid = base.uuid
self.enabled = base.enabled
self.managed = False
self.iconname = self.getIconName()
########################################################################
def copy(self,newobject=None):
if newobject is None:
newobject = MountEntryExt()
# FIXME: use "newobject = self.__class__()" and get rid of the newobject parameter.
newobject.device = self.device
newobject.mountpoint = self.mountpoint
newobject.mounttype = self.mounttype
newobject.use_as_device = self.use_as_device
newobject.showlabel = self.showlabel
newobject.showdevice = self.showdevice
newobject.showuuid = self.showuuid
newobject.extraoptions = self.extraoptions
newobject.fs_freq = self.fs_freq
newobject.fs_passno = self.fs_passno
newobject.enabled = self.enabled
newobject.uuid = self.uuid
newobject.label = self.label
return newobject
########################################################################
def cleanup(self):
# This method is called after the entry has been removed from the
# mounttable.
pass
########################################################################
def setMountType(self,mounttypename): self.mounttype = mounttypename
########################################################################
def isFileSystemAvailable(self):
return microhal.isSupportedFileSystem(self.mounttype)
def getDevice(self): return self.device
def setDevice(self,device): self.device = device
def setUseAsDevice(self,use_as): self.use_as_device = use_as
def getUseAsDevice(self): return self.use_as_device
def setUUID(self,uuid): self.uuid = uuid
def setLabel(self,label): self.label = label
def getMountPoint(self): return self.mountpoint
def setMountPoint(self,mountpoint): self.mountpoint = mountpoint
def getExtraOptions(self): return self.extraoptions
def setExtraOptions(self,extraoptions): self.extraoptions = extraoptions
def getFSFreq(self): return self.fs_freq
def setFSFreq(self,fs_freq): self.fs_freq = fs_freq
def getFSPassno(self): return self.fs_passno
def setFSPassno(self,fs_passno): self.fs_passno = fs_passno
def isManaged(self): return self.managed
def getUUID(self):
if not self.uuid:
return ""
return self.uuid
def getLabel(self):
try:
if not self.label:
return ""
return self.label
except AttributeError:
return ""
def getDeviceString(self):
if self.getUseAsDevice() == "label":
if self.label != "":
return MountEntry.encodeMountEntryString("LABEL="+self.label)
else:
print "No Label set, preventing you from shooting yourself in the foot"
elif self.getUseAsDevice() == "uuid":
if self.uuid != "":
return "UUID="+self.uuid
return MountEntry.encodeMountEntryString("UUID="+self.uuid)
else:
print "No UUID set, preventing you from shooting yourself in the foot"
return MountEntry.encodeMountEntryString(self.device)
########################################################################
def getName(self):
if os.path.basename(self.device).startswith("fd"):
return "Floppy"
else:
return self.mountpoint
########################################################################
def getIconName(self):
if self.device is not None and os.path.basename(self.device).startswith("fd"):
return "hi16-floppy"
else:
return "hi16-blockdevice"
########################################################################
def updateStatus(self,mtablist):
self.enabled = self.mountpoint in mtablist
########################################################################
def getFstabOptions(self):
if self.extraoptions!="":
return self.extraoptions.split(",")
else:
return []
########################################################################
def getFstabLine(self):
# Construct the options field.
_options = self.getFstabOptions()
options = []
# Remove whitespace and dupes
for o in _options:
if o.strip() not in options:
options.append(o.strip())
return self.getDeviceString() + \
u" " + MountEntry.encodeMountEntryString(self.mountpoint.replace("%20","\040")) + \
u" " + MountEntry.encodeMountEntryString(self.mounttype) + \
u" " + MountEntry.encodeMountEntryString(u",".join(options)) + \
u" " + unicode(self.fs_freq) + u" " + unicode(self.fs_passno)
########################################################################
def getCategory(self):
return self.device
########################################################################
def isEnabled(self): return self.enabled
########################################################################
def enable(self,parentdialog):
self._setBusy(parentdialog,True)
try:
(rc,output) = SimpleCommandRunner().run(["/bin/mount",self.mountpoint])
finally:
self._setBusy(parentdialog,False)
if rc!=0:
self.handleMountFailure(parentdialog,rc,output,True)
########################################################################
def disable(self,parentdialog):
self._setBusy(parentdialog,True)
try:
(rc,output) = SimpleCommandRunner().run(["/bin/umount",self.mountpoint])
finally:
self._setBusy(parentdialog,False)
if rc!=0:
self.handleMountFailure(parentdialog,rc,output,False)
########################################################################
def handleMountFailure(self,parentdialog,rc,output,mount_action=True):
"""
Keyword arguments:
mount_action - True=enable, False=disable
"""
global kapp
if mount_action:
msg = i18n("An error occurred while enabling %1.\n\nThe system reported: %2").arg( \
self.mountpoint).arg(output)
captionmsg = i18n("Unable to enable %1").arg(self.mountpoint)
else:
msg = i18n("An error occurred while disabling %1.\n\nThe system reported: %2").arg(
self.mountpoint).arg(output)
captionmsg = i18n("Unable to disable %1").arg(self.mountpoint)
extramsg = unicode(i18n("Return code from mount was %1.\n").arg(rc))
if (rc & 1)!=0:
extramsg += unicode(i18n("\"incorrect invocation or permissions\"\n"))
if (rc & 2)!=0:
extramsg += unicode(i18n("\"system error (out of memory, cannot fork, no more loop devices)\"\n"))
if (rc & 4)!=0:
extramsg += unicode(i18n("\"internal mount bug or missing nfs support in mount\"\n"))
if (rc & 8)!=0:
extramsg += unicode(i18n("\"user interrupt\"\n"))
if (rc & 16)!=0:
extramsg += unicode(i18n("\"problems writing or locking /etc/mtab\"\n"))
if (rc & 32)!=0:
extramsg += unicode(i18n("\"mount failure\"\n"))
if (rc & 64)!=0:
extramsg += unicode(i18n("\"some mount succeeded\"\n"))
in_use = False
if not mount_action:
# Use lsof to find out what is blocking the device.
lsof_bin = '/usr/bin/lsof'
rc, output = SimpleCommandRunner().run([lsof_bin,'-FncL',str(self.mountpoint)])
if rc==0:
# Check if there is one or more processes using the device.
in_use = len(output.split())>3
if in_use:
# Start fuser.py which lists open filedescriptors on device and offers to get
# rid of them.
fuser = FUser(str(self.mountpoint),None,lsof_bin,kapp)
fuser.exec_loop()
in_use_message = ""
if fuser.result() != 0:
in_use_message = unicode(i18n("Unmounting %1 failed or was cancelled.").arg(self.device))
extramsg += in_use_message
else:
extramsg += unicode(i18n("(none)"))
if not in_use:
KMessageBox.detailedSorry(parentdialog, msg, extramsg, captionmsg)
########################################################################
def _setBusy(self,parentdialog,flag):
global kapp
if flag:
kapp.setOverrideCursor( QCursor(Qt.WaitCursor) )
parentdialog.setEnabled(False)
# It is necessary to process some of the events in the event queue.
# Otherwise the user won't see that the window is disabled.
# ( setEnabled() here above doesn't redraw the window immediately.
# Redrawing is done via the event queue.)
kapp.processEvents()
else:
parentdialog.setEnabled(True)
kapp.restoreOverrideCursor()
############################################################################
class MountEntryExtCommonUnix(MountEntryExt):
USERMOUNT_NO = 0
USERMOUNT_ONE = 1
USERMOUNT_ANY = 2
USERMOUNT_OWNER = 3
########################################################################
# Base can be either a fstab format line of text, or another MountEntry
# object.
def __init__(self,base=None):
super(MountEntryExtCommonUnix,self).__init__(base)
if isinstance(base,MountEntryExtCommonUnix):
# Being initalised from an existing object.
# Only mess with objects
self.atime = base.atime
self.auto = base.auto
self.writeable = base.writeable
self.usedevpoints = base.usedevpoints
self.showlabel = True
self.showuuid = True
self.allowexecutables = base.allowexecutables
self.allowsuid = base.allowsuid
self.allowusermount = base.allowusermount
elif isinstance(base,StringType) or isinstance(base,UnicodeType):
options = self.extraoptions.split(",")
self.atime = True
if "noatime" in options:
self.atime = False
self.auto = True
if "noauto" in options:
self.auto = False
self.writeable = True
if "ro" in options:
self.writeable = False
self.usedevpoints = True
if "nodev" in options:
self.usedevpoints = False
self.allowexecutables = True
if "noexec" in options:
self.allowexecutables = False
self.allowsuid = True
if "nosuid" in options:
self.allowsuid = False
self.allowusermount = self.USERMOUNT_NO
if "user" in options:
self.allowusermount = self.USERMOUNT_ONE
if "users" in options:
self.allowusermount = self.USERMOUNT_ANY
if "owner" in options:
self.allowusermount = self.USERMOUNT_OWNER
self.showlabel = True
self.showuuid = True
for x in ["noatime","atime","auto","noauto","dev","nodev","nouser", \
"owner","users","user","suid","nosuid","exec","noexec","rw","ro"]:
try:
options.remove(x)
except ValueError:
pass
self.extraoptions = ",".join(options)
else:
# Set some sane defaults.
self.showlabel = True
self.showuuid = True
self.atime = True
self.auto = False
self.writeable = True
self.usedevpoints = False
self.allowexecutables = False
self.allowsuid = False
self.allowusermount = self.USERMOUNT_NO
########################################################################
def copy(self,newobject=None):
if newobject is None:
newobject = MountEntryExtCommonUnix()
super(MountEntryExtCommonUnix,self).copy(newobject)
newobject.atime = self.atime
newobject.auto = self.auto
newobject.use_as_device = self.use_as_device
newobject.showlabel = self.showlabel
newobject.showdevice = self.showdevice
newobject.showuuid = self.showuuid
newobject.uuid = self.uuid
newobject.label = self.label
newobject.writeable = self.writeable
newobject.usedevpoints = self.usedevpoints
newobject.allowexecutables = self.allowexecutables
newobject.allowsuid = self.allowsuid
newobject.allowusermount = self.allowusermount
return newobject
########################################################################
def getFstabOptions(self):
options = []
# These options must appear before the others. 'user', according to the
# mount man page implies 'noexec' too, BUT the noexec can be overridden
# by specifying 'exec' after the 'user' keyword. Therefore 'exec' etc
# must come after 'user', 'users' and friends.
options.append(['nouser','user','users','owner'][self.allowusermount])
super_options = super(MountEntryExtCommonUnix,self).getFstabOptions()
options.extend(super_options)
options.append(['noatime','atime'][self.atime])
options.append(['noauto','auto'][self.auto])
options.append(['ro','rw'][self.writeable])
options.append(['nodev','dev'][self.usedevpoints])
options.append(['noexec','exec'][self.allowexecutables])
options.append(['nosuid','suid'][self.allowsuid])
return options
########################################################################
# atime/noatime
def getAtime(self): return self.atime
def setAtime(self,val): self.atime = val
# auto/noauto
def getMountAtBoot(self): return self.auto
def setMountAtBoot(self,val): self.auto = val
# ro/rw
def getWritable(self): return self.writeable
def setWritable(self,val): self.writeable = val
# dev, nodev
def getUseDevPoints(self): return self.usedevpoints
def setUseDevPoints(self,val): self.usedevpoints = val
# exec/noexec
def getAllowExecutables(self): return self.allowexecutables
def setAllowExecutable(self,val): self.allowexecutables = val
# suid/nosuid
def getSUID(self): return self.allowsuid
def setSUID(self,val): self.allowsuid = val
# nouser/user/users/owner
def setAllowUserMount(self,val): self.allowusermount = val
def getAllowUserMount(self): return self.allowusermount
############################################################################
# Common unix filesystems, but for local hard disks. i.e. partitions.
class MountEntryExtCommonUnixLocal(MountEntryExtCommonUnix):
########################################################################
def __init__(self,base=None):
super(MountEntryExtCommonUnixLocal,self).__init__(base)
########################################################################
def copy(self,newobject=None):
if newobject is None:
newobject = MountEntryExtCommonUnixLocal()
super(MountEntryExtCommonUnixLocal,self).copy(newobject)
newobject.showlabel = self.showlabel
newobject.showdevice = self.showdevice
newobject.showuuid = self.showuuid
return newobject
############################################################################
class MountEntryExtAlien(MountEntryExt):
USERMOUNT_NO = 0
USERMOUNT_ONE = 1
USERMOUNT_ANY = 2
USERMOUNT_OWNER = 3
########################################################################
# Base can be either a fstab format line of text, of another MountEntry
# object.
def __init__(self,base=None):
super(MountEntryExtAlien,self).__init__(base)
if isinstance(base,MountEntryExtAlien):
self.uid = base.uid
self.gid = base.gid
self.label = base.label
self.writeable = base.writeable
self.auto = base.auto
self.allowusermount = base.allowusermount
elif isinstance(base,StringType) or isinstance(base,UnicodeType):
self.uid = 0
self.gid = 0
options = self.extraoptions.split(",")
newoptions = []
for line in options:
if line.startswith("uid="):
try:
self.uid = int(line[4:])
except ValueError:
self.uid = 0
elif line.startswith("gid="):
try:
self.gid = int(line[4:])
except ValueError:
self.gid = 0
else:
# We hang on to unknown options for later.
newoptions.append(line)
options = newoptions
self.writeable = True
if "ro" in options:
self.writeable = False
self.auto = True
if "noauto" in options:
self.auto = False
self.allowusermount = self.USERMOUNT_NO
if "user" in options:
self.allowusermount = self.USERMOUNT_ONE
if "users" in options:
self.allowusermount = self.USERMOUNT_ANY
if "owner" in options:
self.allowusermount = self.USERMOUNT_OWNER
for x in ["noatime","atime","auto","noauto","dev","nodev","nouser", \
"owner","users","user","suid","nosuid","exec","noexec","rw", \
"ro"]:
try:
options.remove(x)
except ValueError:
pass
self.extraoptions = ",".join(options)
else:
self.uid = 0
self.gid = 0
self.writeable = False
self.auto = False
self.allowusermount = self.USERMOUNT_NO
########################################################################
def copy(self,newobject=None):
if newobject is None:
newobject = MountEntryExtAlien()
super(MountEntryExtAlien,self).copy(newobject)
newobject.uid = self.uid
newobject.gid = self.gid
newobject.use_as_device = self.use_as_device
newobject.showlabel = self.showlabel
newobject.showdevice = self.showdevice
newobject.showuuid = self.showuuid
newobject.writeable = self.writeable
newobject.auto = self.auto
newobject.allowusermount = self.allowusermount
return newobject
########################################################################
def getFstabOptions(self):
# Construct the options field.
options = super(MountEntryExtAlien,self).getFstabOptions()
options.append('uid='+unicode(self.uid))
options.append('gid='+unicode(self.gid))
options.append(['noauto','auto'][self.auto])
options.append(['ro','rw'][self.writeable])
options.append(['nouser','user','users','owner'][self.allowusermount])
return options
########################################################################
def getUID(self): return self.uid
def setUID(self,val): self.uid = val
def getGID(self): return self.gid
def setGID(self,val): self.gid = val
# ro/rw
def getWritable(self): return self.writeable
def setWritable(self,val): self.writeable = val
# auto/noauto
def getMountAtBoot(self): return self.auto
def setMountAtBoot(self,val): self.auto = val
# nouser/user/users/owner
def setAllowUserMount(self,val): self.allowusermount = val
def getAllowUserMount(self): return self.allowusermount
############################################################################
class MountEntryExtVFAT(MountEntryExtAlien):
def __init__(self,base=None):
super(MountEntryExtVFAT,self).__init__(base)
if isinstance(base,MountEntryExtVFAT):
self.suppresspermissionerrors = base.suppresspermissionerrors
elif isinstance(base,StringType) or isinstance(base,UnicodeType):
options = self.extraoptions.split(",")
self.suppresspermissionerrors = "quiet" in options
try:
options.remove("quiet")
except ValueError:
pass
self.extraoptions = ",".join(options)
else:
self.suppresspermissionerrors = False
########################################################################
def copy(self,newobject=None):
if newobject is None:
newobject = MountEntryExtVFAT()
super(MountEntryExtVFAT,self).copy(newobject)
newobject.suppresspermissionerrors = self.suppresspermissionerrors
newobject.showlabel = self.showlabel
newobject.showdevice = self.showdevice
newobject.showuuid = self.showuuid
return newobject
########################################################################
def getFstabOptions(self):
options = super(MountEntryExtVFAT,self).getFstabOptions()
if self.suppresspermissionerrors:
options.append('quiet')
return options
def getSuppressPermissionErrors(self): return self.suppresspermissionerrors
def setSuppressPermissionErrors(self,val): self.suppresspermissionerrors = val
############################################################################
class MountEntryExtSMB(MountEntryExtAlien):
CREDENTIALSBASENAME = "/etc/fstab_smb_credentials_"
########################################################################
def __init__(self,base=None):
super(MountEntryExtSMB,self).__init__(base)
if isinstance(base,MountEntryExtSMB):
self.username = base.username
self.password = base.password
self.credentialsfile = base.credentialsfile
elif isinstance(base,StringType) or isinstance(base,UnicodeType):
self.username = None
self.password = ""
self.credentialsfile = None
newoptions = []
options = self.extraoptions.split(",")
for line in options:
if line.startswith("username="):
self.username = line[9:]
elif line.startswith("password="):
self.password = line[9:]
elif line.startswith("credentials="):
self.credentialsfile = line[12:]
try:
fhandle = codecs.open(self.credentialsfile,'r',locale.getpreferredencoding())
for line in fhandle.readlines():
if line.startswith("username"):
self.username = line[8:].strip()[1:].strip()
elif line.startswith("password"):
self.password = line[8:].strip()[1:].strip()
fhandle.close()
if not self.credentialsfile.startswith(self.CREDENTIALSBASENAME):
self.credentialsfile = None
except IOError:
self.credentialsfile = None
elif line=="guest":
pass
else:
# We hang on to unknown options for later.
newoptions.append(line)
options = newoptions
if self.username == "":
self.username = None
self.extraoptions = ",".join(options)
else:
self.username = None
self.password = ""
self.credentialsfile = None
########################################################################
def copy(self,newobject=None):
if newobject is None:
newobject = MountEntryExtSMB()
super(MountEntryExtSMB,self).copy(newobject)
newobject.username = self.username
newobject.password = self.password
newobject.credentialsfile = self.credentialsfile
newobject.showlabel = self.showlabel
newobject.showdevice = self.showdevice
newobject.showuuid = self.showuuid
return newobject
########################################################################
def cleanup(self):
if (self.credentialsfile is not None) and os.path.exists(self.credentialsfile) and os.path.isfile(self.credentialsfile):
os.remove(self.credentialsfile)
########################################################################
def getIconName(self):
return "hi16-network"
########################################################################
def getFstabOptions(self):
options = super(MountEntryExtSMB,self).getFstabOptions()
if self.username is None:
if (self.credentialsfile is not None) and os.path.exists(self.credentialsfile) and os.path.isfile(self.credentialsfile):
os.remove(self.credentialsfile)
options.append("guest") # This option should stop mount(8) from asking for a password.
else:
# Write out the credentials file
if self.credentialsfile is None:
i = 1
while os.path.exists(self.CREDENTIALSBASENAME+unicode(i)):
i += 1
self.credentialsfile = self.CREDENTIALSBASENAME+unicode(i)
fd = os.open(self.credentialsfile,os.O_WRONLY|os.O_CREAT,0600)
fhandle = os.fdopen(fd,'w')
fhandle.write((u"username = %s\npassword = %s\n" % (self.username,self.password))
.encode(locale.getpreferredencoding(),'replace') )
fhandle.close()
options.append(u"credentials="+self.credentialsfile)
return options
########################################################################
def getUsername(self): return self.username
def setUsername(self,username): self.username = username
def getPassword(self): return self.password
def setPassword(self,password): self.password = password
############################################################################
class MountEntryExtSystem(MountEntryExt):
########################################################################
def __init__(self,base=None):
super(MountEntryExtSystem,self).__init__(base)
self.use_as_device = "devicenode"
self.label = ""
self.showuuid = False
self.showlabel = False
########################################################################
def copy(self,newobject=None):
if newobject is None:
newobject = MountEntryExtSystem()
super(MountEntryExtSystem,self).copy(newobject)
return newobject
########################################################################
def getCategory(self):
return "system"
def disable(self,parentdialog):
""" This shouldn't happen since system entries have the disable button disabled """
msg = i18n("Disabling %1 is not supported.").arg(self.mountpoint)
extramsg = i18n("""Some system devices cannot be disabled because they are needed for \
basic functionality of the operating system.""")
KMessageBox.detailedSorry(parentdialog,msg,extramsg,\
i18n("Error occurred while disabling %1").arg(self.mountpoint))
############################################################################
class MountEntryExtSwap(MountEntryExt):
########################################################################
# Base can be either a fstab format line of text, of another MountEntry
# object.
def __init__(self,base=None):
super(MountEntryExtSwap,self).__init__(base)
if isinstance(base,StringType) or isinstance(base,UnicodeType):
options = self.extraoptions.split(",")
try:
options.remove('defaults')
except ValueError:
pass
self.extraoptions = u",".join(options)
########################################################################
def copy(self,newobject=None):
if newobject is None:
newobject = MountEntryExtSwap()
super(MountEntryExtSwap,self).copy(newobject)
return newobject
########################################################################
def getFstabOptions(self):
options = super(MountEntryExtSwap,self).getFstabOptions()
if len(options)==0:
# Make sure there is at least one option in the list.
options.append('defaults')
return options
########################################################################
def updateStatus(self,mtablist):
this_device = self.device
if this_device is None:
# Find the device name by its UUID.
if self.uuid:
hal_device = microhal.getDeviceByUUID(self.uuid)
if self.label:
hal_device = microhal.getDeviceByLabel(self.label)
if hal_device is None:
self.enabled = False
return
this_device = hal_device.getDev()
# If the device is a symlink, then grab the complete target.
if os.path.islink(this_device):
this_device = os.path.join(os.path.dirname(this_device),os.readlink(this_device))
fhandle = open("/proc/swaps")
lines = fhandle.readlines()
fhandle.close()
try: del lines[0]
except IndexError: pass
self.enabled = False
for line in lines:
parts = line.split()
if parts[0]==this_device:
self.enabled = True
return
########################################################################
# Returns a list of command+arguments
def enable(self,parentdialog):
self._setBusy(parentdialog,True)
try:
(rc,output) = SimpleCommandRunner().run(['/sbin/swapon',self.device])
if rc!=0:
msg = i18n("An error occurred while enabling swap partition %1.\n\nThe system reported: %2").arg(self.device).arg(output)
KMessageBox.sorry(parentdialog,msg,\
i18n("Error occurred while enabling swap partition %1").arg(self.device))
finally:
self._setBusy(parentdialog,False)
########################################################################
# Returns a list of command+arguments or None.
def disable(self,parentdialog):
self._setBusy(parentdialog,True)
try:
(rc,output) = SimpleCommandRunner().run(['/sbin/swapoff',self.device])
if rc!=0:
msg = i18n("An error occurred while disabling swap partition %1.\n\nThe system reported: %2").arg(self.device).arg(output)
KMessageBox.sorry(parentdialog,msg,\
i18n("Error occurred while disabling swap partition %1").arg(self.device))
finally:
self._setBusy(parentdialog,False)
############################################################################
# This represents a mount entry.
#
# It also does a little trick with the MountEntryExt classes. MountEntry
# objects kind of 'change' class under your nose when they are set to
# different mount types. The handling of the different kinds of mount types
# is handled by MountEntryExt objects and subclasses.
class MountEntry(object):
MountTypes = {
'proc' : (MountEntryExtSystem,i18n("proc")),
'sysfs' : (MountEntryExtSystem,i18n("sysfs")),
'rootfs' : (MountEntryExtSystem,i18n("rootfs")),
'bdev' : (MountEntryExtSystem,i18n("bdev")),
'sockfs' : (MountEntryExtSystem,i18n("sockfs")),
'tmpfs' : (MountEntryExtSystem,i18n("tmpfs")),
'shm' : (MountEntryExtSystem,i18n("shm")),
'pipefs' : (MountEntryExtSystem,i18n("pipefs")),
'devfs' : (MountEntryExtSystem,i18n("devfs - Device File System")),
'devpts' : (MountEntryExtSystem,i18n("devpts")),
'ramfs' : (MountEntryExtSystem,i18n("ramfs")),
'auto' : (MountEntryExtCommonUnix,i18n("Automatic")),
'usbdevfs' : (MountEntryExtSystem,i18n("usbdevfs")),
'procbususb' : (MountEntryExtSystem,i18n("procbususb")),
'usbfs' : (MountEntryExtSystem,i18n("usbfs")),
'supermount' : (MountEntryExt,i18n("supermount")),
'swap' : (MountEntryExtSwap,i18n("Swap - Linux Swap Space")),
'nfs' : (MountEntryExtCommonUnix,i18n("NFS - Network File System")),
'cifs' : (MountEntryExtSMB,i18n("Windows File Sharing")),
'ext2' : (MountEntryExtCommonUnixLocal,i18n("Ext2 - Second Extended FS")),
'ext3' : (MountEntryExtCommonUnixLocal,i18n("Ext3 - Third Extended FS")),
'ext4' : (MountEntryExtCommonUnixLocal,i18n("Ext4 - Fourth Extended FS")),
'reiserfs' : (MountEntryExtCommonUnixLocal,i18n("ReiserFS")),
'reiser4' : (MountEntryExtCommonUnixLocal,i18n("Reiser4")),
'xfs' : (MountEntryExtCommonUnixLocal,i18n("XFS - SGI's journaling filesystem")),
'hfs' : (MountEntryExtCommonUnixLocal,i18n("HFS - Apple's Hierarchical File System")),
'hfsplus' : (MountEntryExtVFAT,i18n("HFS+ - Apple's modernized Hierarchical File System")),
'jfs' : (MountEntryExtCommonUnixLocal,i18n("JFS - IBM's Journaled File System")),
'vfat' : (MountEntryExtVFAT,i18n("VFAT - Microsoft FAT File Systems")),
'ntfs' : (MountEntryExtVFAT,i18n("NTFS - NT File System")),
'udf' : (MountEntryExtSystem,i18n("udf")),
'iso9660' : (MountEntryExt,i18n("iso9660 - CD-ROM")),
}
notInFstab = False
maydisable = True # Some entries, such as /proc can't be disabled.
########################################################################
# Base can be either a fstab format line of text, of another MountEntry
# object.
def __init__(self,base=None):
try:
self.extensionObjects = {}
if base==None:
self.mounttype = 'auto'
elif isinstance(base,StringType) or isinstance(base,UnicodeType):
parts = base.split()
self.mounttype = parts[2]
# 'udf,iso9660' seems default for some devices in fstab,
# check if all listed filesystems are available, if yes set to 'auto'.
if len(self.mounttype.split(',')) > 1:
"""
# We could check here, but then we'd need a reference to MicroHAL.
#for m in self.mounttype.split(','):
#if m not in supported_fs:
# print "Filesystem ", m, "not supported by the kernel"
# break
"""
self.mounttype = "auto"
else:
# This is a new entry, but it's based on another one.
self.mounttype = base.mounttype
self.extension = self.MountTypes[self.mounttype][0](base)
self.extensionObjects[self.mounttype] = self.extension
except (KeyError,IndexError):
raise InvalidMountEntryError, u"Unable to parse mount entry:"+unicode(base)
########################################################################
def getMountType(self):
return self.mounttype
########################################################################
def setMountType(self,newtypename):
if newtypename not in self.extensionObjects:
try:
self.extensionObjects[newtypename] = self.MountTypes[newtypename][0](self.extension)
except KeyError:
raise NotImplementedError, "Unknown mounttype:"+newtypename
self.mounttype = newtypename
self.extension = self.extensionObjects[newtypename]
self.extension.setMountType(newtypename)
########################################################################
def copy(self):
newentry = MountEntry()
newentry.mounttype = self.mounttype
newext = self.extension.copy()
newentry.use_as_device = self.use_as_device
newentry.showlabel = self.showlabel
newentry.showdevice = self.showdevice
newentry.showuuid = self.showuuid
newentry.extensionObjects[self.mounttype] = newext
newentry.extension = newext
return newentry
########################################################################
def inPlaceCopyFrom(self,sourceentry):
self.extension.cleanup()
tmpcopy = sourceentry.copy()
self.extensionObjects = tmpcopy.extensionObjects
self.mounttype = tmpcopy.mounttype
self.extension = tmpcopy.extension
# Override the attribute lookup, set/get, to use the extension object
########################################################################
def __getattr__(self,name):
try:
return getattr(self.extension,name)
except AttributeError, a:
print a
########################################################################
# FIXME
## def __setattr__(self,name,value):
## if 'extension' in self.__dict__:
## if name in self.extension.__dict__:
## setattr(self.extension,name,value)
## return
## self.__dict__[name] = value
########################################################################
def getMountTypes():
return MountEntry.MountTypes.keys()
getMountTypes = staticmethod(getMountTypes)
########################################################################
def getMountTypeLongName(typename):
return MountEntry.MountTypes[typename][1]
getMountTypeLongName = staticmethod(getMountTypeLongName)
########################################################################
def encodeMountEntryString(string):
newstring = u""
for c in string:
if c==' ':
newstring += "\\040"
elif c=="\t":
newstring += "\\012"
elif c=='\\':
newstring += "\\134"
else:
newstring += c
return newstring
encodeMountEntryString = staticmethod(encodeMountEntryString)
########################################################################
def decodeMountEntryString(string):
newstring = ""
while string!="":
if len(string)>=4 and string[0]=='\\' and isoct(string[1]) \
and isoct(string[2]) and isoct(string[3]):
newstring += chr(64*(ord(string[1])-ord('0')) + \
8*(ord(string[2])-ord('0')) + (ord(string[3])-ord('0')))
string = string[4:]
else:
newstring += string[0]
string = string[1:]
return newstring
decodeMountEntryString = staticmethod(decodeMountEntryString)
############################################################################
class MountEntryComment(MountEntry):
""" This represents a comment mount entry or generally something that we don't
understand (might be comment, might be fstab syntax we don't know, might be
a faulty line in there). We don't want to wipe that stuff out, but we can't
deal with it in a sensible way, so we keep it in a MountEntryComment,
exclude it from most operations, but will write it back to fstab afterwards
As a result of that we only define the stuff that's necessary, namely saving
the fstab line and returning it when writing."""
########################################################################
def __init__(self,base=None):
self.row = base
########################################################################
def getFstabLine(self): return self.row
############################################################################
def isoct(c): return c in '01234567'
############################################################################
class InvalidMountEntryError(Exception):
########################################################################
def __init__(self,arg=None):
self.arg = arg
########################################################################
def __str__(self):
return str(self.arg)
############################################################################
class MountTable(object):
########################################################################
def __init__(self,fstab_filename,mtab_filename):
self.fstab_filename = fstab_filename
self.mtab_filename = mtab_filename
self.entries = []
self.allentries = []
# sysfs does not need an entry in fstab, so we add it even if it's not
# in there, it's mounted automatically anyway and shows up in mtab
sysfs_in_fstab = False
usbdevfs_in_fstab = False
fhandle = codecs.open(self.fstab_filename,'r',locale.getpreferredencoding())
for row in fhandle.readlines():
row = row.strip('\n') # Carefully remove any trailing newline.
if row.strip().startswith("#") or row.strip()=="":
entry = MountEntryComment(row)
else:
try:
entry = MountEntry(row)
self.append(entry)
if entry.getMountType() == "sysfs":
sysfs_in_fstab = True
if entry.getMountType() == "usbdevfs" or "procbususb":
usbdevfs_in_fstab = True
if entry.getMountType() == "proc":
entry.maydisable = False
except InvalidMountEntryError:
entry = MountEntryComment(row)
# We keep a list with references to _all_ entries, also the comments,
# this is the one we'll use to write out our new fstab, only 'real'
# entries (real == entries we understand) are added to self to let them
# be handled by iterator.
# allentries includes comments and invalid lines, self doesn't.
self.allentries.append(entry)
fhandle.close()
if not sysfs_in_fstab:
sysfsentry = MountEntry(u"sysfs /sys sysfs defaults 0 0")
sysfsentry.notInFstab = True
sysfsentry.maydisable = False
#self.append(sysfsentry)
if not usbdevfs_in_fstab:
usbdevfsentry = MountEntry(u"procbususb /proc/bus/usb usbdevfs defaults 0 0")
usbdevfsentry.notInFstab = True
usbdevfsentry.maydisable = False
self.append(usbdevfsentry)
self.updateStatus()
########################################################################
def append(self,entry):
self.entries.append(entry)
########################################################################
def remove(self,entry):
self.allentries.remove(entry)
entry.cleanup()
########################################################################
def updateStatus(self,entry=None):
mtablist = self.getMtabList()
if entry==None:
for entry in self.entries:
entry.updateStatus(mtablist)
else:
entry.updateStatus(mtablist)
########################################################################
def getMtabList(self):
fhandle = open(self.mtab_filename)
mtablist = []
for row in fhandle.readlines():
if row.strip()[0]!='#':
parts = row.split()
mtablist.append(parts[1])
fhandle.close()
return mtablist
########################################################################
def updateFstabOnDisk(self):
fhandle = None
try:
try:
fhandle = codecs.open(self.fstab_filename+"~","w",locale.getpreferredencoding(),'replace')
for entry in self.allentries:
if not entry.notInFstab:
line = entry.getFstabLine()
fhandle.write(line+u"\n")
print line
fhandle.close()
fhandle = None
# Move it over the original
os.rename(self.fstab_filename+"~",self.fstab_filename)
return True
finally:
if fhandle:
fhandle.close()
except IOError:
return False
########################################################################
# We make this class look like a container, and just forward everything
# on to the entries attribute.
def __contains__(self,item):
return self.entries.__contains(item)
########################################################################
def __delitem__(self,key):
raise NotImplementedError, "No __delitem__ on MountTable."
########################################################################
def __getitem__(self,key):
return self.entries.__getitem__(key)
########################################################################
def __iter__(self):
return self.entries.__iter__()
########################################################################
def __len__(self):
return self.entries.__len__()
########################################################################
def __setitem__(self,key,value):
raise NotImplementedError, "No __setitem__ on MountTable."
############################################################################
class MountEntryDialogOptions(QWidget):
deviceexample = i18n("(for example /dev/hdb3)")
########################################################################
def __init__(self,parent,showmountpoint=True,showdevice=True,
showfs_freq=True,showfs_passno=True,showuuid=True,showlabel=True):
QWidget.__init__(self,parent)
self.showmountpoint = showmountpoint
self.showdevice = showdevice
self.showfs_freq = showfs_freq
self.showfs_passno = showfs_passno
self.showuuid = showuuid
self.showlabel = showlabel
self._fillPage()
# TODO: KDirSelectDialog needs "Create new Folder"
self.mountpointdialog = KDirSelectDialog("/",True,self,"Select Mount Point",True)
########################################################################
def _fillPage(self):
row = 0
grid = QGridLayout(self,1,2)
grid.setSpacing(KDialog.spacingHint())
grid.setColStretch(0,0)
grid.setColStretch(2,0)
if self.showmountpoint:
label = QLabel(i18n("Mount Point:"),self)
grid.addWidget(label,row,0)
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.mountpointlineedit = KLineEdit(hbox)
hbox.setStretchFactor(self.mountpointlineedit,1)
#self.connect(self.homediredit, SIGNAL("textChanged(const QString &)"), self.slotHomeDirChanged)
self.mountpointbutton = KPushButton(i18n("Browse..."),hbox)
hbox.setStretchFactor(self.mountpointbutton,0)
self.connect(self.mountpointbutton,SIGNAL("clicked()"),self.slotBrowseMountPointClicked)
grid.addMultiCellWidget(hbox,row,row,1,3)
row += 1
if self.showdevice:
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
label = QLabel(i18n("Device:"),self)
grid.addWidget(label,row,0)
self.devicecheckbox = QRadioButton(i18n("by name"),hbox)
self.connect(self.devicecheckbox,SIGNAL("clicked()"), \
self.slotDeviceCheckboxClicked)
self.devicelineedit = KLineEdit(hbox)
grid.addMultiCellWidget(hbox,row,row,1,3)
row += 1
example = QLabel(self.deviceexample,self)
grid.addMultiCellWidget(example,row,row,1,3)
row += 1
if self.showuuid:
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.uuidcheckbox = QRadioButton(i18n("by UUID"),hbox)
self.connect(self.uuidcheckbox,SIGNAL("clicked()"), \
self.slotUUIDCheckboxClicked)
self.uuidlineedit = KLineEdit(hbox)
grid.addMultiCellWidget(hbox,row,row,1,3)
row += 1
if self.showlabel:
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.labelcheckbox = QRadioButton(i18n("by label"),hbox)
self.connect(self.labelcheckbox,SIGNAL("clicked()"), \
self.slotLabelCheckboxClicked)
self.labellineedit = KLineEdit(hbox)
grid.addMultiCellWidget(hbox,row,row,1,3)
row += 1
else:
if self.showdevice:
label = QLabel(i18n("Device:"),self)
grid.addWidget(label,row,0)
self.devicelineedit = KLineEdit(self)
grid.addMultiCellWidget(self.devicelineedit,row,row,1,3)
row += 1
example = QLabel(self.deviceexample,self)
grid.addWidget(example,row,1)
if self.showuuid:
label = QLabel(i18n("Device UUID:"),self)
grid.addWidget(label,row,0)
self.uuidlineedit = KLineEdit(self)
grid.addMultiCellWidget(self.uuidlineedit,row,row,1,3)
row += 1
if self.showlabel:
label = QLabel(i18n("Device Label:"),self)
grid.addWidget(label,row,0)
self.labellineedit = KLineEdit(self)
grid.addMultiCellWidget(self.labellineedit,row,row,1,3)
row += 1
label = QLabel(i18n("Options:"),self)
grid.addWidget(label,row,0)
self.optionslineedit = KLineEdit(self)
grid.addMultiCellWidget(self.optionslineedit,row,row,1,3)
row += 1
if self.showfs_freq:
label = QLabel(i18n("fs_freq:"),self)
grid.addWidget(label,row,0)
self.fsfreqspinbox = KIntSpinBox (0,1000,1,0,10,self)
grid.addWidget(self.fsfreqspinbox,row,1)
if self.showfs_passno:
label = QLabel(i18n("fs_passno:"),self)
grid.addWidget(label,row,2)
self.fspassnospinbox = KIntSpinBox (0,1000,1,0,10,self)
grid.addWidget(self.fspassnospinbox,row,3)
row += 1
grid.addWidget(QWidget(self),row,0)
for x in range(grid.numRows()):
grid.setRowStretch(x,0)
grid.setRowStretch(grid.numRows()-1,1)
########################################################################
def displayMountEntry(self,entry):
global allowuuid, allowlabel
if self.showmountpoint:
self.mountpointlineedit.setText(entry.getMountPoint())
uuid = entry.getUUID()
if entry.getDevice() == "" and uuid != "":
device = microhal.getDeviceByUUID(uuid)
self.devicelineedit.setText(uuid)
else:
if self.showdevice:
self.devicelineedit.setText(entry.getDevice())
if self.showuuid:
if entry.getUUID()!="":
self.uuidlineedit.setText(entry.getUUID())
if self.showlabel:
if entry.getLabel()!="":
self.labellineedit.setText(entry.getLabel())
if entry.getUseAsDevice() == "devicenode":
if self.showdevice:
self.devicelineedit.setEnabled(True)
self.devicecheckbox.setChecked(True)
if self.showuuid:
self.uuidcheckbox.setChecked(False)
self.uuidlineedit.setEnabled(False)
if self.showlabel:
self.labelcheckbox.setChecked(False)
self.labellineedit.setEnabled(False)
elif entry.getUseAsDevice() == "label":
if self.showlabel:
self.labellineedit.setEnabled(True)
self.labelcheckbox.setChecked(True)
if self.showdevice:
self.devicelineedit.setEnabled(False)
self.devicecheckbox.setChecked(False)
if self.showuuid:
self.uuidlineedit.setEnabled(False)
self.uuidcheckbox.setChecked(False)
elif entry.getUseAsDevice() == "uuid":
if self.showdevice:
self.devicecheckbox.setChecked(False)
self.devicelineedit.setEnabled(False)
if self.showlabel:
self.labelcheckbox.setChecked(False)
self.labellineedit.setEnabled(False)
if self.showuuid:
self.uuidlineedit.setEnabled(True)
self.uuidcheckbox.setChecked(True)
## if allowlabel:
## self.labellineedit.setText(entry.getLabel())
## if allowuuid:
## self.uuidlineedit.setText(entry.getUUID())
## self.devicelineedit.setText(entry.getDevice())
self.optionslineedit.setText(entry.getExtraOptions())
if self.showfs_freq:
self.fsfreqspinbox.setValue(entry.getFSFreq())
if self.showfs_passno:
self.fspassnospinbox.setValue(entry.getFSPassno())
########################################################################
def undisplayMountEntry(self,entry):
if self.showmountpoint:
entry.setMountPoint( unicode(self.mountpointlineedit.text()) )
if self.showdevice:
entry.setDevice( unicode(self.devicelineedit.text()) )
if self.showuuid and self.showdevice:
if self.devicecheckbox.isChecked():
entry.setUUID(None)
else:
entry.setUUID( unicode(self.uuidlineedit.text()) )
if self.showlabel and self.showdevice:
if self.devicecheckbox.isChecked():
entry.setLabel(None)
else:
entry.setLabel( unicode(self.labellineedit.text()) )
if allowuuid and self.showuuid:
if self.uuidcheckbox.isChecked():
entry.setUseAsDevice("uuid")
if allowlabel and self.showlabel:
if self.labelcheckbox.isChecked():
entry.setUseAsDevice("label")
if self.showdevice:
if self.devicecheckbox.isChecked():
entry.setUseAsDevice("devicenode")
entry.setExtraOptions( unicode(self.optionslineedit.text()) )
if self.showfs_freq:
entry.setFSFreq(self.fsfreqspinbox.value())
if self.showfs_passno:
entry.setFSPassno(self.fspassnospinbox.value())
########################################################################
def slotBrowseMountPointClicked(self):
fileurl = KURL()
fileurl.setPath(self.mountpointlineedit.text())
self.mountpointdialog.setCurrentURL(fileurl)
if self.mountpointdialog.exec_loop()==QDialog.Accepted:
self.mountpointlineedit.setText(self.mountpointdialog.url().path())
########################################################################
def slotDeviceCheckboxClicked(self):
self.uuidcheckbox.setChecked(False)
self.labelcheckbox.setChecked(False)
self.devicelineedit.setEnabled(True)
self.uuidlineedit.setEnabled(False)
self.labellineedit.setEnabled(False)
########################################################################
def slotUUIDCheckboxClicked(self):
if self.uuidlineedit.text() == "":
label = microhal.getUUIDByDevice(unicode(self.devicelineedit.text()))
self.uuidlineedit.setText(label)
self.devicecheckbox.setChecked(False)
self.devicelineedit.setEnabled(False)
self.uuidlineedit.setEnabled(True)
self.labelcheckbox.setChecked(False)
self.labellineedit.setEnabled(False)
def slotLabelCheckboxClicked(self):
if self.labellineedit.text() == "":
label = microhal.getLabelByDevice(unicode(self.devicelineedit.text()))
self.labellineedit.setText(label)
self.uuidcheckbox.setChecked(False)
self.devicelineedit.setEnabled(False)
self.uuidlineedit.setEnabled(False)
self.labelcheckbox.setChecked(True)
self.labellineedit.setEnabled(True)
############################################################################
class MountEntryDialogOptionsCommonUnix(MountEntryDialogOptions):
########################################################################
def __init__(self,parent):
MountEntryDialogOptions.__init__(self,parent)
self.advanceddialog = MountEntryAdvancedCommonUnixDialog(None)
########################################################################
def _fillPage(self):
row = 0
grid = QGridLayout(self,1,2)
grid.setSpacing(KDialog.spacingHint())
grid.setColStretch(0,0)
grid.setRowStretch(6,1)
label = QLabel(i18n("Mount Point:"),self)
grid.addWidget(label,row,0)
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.mountpointlineedit = KLineEdit(hbox)
hbox.setStretchFactor(self.mountpointlineedit,1)
#self.connect(self.homediredit, SIGNAL("textChanged(const QString &)"), self.slotHomeDirChanged)
self.mountpointbutton = KPushButton(i18n("Browse..."),hbox)
hbox.setStretchFactor(self.mountpointbutton,0)
self.connect(self.mountpointbutton,SIGNAL("clicked()"), \
self.slotBrowseMountPointClicked)
grid.addWidget(hbox,row,1)
row += 1
if self.showuuid or self.showlabel:
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
label = QLabel(i18n("Device:"),self)
grid.addWidget(label,row,0)
self.devicecheckbox = QRadioButton(i18n("by name"),hbox)
self.connect(self.devicecheckbox,SIGNAL("clicked()"), \
self.slotDeviceCheckboxClicked)
self.devicelineedit = KLineEdit(hbox)
grid.addWidget(hbox,row,1)
row += 1
example = QLabel(self.deviceexample,self)
grid.addWidget(example,row,1)
row += 1
if self.showuuid:
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.uuidcheckbox = QRadioButton(i18n("by UUID"),hbox)
self.connect(self.uuidcheckbox,SIGNAL("clicked()"), \
self.slotUUIDCheckboxClicked)
self.uuidlineedit = KLineEdit(hbox)
grid.addWidget(hbox,row,1)
row += 1
if self.showlabel:
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.labelcheckbox = QRadioButton(i18n("by label"),hbox)
self.connect(self.labelcheckbox,SIGNAL("clicked()"), \
self.slotLabelCheckboxClicked)
self.labellineedit = KLineEdit(hbox)
grid.addWidget(hbox,row,1)
row += 1
else:
label = QLabel(i18n("Device:"),self)
grid.addWidget(label,row,0)
self.devicelineedit = KLineEdit(self)
grid.addWidget(self.devicelineedit,row,1)
row += 1
example = QLabel(self.deviceexample,self)
grid.addWidget(example,row,1)
row += 1
self.autocheckbox = QCheckBox(i18n("Enable at start up"),self)
grid.addWidget(self.autocheckbox,row,1)
row += 1
self.writeablecheckbox = QCheckBox(i18n("Writeable"),self)
grid.addWidget(self.writeablecheckbox,row,1)
row += 1
label = QLabel(i18n("Mount Permission:"),self)
grid.addWidget(label,row,0)
self.usermountcombobox = KComboBox(self)
self.usermountcombobox.insertItem(i18n("Root user only may enable/disable"))
self.usermountcombobox.insertItem(i18n("One user at a time may enable/disable"))
self.usermountcombobox.insertItem(i18n("Any user may enable/disable anytime"))
self.usermountcombobox.insertItem(i18n("Device owner may enable/disable"))
grid.addWidget(self.usermountcombobox,row,1)
row += 1
#grid.addWidget(,9,0)
button = KPushButton(i18n("Advanced..."),self)
button.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed)
self.connect(button,SIGNAL("clicked()"),self.slotAdvancedClicked)
grid.addWidget(button,row,1,Qt.AlignRight)
row += 1
grid.addWidget(QWidget(self),row,0)
for x in range(grid.numRows()):
grid.setRowStretch(x,0)
grid.setRowStretch(grid.numRows()-1,1)
########################################################################
def displayMountEntry(self,entry):
self.devicelineedit.setText(entry.getDevice())
if self.showuuid:
if entry.getUUID()!="":
self.uuidlineedit.setText(entry.getUUID())
if self.showlabel:
if entry.getLabel()!="":
self.labellineedit.setText(entry.getLabel())
if entry.getUseAsDevice() == "devicenode":
self.devicelineedit.setEnabled(True)
self.devicecheckbox.setChecked(True)
self.uuidcheckbox.setChecked(False)
self.uuidlineedit.setEnabled(False)
self.labelcheckbox.setChecked(False)
self.labellineedit.setEnabled(False)
elif entry.getUseAsDevice() == "label":
self.labellineedit.setEnabled(True)
self.labelcheckbox.setChecked(True)
self.devicelineedit.setEnabled(False)
self.devicecheckbox.setChecked(False)
self.uuidlineedit.setEnabled(False)
self.uuidcheckbox.setChecked(False)
elif entry.getUseAsDevice() == "uuid":
self.devicecheckbox.setChecked(False)
self.devicelineedit.setEnabled(False)
self.labelcheckbox.setChecked(False)
self.labellineedit.setEnabled(False)
self.uuidlineedit.setEnabled(True)
self.uuidcheckbox.setChecked(True)
self.devicelineedit.setText(entry.getDevice())
self.mountpointlineedit.setText(entry.getMountPoint())
self.options = entry.getExtraOptions()
self.fsfreq = entry.getFSFreq()
self.fspassno = entry.getFSPassno()
self.autocheckbox.setChecked(entry.getMountAtBoot())
self.writeablecheckbox.setChecked(entry.getWritable())
self.accesstime = entry.getAtime()
self.allowexecutable = entry.getAllowExecutables()
self.allowsuid = entry.getSUID()
self.usedevpoints = entry.getUseDevPoints()
self.usermountcombobox.setCurrentItem(entry.getAllowUserMount())
########################################################################
def undisplayMountEntry(self,entry):
entry.setDevice( unicode(self.devicelineedit.text()) )
if self.showuuid:
if self.devicecheckbox.isChecked() or self.labelcheckbox.isChecked():
entry.setUUID(None)
else:
entry.setUUID( unicode(self.uuidlineedit.text()) )
if self.showlabel:
if self.devicecheckbox.isChecked() or self.uuidcheckbox.isChecked():
entry.setLabel(None)
else:
entry.setLabel( unicode(self.labellineedit.text()) )
if not self.showlabel and not self.showuuid:
if self.uuidcheckbox.isChecked() or self.labelcheckbox.isChecked():
entry.setLabel(None)
else:
entry.setLabel( unicode(self.devicelineedit.text()) )
if allowuuid:
if self.uuidcheckbox.isChecked():
entry.setUseAsDevice("uuid")
if allowlabel:
if self.labelcheckbox.isChecked():
entry.setUseAsDevice("label")
if self.devicecheckbox.isChecked():
entry.setUseAsDevice("devicenode")
entry.setMountPoint( unicode(self.mountpointlineedit.text()) )
entry.setExtraOptions(self.options)
entry.setFSFreq(self.fsfreq)
entry.setFSPassno(self.fspassno)
entry.setAtime(self.accesstime)
entry.setMountAtBoot(self.autocheckbox.isChecked())
entry.setWritable(self.writeablecheckbox.isChecked())
entry.setUseDevPoints(self.usedevpoints)
entry.setAllowExecutable(self.allowexecutable)
entry.setSUID(self.allowsuid)
entry.setAllowUserMount(self.usermountcombobox.currentItem())
########################################################################
def slotAdvancedClicked(self):
(self.accesstime, self.allowexecutable, self.allowsuid, self.usedevpoints, self.options, self.fsfreq,
self.fspassno)\
= self.advanceddialog.do(self.accesstime, self.allowexecutable, self.allowsuid, self.usedevpoints,
self.options, self.fsfreq, self.fspassno)
########################################################################
def slotDeviceCheckboxClicked(self):
self.uuidcheckbox.setChecked(False)
self.devicelineedit.setEnabled(True)
self.labelcheckbox.setChecked(False)
self.labellineedit.setEnabled(False)
self.uuidlineedit.setEnabled(False)
########################################################################
def slotUUIDCheckboxClicked(self):
if self.uuidlineedit.text() == "":
label = microhal.getUUIDByDevice(unicode(self.devicelineedit.text()))
self.uuidlineedit.setText(label)
self.devicecheckbox.setChecked(False)
self.devicelineedit.setEnabled(False)
self.labelcheckbox.setChecked(False)
self.labellineedit.setEnabled(False)
self.uuidlineedit.setEnabled(True)
def slotLabelCheckboxClicked(self):
if self.labellineedit.text() == "":
label = microhal.getLabelByDevice(unicode(self.devicelineedit.text()))
self.labellineedit.setText(label)
self.devicecheckbox.setChecked(False)
self.devicelineedit.setEnabled(False)
self.uuidcheckbox.setChecked(False)
self.uuidlineedit.setEnabled(False)
self.labellineedit.setEnabled(True)
############################################################################
class MountEntryDialogOptionsSys(MountEntryDialogOptions):
########################################################################
def __init__(self,parent):
MountEntryDialogOptions.__init__(self,parent,True,False,False,False,False,False)
############################################################################
class MountEntryDialogOptionsSwap(MountEntryDialogOptions):
########################################################################
def __init__(self,parent):
MountEntryDialogOptions.__init__(self,parent,False,True,False,False)
class MountEntryDialogOptionsNfs(MountEntryDialogOptionsCommonUnix):
deviceexample = i18n("(for example 192.168.1.66:/export)")
############################################################################
class MountEntryDialogOptionsVFAT(MountEntryDialogOptions):
########################################################################
def __init__(self,parent):
MountEntryDialogOptions.__init__(self,parent)
self.advanceddialog = MountEntryAdvancedPlainDialog(None)
self.updatinggui= False
########################################################################
def _fillPage(self):
global allowuuid, allowlabel
row = 0
grid = QGridLayout(self,11,2)
grid.setSpacing(KDialog.spacingHint())
grid.setColStretch(0,0)
grid.setColStretch(2,0)
grid.setRowStretch(10,1)
label = QLabel(i18n("Mount Point:"),self)
grid.addWidget(label,row,0)
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.mountpointlineedit = KLineEdit(hbox)
hbox.setStretchFactor(self.mountpointlineedit,1)
#self.connect(self.homediredit, SIGNAL("textChanged(const QString &)"), self.slotHomeDirChanged)
self.mountpointbutton = KPushButton(i18n("Browse..."),hbox)
hbox.setStretchFactor(self.mountpointbutton,0)
self.connect(self.mountpointbutton,SIGNAL("clicked()"),self.slotBrowseMountPointClicked)
grid.addMultiCellWidget(hbox,row,row,1,3)
row += 1
if allowuuid or allowlabel:
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
label = QLabel(i18n("Device:"),self)
grid.addWidget(label,row,0)
self.devicecheckbox = QRadioButton(i18n("by name"),hbox)
self.connect(self.devicecheckbox,SIGNAL("clicked()"), \
self.slotDeviceCheckboxClicked)
self.devicelineedit = KLineEdit(hbox)
grid.addWidget(hbox,row,1)
row += 1
example = QLabel(self.deviceexample,self)
grid.addWidget(example,row,1)
row += 1
if allowuuid and self.showuuid:
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.uuidcheckbox = QRadioButton(i18n("by UUID"),hbox)
self.connect(self.uuidcheckbox,SIGNAL("clicked()"), \
self.slotUUIDCheckboxClicked)
self.uuidlineedit = KLineEdit(hbox)
grid.addWidget(hbox,row,1)
row += 1
if allowlabel and self.showlabel:
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.labelcheckbox = QRadioButton(i18n("by label"),hbox)
self.connect(self.labelcheckbox,SIGNAL("clicked()"), \
self.slotLabelCheckboxClicked)
self.labellineedit = KLineEdit(hbox)
grid.addWidget(hbox,row,1)
row += 1
else:
label = QLabel(i18n("Device:"),self)
grid.addWidget(label,row,0)
self.devicelineedit = KLineEdit(self)
grid.addMultiCellWidget(self.devicelineedit,row,row,1,3)
row += 1
example = QLabel(self.deviceexample,self)
grid.addWidget(example,row,1)
row += 1
self.autocheckbox = QCheckBox(i18n("Enable at start up"),self)
grid.addMultiCellWidget(self.autocheckbox,row,row,1,3)
row += 1
# Security & Safety line.
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
tmplabel = QLabel(hbox)
tmplabel.setPixmap(UserIcon("hi16-lock"))
hbox.setStretchFactor(tmplabel,0)
tmplabel = QLabel(hbox)
tmplabel.setText(i18n("Security & Safety"))
hbox.setStretchFactor(tmplabel,0)
sep = KSeparator(KSeparator.Horizontal,hbox)
hbox.setStretchFactor(sep,1)
grid.addMultiCellWidget(hbox,row,row,0,3)
row += 1
self.writeablecheckbox = QCheckBox(i18n("Writeable"),self)
grid.addMultiCellWidget(self.writeablecheckbox,row,row,1,3)
row += 1
label = QLabel(i18n("Files belong to user:"),self)
grid.addWidget(label,row,0)
self.uidcombobox = UserComboBox(self)
grid.addMultiCellWidget(self.uidcombobox,row,row,1,3)
row += 1
label = QLabel(i18n("Files belong to group:"),self)
grid.addWidget(label,row,0)
self.gidcombobox = GroupComboBox(self)
grid.addMultiCellWidget(self.gidcombobox,row,row,1,3)
row += 1
label = QLabel(i18n("Mount Permission:"),self)
grid.addWidget(label,row,0)
self.usermountcombobox = KComboBox(self)
self.usermountcombobox.insertItem(i18n("Root user only may enable/disable"))
self.usermountcombobox.insertItem(i18n("One user at a time may enable/disable"))
self.usermountcombobox.insertItem(i18n("Any user may enable/disable anytime"))
self.usermountcombobox.insertItem(i18n("Device owner may enable/disable"))
grid.addMultiCellWidget(self.usermountcombobox,row,row,1,3)
row += 1
self.suppresspermissionerrorcheckbox = QCheckBox(i18n("Suppress permission errors"),self)
grid.addMultiCellWidget(self.suppresspermissionerrorcheckbox,row,row,1,3)
row += 1
row += 1
button = KPushButton(i18n("Advanced..."),self)
button.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed)
self.connect(button,SIGNAL("clicked()"),self.slotAdvancedClicked)
grid.addMultiCellWidget(button,row,row,1,3,Qt.AlignRight)
########################################################################
def displayMountEntry(self,entry):
global allowuuid, allowlabel
uuid = entry.getUUID()
if entry.getDevice() == "" and uuid != "":
device = microhal.getDeviceByUUID(uuid)
self.devicelineedit.setText(uuid)
else:
self.devicelineedit.setText(entry.getDevice())
if allowuuid:
self.uuidlineedit.setText(uuid)
if entry.getUUID()!="":
self.uuidlineedit.setEnabled(True)
self.devicelineedit.setEnabled(False)
self.devicecheckbox.setChecked(False)
self.uuidcheckbox.setChecked(True)
else:
self.devicelineedit.setEnabled(True)
self.uuidlineedit.setEnabled(False)
self.devicecheckbox.setChecked(True)
self.uuidcheckbox.setChecked(False)
if allowlabel: # If the filesystem has a label override the UUID settings
self.labellineedit.setText(entry.getLabel())
if entry.getLabel()!="":
self.labellineedit.setEnabled(True)
self.devicelineedit.setEnabled(False)
self.devicecheckbox.setChecked(False)
self.labelcheckbox.setChecked(True)
self.uuidlineedit.setEnabled(False)
self.uuidcheckbox.setChecked(False)
else:
if entry.getUUID()!="":
self.uuidlineedit.setEnabled(True)
self.devicelineedit.setEnabled(False)
self.devicecheckbox.setChecked(False)
self.uuidcheckbox.setChecked(True)
else:
self.devicelineedit.setEnabled(True)
self.uuidlineedit.setEnabled(False)
self.devicecheckbox.setChecked(True)
self.uuidcheckbox.setChecked(False)
if allowlabel:
self.labellineedit.setText(entry.getLabel())
if allowuuid:
self.uuidlineedit.setText(entry.getUUID())
self.devicelineedit.setText(entry.getDevice())
self.mountpointlineedit.setText(entry.getMountPoint())
self.options = entry.getExtraOptions()
self.fsfreq = entry.getFSFreq()
self.fspassno = entry.getFSPassno()
self.writeablecheckbox.setChecked(entry.getWritable())
self.autocheckbox.setChecked(entry.getMountAtBoot())
self.usermountcombobox.setCurrentItem(entry.getAllowUserMount())
self.uidcombobox.setUID(entry.getUID())
self.gidcombobox.setGID(entry.getGID())
self.suppresspermissionerrorcheckbox.setChecked(entry.getSuppressPermissionErrors())
########################################################################
def undisplayMountEntry(self,entry):
global allowuuid, allowlabel
if allowuuid:
if self.devicecheckbox.isChecked():
entry.setUUID(None)
else:
if allowlabel:
if self.labelcheckbox.isChecked():
entry.setLabel( unicode(self.labellineedit.text()) )
else:
entry.setUUID( unicode(self.uuidlineedit.text()) )
else:
entry.setUUID( unicode(self.uuidlineedit.text()) )
if allowlabel:
if self.devicecheckbox.isChecked():
entry.setLabel(None)
else:
if allowuuid:
if self.uuidcheckbox.isChecked():
entry.setUUID( unicode(self.uuidlineedit.text()) )
else:
entry.setLabel( unicode(self.labellineedit.text()) )
else:
entry.setLabel( unicode(self.labellineedit.text()) )
entry.setDevice( unicode(self.devicelineedit.text()) )
entry.setMountPoint( unicode(self.mountpointlineedit.text()) )
entry.setExtraOptions(self.options)
entry.setFSFreq(self.fsfreq)
entry.setFSPassno(self.fspassno)
entry.setMountAtBoot(self.autocheckbox.isChecked())
entry.setWritable(self.writeablecheckbox.isChecked())
entry.setAllowUserMount(self.usermountcombobox.currentItem())
entry.setUID(self.uidcombobox.UID())
entry.setGID(self.gidcombobox.GID())
entry.setSuppressPermissionErrors(self.suppresspermissionerrorcheckbox.isChecked())
########################################################################
def slotAdvancedClicked(self):
(self.options, self.fsfreq, self.fspassno)\
= self.advanceddialog.do(self.options, self.fsfreq, self.fspassno)
########################################################################
def slotDeviceCheckboxClicked(self):
self.uuidcheckbox.setChecked(False)
self.devicelineedit.setEnabled(True)
self.uuidlineedit.setEnabled(False)
########################################################################
def slotUUIDCheckboxClicked(self):
if self.uuidlineedit.text() == "":
label = microhal.getUUIDByDevice(unicode(self.devicelineedit.text()))
self.uuidlineedit.setText(label)
self.devicecheckbox.setChecked(False)
self.devicelineedit.setEnabled(False)
self.uuidlineedit.setEnabled(True)
############################################################################
class MountEntryDialogOptionsSMB(MountEntryDialogOptions):
########################################################################
def __init__(self,parent):
MountEntryDialogOptions.__init__(self,parent)
self.advanceddialog = MountEntryAdvancedPlainDialog(None)
self.updatinggui= False
########################################################################
def _fillPage(self):
grid = QGridLayout(self,14,4)
grid.setSpacing(KDialog.spacingHint())
grid.setColStretch(0,0)
grid.setColStretch(2,0)
grid.setRowStretch(12,1)
label = QLabel(i18n("Mount Point:"),self)
grid.addWidget(label,0,0)
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.mountpointlineedit = KLineEdit(hbox)
hbox.setStretchFactor(self.mountpointlineedit,1)
#self.connect(self.homediredit, SIGNAL("textChanged(const QString &)"), self.slotHomeDirChanged)
self.mountpointbutton = KPushButton(i18n("Browse..."),hbox)
hbox.setStretchFactor(self.mountpointbutton,0)
self.connect(self.mountpointbutton,SIGNAL("clicked()"),self.slotBrowseMountPointClicked)
grid.addMultiCellWidget(hbox,0,0,1,3)
label = QLabel(i18n("Network Share:"),self)
grid.addWidget(label,1,0)
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
self.devicelineedit = KLineEdit(hbox)
hbox.setStretchFactor(self.devicelineedit,1)
self.devicelinebutton = KPushButton(i18n("Scan..."),hbox)
hbox.setStretchFactor(self.devicelinebutton,0)
self.connect(self.devicelinebutton,SIGNAL("clicked()"),self.slotBrowseDeviceLineClicked)
grid.addMultiCellWidget(hbox,1,1,1,3)
# Connect as:
connectaslabel = QLabel(self)
connectaslabel.setText(i18n("Connect as:"))
grid.addWidget(connectaslabel,2,0)
self.guestradio = QRadioButton(self)
self.guestradio.setChecked(True)
grid.addWidget(self.guestradio,2,1)
tmplabel = QLabel(self)
tmplabel.setText(i18n("Guest"))
grid.addMultiCellWidget(tmplabel,2,2,2,3)
self.connect(self.guestradio,SIGNAL("stateChanged(int)"),self.slotGuestRadioClicked)
self.userradio = QRadioButton(self)
grid.addWidget(self.userradio,3,1)
tmplabel = QLabel(self)
tmplabel.setText(i18n("Username:"))
grid.addWidget(tmplabel,3,2)
self.connect(self.userradio,SIGNAL("stateChanged(int)"),self.slotUserRadioClicked)
self.usernameedit = KLineEdit(self)
grid.addWidget(self.usernameedit,3,3)
tmplabel = QLabel(self)
tmplabel.setText(i18n("Password:"))
grid.addWidget(tmplabel,4,2)
self.passwordedit = KLineEdit(self)
grid.addWidget(self.passwordedit,4,3)
self.autocheckbox = QCheckBox(i18n("Enable at start up"),self)
grid.addMultiCellWidget(self.autocheckbox,5,5,1,3)
# Security & Safety line.
hbox = QHBox(self)
hbox.setSpacing(KDialog.spacingHint())
tmplabel = QLabel(hbox)
tmplabel.setPixmap(UserIcon("hi16-lock"))
hbox.setStretchFactor(tmplabel,0)
tmplabel = QLabel(hbox)
tmplabel.setText(i18n("Security & Safety"))
hbox.setStretchFactor(tmplabel,0)
sep = KSeparator(KSeparator.Horizontal,hbox)
hbox.setStretchFactor(sep,1)
grid.addMultiCellWidget(hbox,6,6,0,3)
self.writeablecheckbox = QCheckBox(i18n("Writeable"),self)
grid.addMultiCellWidget(self.writeablecheckbox,7,7,1,3)
label = QLabel(i18n("Files belong to user:"),self)
grid.addWidget(label,8,0)
self.uidcombobox = UserComboBox(self)
grid.addMultiCellWidget(self.uidcombobox,8,8,1,3)
label = QLabel(i18n("Files belong to group:"),self)
grid.addWidget(label,9,0)
self.gidcombobox = GroupComboBox(self)
grid.addMultiCellWidget(self.gidcombobox,9,9,1,3)
label = QLabel(i18n("Mount Permission:"),self)
grid.addWidget(label,10,0)
self.usermountcombobox = KComboBox(self)
self.usermountcombobox.insertItem(i18n("Root user only may enable/disable"))
self.usermountcombobox.insertItem(i18n("One user at a time may enable/disable"))
self.usermountcombobox.insertItem(i18n("Any user may enable/disable anytime"))
self.usermountcombobox.insertItem(i18n("Device owner may enable/disable"))
grid.addMultiCellWidget(self.usermountcombobox,10,10,1,3)
button = KPushButton(i18n("Advanced..."),self)
button.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed)
self.connect(button,SIGNAL("clicked()"),self.slotAdvancedClicked)
grid.addMultiCellWidget(button,13,13,1,3,Qt.AlignRight)
self.selectsmbdialog = None
########################################################################
def slotBrowseDeviceLineClicked(self):
if self.updatinggui:
return
self.updatinggui = True
if self.selectsmbdialog is None:
self.selectsmbdialog = SMBShareSelectDialog(None)
# This just converts a \\zootv\data\ share name to smb:/zootv/data
parts = [x.replace("/",'\\') for x in unicode(self.devicelineedit.text()).split('\\') if x!=""]
oldurl = u"smb:/"+("/".join(parts) )
urlobj = KURL(oldurl)
if self.userradio.isChecked():
urlobj.setUser(self.usernameedit.text())
urlobj.setPass(self.passwordedit.text())
newurlobj = self.selectsmbdialog.choose(urlobj)
# This just converts smb:/zootv/data to \\zootv\data.
plainurl = KURL(newurlobj)
plainurl.setUser(QString.null)
plainurl.setPass(QString.null)
parts = [x.replace('\\',"/") for x in unicode(plainurl.url())[4:].split("/") if x !=""]
#convert the first part to an IP address
nmboutput = subprocess.Popen(["nmblookup",parts[0]], stdout=subprocess.PIPE).stdout
nmboutput.readline()
ipaddress = nmboutput.readline().split(" ")[0]
parts[0] = ipaddress
self.devicelineedit.setText(r'\\'+('\\'.join(parts)))
if not newurlobj.hasUser():
self.guestradio.setChecked(True)
self.userradio.setChecked(False)
self.passwordedit.setEnabled(False)
self.usernameedit.setEnabled(False)
self.usernameedit.setText("")
self.passwordedit.setText("")
else:
self.guestradio.setChecked(False)
self.userradio.setChecked(True)
self.passwordedit.setEnabled(True)
self.usernameedit.setEnabled(True)
self.usernameedit.setText(newurlobj.user())
self.passwordedit.setText(newurlobj.pass_())
self.updatinggui = False
########################################################################
def displayMountEntry(self,entry):
self.devicelineedit.setText(entry.getDevice())
self.mountpointlineedit.setText(entry.getMountPoint())
self.options = entry.getExtraOptions()
self.fsfreq = entry.getFSFreq()
self.fspassno = entry.getFSPassno()
self.writeablecheckbox.setChecked(entry.getWritable())
self.autocheckbox.setChecked(entry.getMountAtBoot())
self.usermountcombobox.setCurrentItem(entry.getAllowUserMount())
self.uidcombobox.setUID(entry.getUID())
self.gidcombobox.setGID(entry.getGID())
if entry.getUsername() is None:
self.guestradio.setChecked(True)
self.userradio.setChecked(False)
self.passwordedit.setEnabled(False)
self.usernameedit.setEnabled(False)
self.usernameedit.setText("")
self.passwordedit.setText("")
else:
self.guestradio.setChecked(False)
self.userradio.setChecked(True)
self.passwordedit.setEnabled(True)
self.usernameedit.setEnabled(True)
self.usernameedit.setText(entry.getUsername())
self.passwordedit.setText(entry.getPassword())
########################################################################
def undisplayMountEntry(self,entry):
entry.setDevice( unicode(self.devicelineedit.text()) )
entry.setMountPoint( unicode(self.mountpointlineedit.text()) )
entry.setExtraOptions(self.options)
entry.setFSFreq(self.fsfreq)
entry.setFSPassno(self.fspassno)
entry.setMountAtBoot(self.autocheckbox.isChecked())
entry.setWritable(self.writeablecheckbox.isChecked())
entry.setAllowUserMount(self.usermountcombobox.currentItem())
entry.setUID(self.uidcombobox.UID())
entry.setGID(self.gidcombobox.GID())
if self.guestradio.isChecked():
entry.setUsername(None)
entry.setPassword(None)
else:
entry.setUsername( unicode(self.usernameedit.text()) )
entry.setPassword( unicode(self.passwordedit.text()) )
########################################################################
def slotAdvancedClicked(self):
(self.options, self.fsfreq, self.fspassno)\
= self.advanceddialog.do(self.options, self.fsfreq, self.fspassno)
########################################################################
def slotGuestRadioClicked(self,state):
if self.updatinggui:
return
self.updatinggui = True
if state==QButton.Off:
self.guestradio.setChecked(True)
self.userradio.setChecked(False)
self.passwordedit.setEnabled(False)
self.usernameedit.setEnabled(False)
self.updatinggui = False
########################################################################
def slotUserRadioClicked(self,state):
if self.updatinggui:
return
self.updatinggui = True
if state==QButton.Off:
self.userradio.setChecked(True)
self.guestradio.setChecked(False)
self.passwordedit.setEnabled(True)
self.usernameedit.setEnabled(True)
self.updatinggui = False
############################################################################
class ROListBoxItem(QListBoxPixmap):
"""A read-only ListBox item that also uses the 'alternate' background colour
as background.
"""
def __init__(self,listbox,pix,text):
QListBoxPixmap.__init__(self,listbox,pix,text)
self.setSelectable(False)
def paint(self,p):
boldfont = QFont(p.font())
boldfont.setWeight(QFont.Bold)
p.setFont(boldfont)
p.setBackgroundColor(TDEGlobalSettings.alternateBackgroundColor())
p.eraseRect(0,0,self.listBox().width(),self.height(self.listBox()))
QListBoxPixmap.paint(self,p)
############################################################################
class MountEntryDialog(KDialogBase):
MountTypeEditorsDisk = {
'ext2' : MountEntryDialogOptionsCommonUnix,
'ext3' : MountEntryDialogOptionsCommonUnix,
'ext4' : MountEntryDialogOptionsCommonUnix,
'reiserfs' : MountEntryDialogOptionsCommonUnix,
'reiser4' : MountEntryDialogOptionsCommonUnix,
'xfs' : MountEntryDialogOptionsCommonUnix,
'jfs' : MountEntryDialogOptionsCommonUnix,
'vfat' : MountEntryDialogOptionsVFAT,
'ntfs' : MountEntryDialogOptionsVFAT,
'hfsplus' : MountEntryDialogOptionsVFAT,
'udf' : MountEntryDialogOptions,
'iso9660' : MountEntryDialogOptions,
}
MountTypeEditorsNetwork = {
'nfs' : MountEntryDialogOptionsNfs,
'cifs' : MountEntryDialogOptionsSMB,
}
MountTypeEditorsSystem = {
'proc' : MountEntryDialogOptionsSys,
'sysfs' : MountEntryDialogOptionsSys,
'rootfs' : MountEntryDialogOptions,
'bdev' : MountEntryDialogOptions,
'sockfs' : MountEntryDialogOptions,
'tmpfs' : MountEntryDialogOptions,
'shm' : MountEntryDialogOptions,
'pipefs' : MountEntryDialogOptions,
'ramfs' : MountEntryDialogOptionsSys,
'devfs' : MountEntryDialogOptions,
'devpts' : MountEntryDialogOptionsSys,
'auto' : MountEntryDialogOptionsCommonUnix,
'usbdevfs' : MountEntryDialogOptions,
'procbususb' : MountEntryDialogOptions,
'usbfs' : MountEntryDialogOptions,
'supermount' : MountEntryDialogOptions,
'swap' : MountEntryDialogOptionsSwap
}
########################################################################
def __init__(self,parent):
KDialogBase.__init__(self,parent,None,True,"Configuration",KDialogBase.Ok|KDialogBase.Cancel,
KDialogBase.Cancel)
self.updatingGUI = True
# Maps MountEntry classes to MountEntryDialogOptions objects
self.mountTypeToOptionWidget = {}
# Maps indexes in the combobox to mounttypes
self.comboIndexToMountType = []
self.currentOptionWidget = None
self.topvbox = QVBox(self)
self.setMainWidget(self.topvbox)
self.topvbox.setSpacing(self.spacingHint())
hb = QHBox(self.topvbox)
hb.setSpacing(self.spacingHint())
self.topvbox.setStretchFactor(hb,0)
label = QLabel(i18n("Type:"),hb)
hb.setStretchFactor(label,0)
self.mounttypecombo = KComboBox(hb)
# Disk types
ROListBoxItem(self.mounttypecombo.listBox(),UserIcon("hi16-hdd"),i18n("Disk Filesystems"))
self.comboIndexToMountType.append(None)
items = self.MountTypeEditorsDisk.keys()
items.sort()
for mounttype in items:
self.mounttypecombo.insertItem(MountEntry.getMountTypeLongName(mounttype))
self.comboIndexToMountType.append(mounttype)
# Network types
ROListBoxItem(self.mounttypecombo.listBox(),UserIcon("hi16-network"),i18n("Network Filesystems"))
self.comboIndexToMountType.append(None)
items = self.MountTypeEditorsNetwork.keys()
items.sort()
for mounttype in items:
self.mounttypecombo.insertItem(MountEntry.getMountTypeLongName(mounttype))
self.comboIndexToMountType.append(mounttype)
# System types
ROListBoxItem(self.mounttypecombo.listBox(),UserIcon("hi16-blockdevice"),i18n("Operating System"))
self.comboIndexToMountType.append(None)
items = self.MountTypeEditorsSystem.keys()
items.sort()
for mounttype in items:
self.mounttypecombo.insertItem(MountEntry.getMountTypeLongName(mounttype))
self.comboIndexToMountType.append(mounttype)
self.MountTypeEditors = self.MountTypeEditorsDisk.copy()
self.MountTypeEditors.update(self.MountTypeEditorsNetwork)
self.MountTypeEditors.update(self.MountTypeEditorsSystem)
#hb.setStretchFactor(self.runlevelcombo,0)
self.connect(self.mounttypecombo, SIGNAL("activated(int)"), self.slotMountTypeChanged)
widget = QWidget(hb)
hb.setStretchFactor(widget,1)
# Create the stack of option edit widgets.
gb = QVGroupBox(self.topvbox)
self.topvbox.setStretchFactor(gb,1)
self.optionsstack = QWidgetStack(gb)
for mounttype in self.MountTypeEditors:
editpage = self.MountTypeEditors[mounttype](self.optionsstack)
self.mountTypeToOptionWidget[mounttype] = editpage
self.optionsstack.addWidget(editpage)
self.fsunavailablelabel = QHBox(gb)
self.fsunavailablelabel.setSpacing(KDialog.spacingHint())
tmplabel = QLabel(self.fsunavailablelabel)
self.fsunavailablelabel.setStretchFactor(tmplabel,0)
tmplabel.setPixmap(SmallIcon('info'))
label = QLabel(i18n("This filesystem type is currently unavailable on the running kernel."),
self.fsunavailablelabel)
self.fsunavailablelabel.setStretchFactor(label,1)
self.fsunavailablelabel.hide()
self.updatingGUI = False
#######################################################################
def doEditMount(self,mounttable,mountentry):
self.newEntry = False
self.mounttable = mounttable
self.originalMountEntry = mountentry
self.currentMountEntry = mountentry.copy()
self.updatingGUI = True
self.selectEntry(self.currentMountEntry.getMountType())
self.updatingGUI = False
if self.exec_loop()==QDialog.Accepted:
# All of the update stuff is in slotOk()
return True
return False
#######################################################################
def doNewMount(self,mounttable,defaultdevice):
self.newEntry = True
self.mounttable = mounttable
self.currentMountEntry = MountEntry()
if defaultdevice is not None:
self.currentMountEntry.setDevice(defaultdevice)
self.updatingGUI = True
self.currentOptionWidget = None
self.selectEntry(self.currentMountEntry.mounttype)
self.updatingGUI = False
if self.exec_loop()==QDialog.Accepted:
self.mounttable.allentries.append(self.currentMountEntry)
self.mounttable.updateFstabOnDisk()
return self.currentMountEntry
return None
#######################################################################
def selectEntry(self,mounttype):
#if self.currentOptionWidget!=None:
# # Update the mount entry from the
# self.currentOptionWidget.undisplayMountEntry(self.currentMountEntry)
self.currentMountEntry.setMountType(mounttype)
# Update GUI
self.mounttypecombo.setCurrentItem(self.comboIndexToMountType.index(mounttype))
self.currentOptionWidget = self.mountTypeToOptionWidget[mounttype]
self.currentOptionWidget.displayMountEntry(self.currentMountEntry)
self.optionsstack.raiseWidget(self.currentOptionWidget)
if microhal.isSupportedFileSystem(mounttype):
self.fsunavailablelabel.hide()
else:
self.fsunavailablelabel.show()
#######################################################################
def slotMountTypeChanged(self,index):
if self.updatingGUI==False:
self.updatingGUI = True
self.selectEntry(self.comboIndexToMountType[index])
self.updatingGUI = False
#######################################################################
def slotOk(self):
global allowlabel, allowuuid
self.currentOptionWidget.undisplayMountEntry(self.currentMountEntry)
if allowuuid:
if self.currentOptionWidget.uuidcheckbox.isChecked():
self.currentMountEntry.setUseAsDevice("uuid")
if allowlabel:
if self.currentOptionWidget.labelcheckbox.isChecked():
self.currentMountEntry.setUseAsDevice("label")
conflictentry = None
if self.newEntry:
for entry in self.mounttable:
if entry.getMountPoint()==self.currentMountEntry.getMountPoint():
# Conflict found.
conflictentry = entry
else:
# Check if the mountpoint is already in use elsewhere in the mounttable.
if self.originalMountEntry.getMountPoint()!=self.currentMountEntry.getMountPoint():
for entry in self.mounttable:
if (entry.getMountPoint()==self.currentMountEntry.getMountPoint()
and entry is not self.originalMountEntry):
# Conflict found.
conflictentry = entry
if conflictentry is not None:
if KMessageBox.warningContinueCancel(self, \
i18n("The mountpoint '%1' is already in use by another entry?\nContinue?").arg(
self.currentMountEntry.getMountPoint()), \
i18n("Mountpoint already in use"))!=KMessageBox.Continue:
return
if self.currentMountEntry.getMountType() in MountEntryDialog.MountTypeEditorsDisk.keys():
# If device is not in /dev and it's no bind mount, ask if that's meant this way ...
options = self.currentMountEntry.getFstabOptions()
if (not self.currentMountEntry.getDevice().startswith("/dev/")
and not ("loop" in options or "bind" in options)):
ask = KMessageBox.warningYesNoCancel(self,
i18n("'%1' does not seem to be a device and the option 'bind' has not been specified in the \
\"Advanced\" page?\n Should I add the 'loop' option?").arg(self.currentMountEntry.device),
i18n("Options may be missing"))
if ask==KMessageBox.Cancel:
return
elif ask==KMessageBox.Yes:
# Add loop option
extraoptions = self.currentMountEntry.getExtraOptions().split(',')
extraoptions.append('loop')
self.currentMountEntry.setExtraOptions(','.join(extraoptions))
if (not os.path.isdir(self.currentMountEntry.getMountPoint())
and not os.path.isfile(self.currentMountEntry.getMountPoint())
and not self.currentMountEntry.mounttype == 'swap'):
ask = KMessageBox.warningYesNoCancel(self,
i18n("""The mountpoint '%1' does not exist. You will not be able to enable it until it is created.\
\nShould I create the mountpoint?""").arg(self.currentMountEntry.getMountPoint()),
i18n("Mountpoint does not exist"))
if ask==KMessageBox.Cancel:
return
elif ask==KMessageBox.Yes:
os.mkdir(self.currentMountEntry.getMountPoint())
elif os.path.isfile(self.currentMountEntry.getMountPoint()):
if KMessageBox.warningContinueCancel(self,
i18n("""The mountpoint '%1' is a file, but it has to be a directory. You will probably not \
be able to enable it.\nContinue?""").arg(self.currentMountEntry.getMountPoint()),
i18n("Invalid mountpoint"))!=KMessageBox.Continue:
return
if self.newEntry==False:
# How to Change a Mount Entry.
# 1. Disable the exisiting entry (if needed)
# 2. Update existing entry from the mount table.
# 3. Enable the updated entry (if needed)
# 4. Write new fstab file.
# 5. Enable the new entry (if needed)
# 1. Disable the exisiting entry (if needed)
enabled = self.originalMountEntry.isEnabled()
if enabled:
self.disablingold = True
self.originalMountEntry.disable(self)
self.originalMountEntry.inPlaceCopyFrom(self.currentMountEntry)
self.mounttable.updateFstabOnDisk()
if enabled and self.originalMountEntry.isFileSystemAvailable():
self.originalMountEntry.enable(self)
self.accept()
############################################################################
class MountEntryAdvancedCommonUnixDialog(KDialogBase):
########################################################################
def __init__(self,parent,name=None):
KDialogBase.__init__(self,parent,name,1,"",KDialogBase.Ok|KDialogBase.Cancel)
grid = self.makeGridMainWidget(2,Qt.Horizontal)
grid.setSpacing(self.spacingHint())
QWidget(grid)
self.accesstimecheckbox = QCheckBox(i18n("Update file access timestamps"),grid)
QWidget(grid)
self.allowexecutablecheckbox = QCheckBox(i18n("Allow Executables"),grid)
QWidget(grid)
self.allowsuidcheckbox = QCheckBox(i18n("Allow the SUID and SGID attributes"),grid)
QWidget(grid)
self.usedevpointscheckbox = QCheckBox(i18n("Allow device points"),grid)
label = QLabel(i18n("Options:"),grid)
self.optionslineedit = KLineEdit(grid)
label = QLabel(i18n("fs_freq:"),grid)
self.fsfreqspinbox = KIntSpinBox (0,1000,1,0,10,grid)
label = QLabel(i18n("fs_passno:"),grid)
self.fspassnospinbox = KIntSpinBox (0,1000,1,0,10,grid)
########################################################################
def do(self,atime,allowexecutable,allowsuid,usedevpoints,options,fsfreq,fspassno):
self.accesstimecheckbox.setChecked(atime)
self.allowexecutablecheckbox.setChecked(allowexecutable)
self.allowsuidcheckbox.setChecked(allowsuid)
self.usedevpointscheckbox.setChecked(usedevpoints)
self.optionslineedit.setText(options)
self.fsfreqspinbox.setValue(fsfreq)
self.fspassnospinbox.setValue(fspassno)
self.exec_loop()
return ( self.accesstimecheckbox.isChecked(),
self.allowexecutablecheckbox.isChecked(),
self.allowsuidcheckbox.isChecked(),
self.usedevpointscheckbox.isChecked(),
unicode(self.optionslineedit.text()),
self.fsfreqspinbox.value(),
self.fspassnospinbox.value())
############################################################################
class MountEntryAdvancedPlainDialog(KDialogBase):
########################################################################
def __init__(self,parent,name=None):
KDialogBase.__init__(self,parent,name,1,"",KDialogBase.Ok|KDialogBase.Cancel)
grid = self.makeGridMainWidget(2,Qt.Horizontal)
grid.setSpacing(self.spacingHint())
label = QLabel(i18n("Options:"),grid)
self.optionslineedit = KLineEdit(grid)
label = QLabel(i18n("fs_freq:"),grid)
self.fsfreqspinbox = KIntSpinBox (0,1000,1,0,10,grid)
label = QLabel(i18n("fs_passno:"),grid)
self.fspassnospinbox = KIntSpinBox (0,1000,1,0,10,grid)
########################################################################
def do(self,options,fsfreq,fspassno):
self.optionslineedit.setText(options)
self.fsfreqspinbox.setValue(fsfreq)
self.fspassnospinbox.setValue(fspassno)
self.exec_loop()
return (unicode(self.optionslineedit.text()), self.fsfreqspinbox.value(), self.fspassnospinbox.value())
############################################################################
class MountListViewItem(TDEListViewItem):
########################################################################
def __init__(self,parentitem,mountentry,haldevice=None):
self.haldevice = haldevice
self.mountentry = mountentry
if self.mountentry is None:
# There is no mount entry right now. This acts as a place holder
# for now.
TDEListViewItem.__init__(self,parentitem,self.haldevice.getName(),"","",self.haldevice.getDev(),"")
else:
if mountentry.isEnabled():
enabled = i18n("Enabled")
else:
enabled = i18n("Disabled")
if self.haldevice is not None:
name = self.haldevice.getName()
else:
name = self.mountentry.getName()
TDEListViewItem.__init__(self, parentitem, \
name,
self.mountentry.getMountPoint(), \
self.mountentry.mounttype, \
self.mountentry.getDevice(), \
enabled)
if self.mountentry.isEnabled():
self.setPixmap(4,UserIcon("greenled"))
else:
self.setPixmap(4,UserIcon("greyled"))
self.__updateIcon()
########################################################################
def hasHAL(self):
return self.haldevice is not None
########################################################################
def getHAL(self): return self.haldevice
########################################################################
def updateDisplay(self):
if self.mountentry is not None:
if self.mountentry.isEnabled():
enabled = i18n("Enabled")
self.setPixmap(4,UserIcon("greenled"))
else:
enabled = i18n("Disabled")
self.setPixmap(4,UserIcon("greyled"))
if self.haldevice is not None:
self.setText(0,self.haldevice.getName())
else:
self.setText(0,self.mountentry.getMountPoint())
self.setText(1,self.mountentry.getMountPoint())
self.setText(2,self.mountentry.mounttype)
if self.mountentry.getDevice() is not None:
self.setText(3,self.mountentry.getDevice())
else:
uuid_device = microhal.getDeviceByUUID(self.mountentry.getUUID())
label_device = microhal.getDeviceByUUID(self.mountentry.getUUID())
if label_device is not None:
self.setText(3,label_device.getDev()+" (Label)")
elif real_device is not None:
self.setText(3,real_device.getDev()+" (UUID)")
else:
self.setText(3,"UUID="+self.mountentry.getUUID())
self.setText(4,enabled)
else:
self.setText(0,self.haldevice.getName())
self.setText(1,"")
self.setText(2,"")
self.setText(3,self.haldevice.getDev())
self.setText(4,"")
self.setPixmap(4,QPixmap())
self.__updateIcon()
########################################################################
def setMountEntry(self,entry):
self.mountentry = entry
self.updateDisplay()
########################################################################
def getMountEntry(self):
return self.mountentry
########################################################################
def getDevice(self): return self.haldevice.getDev()
########################################################################
def __updateIcon(self):
if self.haldevice is not None:
self.setPixmap(0,UserIcon(self.haldevice.iconname))
else:
self.setPixmap(0,UserIcon(self.mountentry.getIconName()))
############################################################################
class MountGroupListViewItem(TDEListViewItem):
########################################################################
def __init__(self,parentitem,haldevice):
self.haldevice = haldevice
TDEListViewItem.__init__(self,parentitem,self.haldevice.getName(),"","","","")
if self.haldevice is not None:
iconname = self.haldevice.iconname
else:
iconname = self.mountentry.getIconName()
self.setPixmap(0,UserIcon(iconname))
########################################################################
def getMountEntry(self):
return None
########################################################################
def updateDisplay(self):
pass
def hasHAL(self):
return False
############################################################################
# Try translating this code to C++. I dare ya!
if standalone:
programbase = KDialogBase
else:
programbase = TDECModule
class MountConfigApp(programbase):
########################################################################
def __init__(self,parent=None,name=None):
global standalone,isroot
TDEGlobal.locale().insertCatalogue("guidance")
if standalone:
KDialogBase.__init__(self,KJanusWidget.Plain,i18n("Disk & Filesystems"),
KDialogBase.User1|KDialogBase.Close, KDialogBase.Close)
self.setButtonText(KDialogBase.User1,i18n("About"))
topwidget = self.plainPage()
else:
TDECModule.__init__(self,parent,name)
self.setButtons(0)
self.aboutdata = MakeAboutData()
topwidget = self
# Create a configuration object.
self.config = TDEConfig("mountconfigrc")
TDEGlobal.iconLoader().addAppDir("guidance")
self.updatingGUI = False
self.mounttable = MountTable('/etc/fstab','/etc/mtab')
self.selectedentry = None
self.aboutus = TDEAboutApplication(self)
self.sizeviewdialogs = {}
toplayout = QVBoxLayout(topwidget, 0, KDialog.spacingHint())
#topwidget.setEnabled(isroot)
hb = QHBox(topwidget)
hb.setSpacing(KDialog.spacingHint())
#if standalone:
# hb.setMargin(KDialog.marginHint())
toplayout.addWidget(hb)
label = QLabel(hb)
label.setPixmap(UserIcon("kcmpartitions"))
hb.setStretchFactor(label,0)
label = QLabel(i18n("Available Disks and Filesystems:"),hb)
hb.setStretchFactor(label,1)
self.mountlist = TDEListView(topwidget,"Mount list")
toplayout.addWidget(self.mountlist)
self.mountlist.addColumn(i18n("Name"))
self.mountlist.addColumn(i18n("Mount Point"))
self.mountlist.addColumn(i18n("Type"))
self.mountlist.addColumn(i18n("Device"))
self.mountlist.addColumn(i18n("Enabled"))
self.mountlist.setAllColumnsShowFocus(True)
self.mountlist.setSelectionMode(QListView.Single)
self.mountlist.setRootIsDecorated(True)
self.mountlist.setSorting(-1)
self.connect(self.mountlist, SIGNAL("selectionChanged(QListViewItem *)"), self.slotListClicked)
# Doubleclick in item opens modify dialogue.
self.connect(self.mountlist, SIGNAL("doubleClicked(QListViewItem *)"), self.slotModifyClicked)
# Rightclick: Open ContextMenu
self.connect(self.mountlist, SIGNAL("contextMenu(TDEListView*,QListViewItem*,const QPoint&)"),
self.slotContextMenu)
hbox = QHBox(topwidget)
toplayout.addWidget(hbox)
hbox.setSpacing(KDialog.spacingHint())
toplayout.setStretchFactor(hbox,0)
self.newbutton = KPushButton(i18n("New..."),hbox)
hbox.setStretchFactor(self.newbutton,1)
self.connect(self.newbutton,SIGNAL("clicked()"),self.slotNewClicked)
self.newbutton.setEnabled(isroot)
self.modifybutton = KPushButton(i18n("Modify..."),hbox)
hbox.setStretchFactor(self.modifybutton,1)
self.connect(self.modifybutton,SIGNAL("clicked()"),self.slotModifyClicked)
self.deletebutton = KPushButton(i18n("Delete..."),hbox)
hbox.setStretchFactor(self.deletebutton,1)
self.connect(self.deletebutton,SIGNAL("clicked()"),self.slotDeleteClicked)
self.enablebutton = KPushButton(i18n("Enable"),hbox)
hbox.setStretchFactor(self.enablebutton,1)
self.connect(self.enablebutton,SIGNAL("clicked()"),self.slotEnableClicked)
self.disablebutton = KPushButton(i18n("Disable"),hbox)
hbox.setStretchFactor(self.disablebutton,1)
self.connect(self.disablebutton,SIGNAL("clicked()"),self.slotDisableClicked)
self.detailsbutton = KPushButton(i18n("Details..."),hbox)
hbox.setStretchFactor(self.detailsbutton,1)
self.connect(self.detailsbutton,SIGNAL("clicked()"),self.slotDetailsClicked)
self.devstolistitems = None
self.uuidstolistitems = None
self.mountentriestolistitems = None
self.__updateMountList()
self.__selectEntry(self.mounttable[0])
self.configuredialog = MountEntryDialog(None)
########################################################################
def exec_loop(self):
global programbase
self.__loadOptions()
programbase.exec_loop(self)
self.__saveOptions()
########################################################################
def slotContextMenu(self,lv,lv_item,p):
hal_device = lv_item.haldevice
if hal_device is not None and not isinstance(hal_device,MicroHAL.FakeSystemDevice):
self.cmenu = TDEPopupMenu(self,"MyActions")
if isinstance(hal_device,MicroHAL.RemovableDisk) or isinstance(lv_item,MountListViewItem):
self.cmenu.insertItem(i18n("Modify..."), self.slotModifyClicked, 0, 0)
self.cmenu.insertItem(i18n("Delete..."), self.slotDeleteClicked, 0, 1)
if not isroot:
self.cmenu.setItemEnabled(0,False)
self.cmenu.setItemEnabled(1,False)
elif isinstance(hal_device,MicroHAL.Disk) or isinstance(hal_device,MicroHAL.USBDisk):
self.cmenu.insertItem(i18n("Show details..."), self.slotDetailsClicked, 0, 0)
self.cmenu.insertItem(i18n("New..."), self.slotNewClicked, 0, 1)
if not isroot:
self.cmenu.setItemEnabled(1,False)
self.cmenu.exec_loop(p)
########################################################################
def slotUser1(self):
self.aboutus.show()
########################################################################
def slotEnableClicked(self):
if self.selectedentry!=None:
self.selectedentry.enable(self)
self.mounttable.updateStatus(self.selectedentry)
self.__updateEntry(self.selectedentry)
self.enablebutton.setEnabled(not self.selectedentry.isEnabled())
self.disablebutton.setEnabled(self.selectedentry.isEnabled())
########################################################################
def slotDisableClicked(self):
if self.selectedentry!=None:
self.__disableEntry()
########################################################################
def slotModifyClicked(self):
global isroot
if not isroot:
return
if self.selectedentry!=None:
self.configuredialog.doEditMount(self.mounttable,self.selectedentry)
lvi = self.mountentriestolistitems[self.selectedentry]
if lvi.hasHAL():
if lvi.getHAL().getDev()!=self.selectedentry.getDevice():
# The (device-)item in the listview no longer matches this mount entry.
del self.mountentriestolistitems[self.selectedentry]
lvi.setMountEntry(None)
lvi.updateDisplay()
# Reinsert this mount entry into the list view.
self.__insertMountEntryIntoListView(self.selectedentry)
elif self.selectedentry.getDevice() is not None \
and self.selectedentry.getDevice() in self.devstolistitems:
# The mount entry can now merged with any existing (HAL-)item.
# Remove the existing lose item.
self.mountlist.takeItem(lvi)
del self.mountentriestolistitems[self.selectedentry]
del self.devstolistitems[self.selectedentry.getDevice()]
del lvi
# Reinsert this mount entry into the list view.
self.__insertMountEntryIntoListView(self.selectedentry)
elif self.selectedentry.getUUID() is not None \
and self.selectedentry.getUUID() in self.uuidstolistitems:
# The mount entry can now merged with any existing (HAL-)item.
# Remove the existing lose item.
self.mountlist.takeItem(lvi)
del self.mountentriestolistitems[self.selectedentry]
del self.uuidstolistitems[self.selectedentry.getUUID()]
del lvi
# Reinsert this mount entry into the list view.
self.__insertMountEntryIntoListView(self.selectedentry)
self.__updateEntry(self.selectedentry)
self.__selectEntry(self.selectedentry)
else:
self.slotNewClicked()
########################################################################
def slotNewClicked(self):
defaultdevice = None
if self.selectedentry is None:
lvi = self.mountlist.selectedItem()
if lvi is not None and lvi.hasHAL() and (lvi.getMountEntry() is None):
defaultdevice = lvi.getDevice()
newentry = self.configuredialog.doNewMount(self.mounttable,defaultdevice)
if newentry!=None:
self.updatingGUI = True
self.__insertMountEntryIntoListView(newentry)
self.__selectEntry(newentry)
self.updatingGUI = False
########################################################################
def slotDeleteClicked(self):
if self.selectedentry!=None:
if self.selectedentry.isEnabled():
if not self.__disableEntry():
return # If we couldn't disable it, then we can't continue.
message = i18n("Are you sure you want to delete mount '%1' of type %2 at '%3'?\n " +
"(This will only remove the mount, no data will be deleted.)") \
.arg(self.selectedentry.getMountPoint()).arg(self.selectedentry.mounttype).arg(
self.selectedentry.getDevice())
if KMessageBox.warningYesNo(self,message,i18n("Delete Mount?"))==KMessageBox.Yes:
lvi = self.mountentriestolistitems[self.selectedentry]
if not lvi.hasHAL():
self.mountlist.takeItem(lvi)
del lvi
del self.mountentriestolistitems[self.selectedentry]
else:
lvi.setMountEntry(None)
self.mounttable.remove(self.selectedentry)
self.mounttable.updateFstabOnDisk()
self.__selectEntry(None)
########################################################################
def slotDetailsClicked(self):
# Popup a dialog showing disklayout and a graphical represenation of 'df'
hal_device = self.mountlist.selectedItem().haldevice
if isinstance(hal_device,MicroHAL.Disk):
blk = hal_device.getDev()
devicepath, devicename = ('/'.join(blk.split('/')[0:-1])+'/', blk.split('/')[-1])
# We keep a dict with those widgets, that saves us some time reading out all the values.
if devicename not in self.sizeviewdialogs.keys():
self.sizeviewdialogs[devicename] = sizeview.SizeView(self,devicename,devicepath)
self.sizeviewdialogs[devicename].exec_loop()
else:
self.sizeviewdialogs[devicename].exec_loop()
else:
print "Sizeview doesn't support",blk.__class__," yet."
########################################################################
def slotListClicked(self,item):
if self.updatingGUI==False:
self.__selectEntry(item.getMountEntry())
########################################################################
def __disableEntry(self):
self.selectedentry.disable(self)
self.mounttable.updateStatus(self.selectedentry)
self.__updateEntry(self.selectedentry)
self.enablebutton.setEnabled(not self.selectedentry.isEnabled() and self.selectedentry.isFileSystemAvailable())
self.disablebutton.setEnabled(self.selectedentry.isEnabled())
return not self.selectedentry.isEnabled()
########################################################################
def __updateEntry(self,selectedentry):
# Update the display.
lvi = self.mountentriestolistitems[selectedentry]
lvi.updateDisplay()
########################################################################
def __loadOptions(self):
self.config.setGroup("General")
size = self.config.readSizeEntry("Geometry")
if size.isEmpty()==False:
self.resize(size)
#######################################################################
def __saveOptions(self):
global isroot
if isroot:
return
self.config.setGroup("General")
self.config.writeEntry("Geometry", self.size())
self.config.sync()
########################################################################
def __updateMountList(self):
self.mountentriestolistitems = {}
self.mountlist.clear()
self.listgroups = {}
self.devstolistitems = {}
self.uuidstolistitems = {}
lasttopitem = None
# Find out which disks are installed and should be shown in the
# listview. For real disks we put a 'group' in the listview and
# under the group we list the partitions, whether they are
# mounted or not.
for blockdevice in microhal.getDevices():
# We are looking for block devices that represent hard disks or
# things that have partitions and are not removable
if (blockdevice.major in microhal.partitionblockdevs and not blockdevice.removable) \
or isinstance(blockdevice,MicroHAL.USBDisk):
# We have a not removable block device.
# We want to create a listitem for the device and subitems
# for each partition.
groupitem = MountGroupListViewItem(self.mountlist,blockdevice)
groupitem.setOpen(True)
lasttopitem = groupitem
lvi = None
for partition in blockdevice.getPartitions():
# Try to find a matching mount entry for this partition.
lastlvi = lvi
lvi = MountListViewItem(groupitem,None,partition)
if partition.getUUID() is not None:
self.uuidstolistitems[partition.getUUID()] = lvi
if partition.getDev() is not None:
self.devstolistitems[partition.getDev()] = lvi
if lastlvi is not None:
lvi.moveItem(lastlvi)
elif blockdevice.getMajor() in microhal.cdromsdevs or blockdevice.isRemovable():
# Removable block device, assume CDROM (even if it's a partitionblockdevice)
lvi = MountListViewItem(self.mountlist,None,blockdevice)
if blockdevice.getUUID() is not None:
self.uuidstolistitems[blockdevice.getUUID()] = lvi
if blockdevice.getDev() is not None:
self.devstolistitems[blockdevice.getDev()] = lvi
lasttopitem = lvi
systemdevice = MicroHAL.FakeSystemDevice()
systemdevice.iconname = systemdevice.getIconName()
groupitem = MountGroupListViewItem(self.mountlist,systemdevice)
if lasttopitem is not None:
groupitem.moveItem(lasttopitem)
lasttopitem = groupitem
self.listgroups["system"] = groupitem
self.mountentriestolistitems = {}
for entry in self.mounttable:
self.__insertMountEntryIntoListView(entry)
########################################################################
def __insertMountEntryIntoListView(self,mountentry):
if mountentry.getDevice() in self.devstolistitems:
lvi = self.devstolistitems[mountentry.getDevice()]
lvi.setMountEntry(mountentry)
elif mountentry.getUUID() in self.uuidstolistitems:
lvi = self.uuidstolistitems[mountentry.getUUID()]
lvi.setMountEntry(mountentry)
else:
cat = mountentry.getCategory() # Place it under a special node?
if cat not in self.listgroups:
lvi = MountListViewItem(self.mountlist,mountentry)
item = self.mountlist.firstChild()
else:
lvi = MountListViewItem(self.listgroups[cat],mountentry)
item = self.listgroups[cat].firstChild()
# Move the item to the end of this (sub-list).
while item.nextSibling() is not None:
item = item.nextSibling()
lvi.moveItem(item)
self.mountentriestolistitems[mountentry] = lvi
########################################################################
def __selectEntry(self,mountentry):
if mountentry is not None and isroot:
lvi = self.mountentriestolistitems[mountentry]
self.mountlist.setSelected(lvi,True)
self.enablebutton.setEnabled(not mountentry.isEnabled() and mountentry.isFileSystemAvailable())
self.selectedentry = mountentry
# disable unsupported stuff, such as SystemEntries that canot be disabled and modified
if not mountentry.maydisable:
disable = False
else:
disable = mountentry.isEnabled()
if mountentry.notInFstab:
delete = False
modify = False
else:
delete = True
modify = True
self.disablebutton.setEnabled(disable)
self.deletebutton.setEnabled(delete)
self.modifybutton.setEnabled(modify)
else:
self.enablebutton.setEnabled(False)
self.disablebutton.setEnabled(False)
self.deletebutton.setEnabled(False)
self.modifybutton.setEnabled(False)
self.detailsbutton.setEnabled(False)
self.selectedentry = None
selected_item = self.mountlist.selectedItem()
if selected_item is not None:
self.detailsbutton.setEnabled(isinstance(selected_item.haldevice,MicroHAL.Disk) \
and not isinstance(selected_item.haldevice,MicroHAL.RemovableDisk))
else:
self.detailsbutton.setEnabled(False)
#######################################################################
# KControl virtual void methods
def load(self):
pass
def save(self):
pass
def defaults(self):
pass
def sysdefaults(self):
pass
def aboutData(self):
# Return the TDEAboutData object which we created during initialisation.
return self.aboutdata
def buttons(self):
# Only supply a Help button. Other choices are Default and Apply.
return TDECModule.Help
############################################################################
# Factory function for KControl
def create_mountconfig(parent,name):
global kapp, microhal
microhal = MicroHAL.MicroHAL()
kapp = TDEApplication.kApplication()
return MountConfigApp(parent, name)
############################################################################
def MakeAboutData():
aboutdata = TDEAboutData("mountconfig",programname,version,"Disk & Filesystem Configuration Tool",
TDEAboutData.License_GPL, "Copyright (C) 2003-2007 Simon Edwards")
aboutdata.addAuthor("Simon Edwards","Developer","simon@simonzone.com",
"http://www.simonzone.com/software/guidance")
aboutdata.addAuthor("Sebastian Kügler","Developer","sebas@kde.org","http://vizZzion.org");
return aboutdata
if standalone:
aboutdata = MakeAboutData()
TDECmdLineArgs.init(sys.argv,aboutdata)
microhal = MicroHAL.MicroHAL()
kapp = TDEApplication()
sysvapp = MountConfigApp()
sysvapp.exec_loop()