summaryrefslogtreecommitdiffstats
path: root/mountconfig/mountconfig.py
diff options
context:
space:
mode:
Diffstat (limited to 'mountconfig/mountconfig.py')
-rwxr-xr-xmountconfig/mountconfig.py3303
1 files changed, 3303 insertions, 0 deletions
diff --git a/mountconfig/mountconfig.py b/mountconfig/mountconfig.py
new file mode 100755
index 0000000..1f31f13
--- /dev/null
+++ b/mountconfig/mountconfig.py
@@ -0,0 +1,3303 @@
+#!/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 kdeui import *
+from kdecore import *
+from kfile import *
+from kio 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
+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")),
+ '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(KGlobalSettings.alternateBackgroundColor())
+ p.eraseRect(0,0,self.listBox().width(),self.height(self.listBox()))
+ QListBoxPixmap.paint(self,p)
+
+############################################################################
+class MountEntryDialog(KDialogBase):
+
+ MountTypeEditorsDisk = {
+ 'ext2' : MountEntryDialogOptionsCommonUnix,
+ 'ext3' : 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(KListViewItem):
+ ########################################################################
+ 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.
+ KListViewItem.__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()
+ KListViewItem.__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(KListViewItem):
+ ########################################################################
+ def __init__(self,parentitem,haldevice):
+ self.haldevice = haldevice
+ KListViewItem.__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 = KCModule
+
+class MountConfigApp(programbase):
+ ########################################################################
+ def __init__(self,parent=None,name=None):
+ global standalone,isroot
+ KGlobal.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:
+ KCModule.__init__(self,parent,name)
+ self.setButtons(0)
+ self.aboutdata = MakeAboutData()
+ topwidget = self
+
+ # Create a configuration object.
+ self.config = KConfig("mountconfigrc")
+
+ KGlobal.iconLoader().addAppDir("guidance")
+ self.updatingGUI = False
+ self.mounttable = MountTable('/etc/fstab','/etc/mtab')
+ self.selectedentry = None
+ self.aboutus = KAboutApplication(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 = KListView(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(KListView*,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 = KPopupMenu(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 KAboutData object which we created during initialisation.
+ return self.aboutdata
+ def buttons(self):
+ # Only supply a Help button. Other choices are Default and Apply.
+ return KCModule.Help
+
+############################################################################
+# Factory function for KControl
+def create_mountconfig(parent,name):
+ global kapp, microhal
+ microhal = MicroHAL.MicroHAL()
+ kapp = KApplication.kApplication()
+ return MountConfigApp(parent, name)
+
+############################################################################
+def MakeAboutData():
+ aboutdata = KAboutData("mountconfig",programname,version,"Disk & Filesystem Configuration Tool",
+ KAboutData.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()
+ KCmdLineArgs.init(sys.argv,aboutdata)
+
+ microhal = MicroHAL.MicroHAL()
+ kapp = KApplication()
+ sysvapp = MountConfigApp()
+ sysvapp.exec_loop()