# -*- coding: utf-8 -*-
from gLocale import _
from GeminiDef import *
from WidgetVariableList import WidgetVariableList
from WidgetConfig import WidgetInput
from ShowFileList import ShowFileList
from gTools import libgeminimain, cleanexit, gLoadPixmap, pathExists, modulExists, myExecute, ctoolsclass #, myExecute
from plugin import cgevent, geventNotifier
from WidgetTools import currthread, C_FORMAT, BackGroundThread, HumanSize, luksinfo
from WidgetConfig import gConfigWindow, gConfigSelection, gConfigOnOff, CONFIGSEPERATOR

from enigma import eTimer
from Tools.Directories import createDir
from Tools.BoundFunction import boundFunction
from Screens.MessageBox import MessageBox
from Screens.ChoiceBox import ChoiceBox
from Components.Console import Console
from Components.ActionMap import ActionMap
from Components.config import config, NoSave, getConfigListEntry, ConfigText, ConfigInteger


#-------------------------------------------------------------------

class Cformat(gConfigWindow):
	def __init__(self, session, freesize=None, cryptsetup=False):
		gConfigWindow.__init__ (self, session, _("Modify partitions"), greenbutton=_("Start"))
		self.__currfs = None
		self.__freesize = freesize
		self.__cryptsetup = cryptsetup

		menu=[]
		for x in ctoolsclass.getAllFilesystems():
			if x[ctoolsclass.FS_MAKE] and x[ctoolsclass.FS_NAME]!="luks":
				menu.append(x[ctoolsclass.FS_NAME])
		
		if self.__freesize:
			config.bp.size = NoSave(ConfigInteger(default=self.__freesize/1024/1024, limits=(1, self.__freesize/1024/1024)))
		
		config.bp.fs = NoSave(gConfigSelection(default="ext4", choices=menu))
		config.bp.vol = NoSave(ConfigText(default = _("Please label the partition"), fixed_size=False))
		config.bp.crypt = NoSave(gConfigOnOff(default=False))
		config.bp.passwd = NoSave(ConfigText(default = "foobar", fixed_size=False))
		config.bp.big = NoSave(gConfigOnOff(default=False))
		
		self.onLayoutFinish.append(self.__fillList)
		
	def KeyExit(self):
		self.close(None)
		
	def __fillList(self):
		self.__currfs = ctoolsclass.getFilesystemData(config.bp.fs.value)
		list = []
		list.append(getConfigListEntry(_("Filesystem"), config.bp.fs))
		if self.__freesize:
			list.append(getConfigListEntry(_("Size in %s (max %d%s)") %("MB",self.__freesize/1024/1024,"MB"), config.bp.size))
		if self.__currfs and self.__currfs[ctoolsclass.FS_TOOL]:
			list.append(getConfigListEntry(_("Device Label"), config.bp.vol))
		if self.__currfs and self.__currfs[ctoolsclass.FS_LARGE]:
			list.append(getConfigListEntry(_("Optimize for large files?"), config.bp.big))
		if self.__currfs and self.__cryptsetup and self.__currfs[ctoolsclass.FS_NAME] != "linux-swap":
			list.append(CONFIGSEPERATOR())
			list.append(getConfigListEntry(_("encrypt %s?") %_("Partition"), config.bp.crypt))
			if config.bp.crypt.value:
				list.append(getConfigListEntry(_("Password"), config.bp.passwd))
		self.SetConfList(list)
		
	def KeyLeft(self):
		gConfigWindow.KeyLeft(self)
		if self.getCurrendValue()==config.bp.fs or self.getCurrendValue()==config.bp.crypt:
			self.__fillList()

	def KeyRight(self):
		gConfigWindow.KeyRight(self)
		if self.getCurrendValue()==config.bp.fs or self.getCurrendValue()==config.bp.crypt:
			self.__fillList()

	def KeyGreen(self):
		label=""
		if self.__currfs and self.__currfs[ctoolsclass.FS_TOOL] and config.bp.vol.value != _("Please label the partition"):
			label = config.bp.vol.value.replace(" ", "_")
		size=0
		if self.__freesize:
			size = config.bp.size.value*1024*1024
		passwd=None
		if config.bp.crypt.value and self.__cryptsetup and self.__currfs and self.__currfs[ctoolsclass.FS_NAME] != "linux-swap":
			passwd = config.bp.passwd.value
		large=""
		if config.bp.big.value and self.__currfs and self.__currfs[ctoolsclass.FS_LARGE]:
			large=self.__currfs[ctoolsclass.FS_LARGE]
		self.close((self.__currfs, label, size, passwd, large))

#-------------------------------------------------------------------

class FilesystemManager(WidgetVariableList):
	def __init__(self, session):
		WidgetVariableList.__init__ (self, session, _("Supported filesystems"), ListIcon=(66,66), LinesProEntry=4, icon="icon_devicemanager.png")
		self.skinName = [self.__class__.__name__,"VariableList3Button_" + self.__class__.__name__,"VariableList3Button"]
		self.__makeupdate=False
		self.__installok=None
		self.__fslist = ctoolsclass.getAllFilesystems()
		self.onLayoutFinish.append(self.__fillListe)
		
	def KeyExit(self):
		self.close(self.__makeupdate)
		
	def __fillListe(self):
		lastIndex = self.GetIndex()
		list = []
		for x in self.__fslist:
			#print x
			pic="dev_hdd.png"
			text = "%s (%s)\n" %(x[ctoolsclass.FS_DESC],x[ctoolsclass.FS_NAME])
			text += "%s:\t\t" %_("create")
			if x[ctoolsclass.FS_MAKE]:
				text += "%s\n" %_("available")
			else:
				text += "%s\n" %_("not available")
			
			if x[ctoolsclass.FS_NAME]=="linux-swap":
				pic="dev_memory.png"
			elif x[ctoolsclass.FS_NAME]=="luks":
				pic="dev_luks.png"
			else:
				text += "%s:\t\t" %_("test")
				if x[ctoolsclass.FS_FSCK]:
					text += "%s\n" %_("available")
				else:
					text += "%s\n" %_("not available")
				text += "%s:\t" %_("set volume label")
				if x[ctoolsclass.FS_TOOL]:
					text += "%s" %_("available")
				else:
					text += "%s" %_("not available")
			list.append((text, gLoadPixmap(pic), x))

		self.SetList(list)
		self.SetIndex(lastIndex)

	def selectionChanged(self):
		self.SetGB()
		self.__installok=None
		sel = self.getCurrentEntry()
		if sel and sel[2] and sel[2][ctoolsclass.FS_TOOL]==None and sel[2][ctoolsclass.FS_PACK] is not None:
			self.SetGB(_("Install package"))
			self.__installok=sel[2][ctoolsclass.FS_PACK]
			
	def KeyGreen(self):
		if self.__installok:
			from WidgetIpkg import WidgetIpkg, IPKG_UPDATE, IPKG_INSTALL
			self.session.openWithCallback(self.__afterInstall, WidgetIpkg, cmdList=[(IPKG_UPDATE,""), (IPKG_INSTALL, self.__installok)])
			
	def __afterInstall(self,val):
		if val[0]==0:
			if self.__installok=="cryptsetup":
				myExecute("modprobe dm_crypt")
			self.__fslist = ctoolsclass.getAllFilesystems(True)
			self.__installok=None
			self.__fillListe()

#-------------------------------------------------------------------------------

class DeviceManager(WidgetVariableList):
	def __init__(self, session, name=None):
		WidgetVariableList.__init__ (self, session, name or _("Device Manager"), ListIcon=(66,66), LinesProEntry=4, NameGreen=_("Supported filesystems"), NameBlue=_("Menu"), icon="icon_devicemanager.png")
		self.skinName = [self.__class__.__name__,"VariableList3Button_" + self.__class__.__name__,"VariableList3Button"]
		geventNotifier.append((EVENT_HARDWARE, self.__fillListe))
		self.onLayoutFinish.append(self.__fillListe)
		
	def KeyExit(self):
		del currthread[:]
		geventNotifier.remove((EVENT_HARDWARE, self.__fillListe))
		self.close()
		cleanexit(__name__)

	def selectionChanged(self):
		sel = self.getCurrentEntry()
		if sel and sel[2]:
			self.SetLabel()
			self.SetRB()
			if sel[2][DEV_SIZE]>0:
				if sel[2][DEV_TYPE] & (ATA_HDD | ATAPI_CF | SCSI_STICK | SCSI_HDD | MMCBLK):
					self.SetLabel(_("Press ok for the partitionsmanager"))
				if sel[2][DEV_TYPE] & (ATAPI_CD | SCSI_DVD):
					self.SetRB(_("Eject"))
				if sel[2][DEV_TYPE] & (SCSI_STICK | SCSI_HDD | MMCBLK):
					self.SetRB(_("Remove"))
		
	def __fillListe(self, what=0, val=""):
		lastIndex = self.GetIndex()
		list = []
		for x in libgeminimain.getPyList(GETBLOCKLIST):
			#print x
			if x[DEV_TYPE] & (DMAPPER | LOOPDEV):
				continue
			tstr = _("Type") + ": " + x[DEV_DESC] + "  " + x[DEV_DEVPATH] + "\n"
			if x[DEV_MODEL]:
				tstr += _("Model") + ": " + x[DEV_MODEL] + "\n"
			if x[DEV_SIZE]:
				tstr += _("Size") + ": " + HumanSize(x[DEV_SIZE]) + " "
			if x[DEV_PARTS]:
				tstr += _("in %d Partition(s)") % (x[DEV_PARTS])
			else:
				tstr += "         %s %s" %(_("Attention!"), _("No partitions found"))
			tstr += "\n"
			
			if x[DEV_STATUS]=="stby":
				tstr += _("Harddisk is sleeping")
			elif x[DEV_STATUS]!="":
				tstr += "%s %s\xc2\xb0C" % (_("HDD-Temperature"),x[DEV_STATUS])
			list.append((tstr, gLoadPixmap(x[DEV_PIC]), x))
		self.SetList(list)
		self.SetIndex(lastIndex)
		
	def KeyOk(self):
		sel = self.getCurrentEntry()
		if sel and sel[2] and sel[2][DEV_SIZE]>0:
			if sel[2][DEV_TYPE] & (ATA_HDD | ATAPI_CF | SCSI_STICK | SCSI_HDD | MMCBLK):
				self.session.openWithCallback(self.__fillListe, PartitionsManager, sel[2])
				
	def KeyGreen(self):
		self.session.open(FilesystemManager)
	
	def KeyRed(self):#Auswerfen
		sel = self.getCurrentEntry()
		if sel and sel[2]:
			dev = sel[2]
			if dev[DEV_SIZE]>0:
				if dev[DEV_TYPE] & (ATAPI_CD | SCSI_DVD):
					myExecute("eject -s " + dev[DEV_DEVPATH])
					self.__fillListe()
				elif dev[DEV_TYPE] & (SCSI_STICK | SCSI_HDD | MMCBLK):
					libgeminimain.setHWLock(1)
					if self.__umountBlocKDevice(dev) == 0:
						self.session.open(MessageBox, _("Device can now be safely removed!"), MessageBox.TYPE_INFO, timeout=5)
					libgeminimain.setHWLock(0)

	def KeyBlue(self):
		sel = self.getCurrentEntry()
		if sel and sel[2]:
			devices = sel[2]
			menu = []
			menu.append((_("Mountoptions"), "mountoptions", None))
			if devices[DEV_TYPE] & (ATA_HDD | SCSI_HDD | ATAPI_CD | SCSI_DVD):
				menu.append((_("Setup"), "setup", devices))
				if devices[DEV_TYPE] & (ATA_HDD | SCSI_HDD):
					menu.append((_("SpinDown"), "spindown", devices))
			if devices[DEV_TYPE] & (ATA_HDD | SCSI_HDD):
				menu.append((_("HDD-Temperature"), "temperature", devices))
			if devices[DEV_TYPE] & (ATA_HDD | ATAPI_CF | SCSI_HDD | SCSI_STICK):
				menu.append((_("S.M.A.R.T. Self-Monitoring Report"), "smart", devices))
				if devices[DEV_SIZE]>0:
					menu.append((_("Speed"), "speed", devices))
			if len(menu):
				self.session.openWithCallback(self.__menuCallback, ChoiceBox, title="", list=menu)

	def __menuCallback(self, choice):
		if choice == None:
			return
		dev = choice[2]
		if choice[1] == "setup":
			if dev[DEV_TYPE] & (ATA_HDD | SCSI_HDD):
				from Screens.Setup import Setup
				self.session.open(Setup, "harddisk")
			elif dev[DEV_TYPE] & (ATAPI_CD | SCSI_DVD):
				self.session.openWithCallback(self.__cdspeedCallback, WidgetInput, default=cgevent.getConfig("dvdspeed",15), limits=(0, 128), entryname=_("Speed") + " (0-128)")
		elif choice[1] == "temperature":
			if dev[DEV_TYPE] & ATA_HDD:
				val = libgeminimain.getPyList(GETATATEMP, "smartctl -A -d ata " + dev[DEV_DEVPATH])
			else:
				val = libgeminimain.getPyList(GETATATEMP, "smartctl -A -d scsi " + dev[DEV_DEVPATH])
			if val != "":
				self.session.open(MessageBox, "%s %s\xc2\xb0C" % (_("HDD-Temperature"),val), MessageBox.TYPE_INFO, timeout=7)
		elif choice[1] == "speed":
			self.session.open(ShowFileList, cmdlist=["hdparm -Tt " + dev[DEV_DEVPATH]])
		elif choice[1] == "smart":
			cmd = "smartctl -s on -a -d ata " + dev[DEV_DEVPATH]
			if dev[DEV_TYPE] & (SCSI_HDD | SCSI_STICK):
				cmd = "smartctl -s on -a -d scsi " + dev[DEV_DEVPATH]
			self.session.open(ShowFileList, cmdlist=[cmd])
		elif choice[1] == "spindown":
			myExecute("hdparm -y %s && sleep 2" %dev[DEV_DEVPATH])
			self.__fillListe()
		elif choice[1] == "mountoptions":
			default=(_("off"),_("on"))
			if cgevent.getConfig("forceuuid",0):
				default=(_("on"),_("off"))
			self.session.openWithCallback(self.__mountoptionsCallback, WidgetInput, default=default, choices=((_("on"),_("off"))), entryname=_("force uuid: (default off)"))
		
	def __mountoptionsCallback(self,val=None):
		if val is not None:
			if val==_("on"):
				cgevent.setConfig("forceuuid",1)
			else:
				cgevent.setConfig("forceuuid",0)

	def __cdspeedCallback(self,val=None):
		if val is not None:
			sel = self.getCurrentEntry()
			if sel and sel[2]:
				libgeminimain.gFunktion(SETCDSPEED, (sel[2][DEV_DEVPATH],val,1))

	def __partedCallback(self,val=None):
		if val is not None:
			libgeminimain.gFunktion(MOUNTDEVICE, val[DEV_DEV])
			self.__fillListe()
	
	def __umountBlocKDevice(self, dev):
		ret=0
		if dev[DEV_PARTS]:
			for x in libgeminimain.getPyList(GETPARTLIST, dev[DEV_DEV]):
				if x[PART_ISMOUNTED]:
					if x[PART_FS_TYPE] & FS_SWAP:
						ret += myExecute("swapoff " + x[PART_DEVPATH])
						continue
					if x[PART_FS_TYPE] & FS_LUKS:
						if pathExists("/dev/mapper/" + x[PART_UUID]):
							ret += myExecute("cryptsetup luksClose %s" %x[PART_UUID])
					ret += libgeminimain.gFunktion(UMOUNTPART, x[PART_DEV])
		else:
			ret += libgeminimain.gFunktion(UMOUNTPART, dev[DEV_DEV])
		if ret:
			self.session.open(MessageBox, _("Unmount failed!"), MessageBox.TYPE_ERROR, timeout=5)
		return ret

#---------------------------------------------------------------------------------------

class PartitionsManager(WidgetVariableList):
	def __init__(self, session, device):
		from Components.MultiContent import MultiContentEntryPixmapAlphaBlend
		extra = MultiContentEntryPixmapAlphaBlend(pos=(45, 5), size=(22, 22), png=2)
		WidgetVariableList.__init__ (self, session, _("Partitions Manager"), ListIcon=(66,66), LinesProEntry=4, ExtraTemplate=extra, NameBlue=_("Menu"), icon="icon_devicemanager.png")
		self.skinName = [self.__class__.__name__,"VariableList3Button_" + self.__class__.__name__,"VariableList3Button"]
		self.__device = device
		self.__Cryptsetup = pathExists("/usr/sbin/cryptsetup")
		self.__Parted = pathExists("/usr/sbin/parted")
		self.Console = Console()
		
		self["HelpActions"] = ActionMap(["HelpActions"],
		{
			"displayHelp": self.KeyHelp
		}, -1)
		
		geventNotifier.append((EVENT_BACKGROUND, self.__newBGEvent))
		geventNotifier.append((EVENT_HARDWARE, self.__hardwareEvent))

		self.onLayoutFinish.append(self.__firstStart)


	def KeyExit(self):
		self.Console.killAll()
		geventNotifier.remove((EVENT_BACKGROUND, self.__newBGEvent))
		geventNotifier.remove((EVENT_HARDWARE, self.__hardwareEvent))
		self.close()
		
	def KeyHelp(self):
		self.session.open(MessageBox, _("To delete or create partitions, please go to last entry."), MessageBox.TYPE_INFO)
		
	def __firstStart(self):
		self.__checkFormatRunning(libgeminimain.getBGstatus())
		self.__fillListe()

	def __hardwareEvent(self, what=0, val=""):
		self.__fillListe()
		self.selectionChanged()
		
	def __newBGEvent(self, what=0, val=0):
		if what == EVENT_BACKGROUND:
			self.__checkFormatRunning(val)
			self.__fillListe()
				
	def __checkFormatRunning(self,val):
		self.SetLabel()
		if val & BG_SYSTEM and [tup for tup in currthread if tup[1] == C_FORMAT]:
			self.SetLabel(_("Creating the filesystem, please wait!"))

	def __fillListe(self):
		#print "filllist____________________________"
		lastposition=0
		lastIndex = self.GetIndex()
		list = []
		for x in libgeminimain.getPyList(GETPARTLIST, self.__device[DEV_DEV]):
			#print x
			picbig = x[PART_PIC]
			if x[PART_FS_TYPE] & FS_LUKS and pathExists("/dev/mapper/" + x[PART_UUID]):
				picbig = "dev_luks_unlocked.png"
			picsmall = "logo_unmounted.png"
			if x[PART_ISMOUNTED]:
				picsmall = "logo_mounted.png"

			tstr = ""
			if x[PART_MPOINT]:
				tstr += _("Mountpoint") + ": " + x[PART_MPOINT] + " (" + x[PART_FS] + ")\n"
			else:
				if x[PART_FS_TYPE] & FS_LUKS:
					tstr += _("Filesystem") + ": " + "encrypted" + "\n"
				else:
					tstr += _("Filesystem") + ": " + x[PART_FS] + "\n"
			tstr += _("Device") + ": " + x[PART_DEVPATH] + " (" + HumanSize(x[PART_CAPA]) + ")\n"
			if x[PART_ISMOUNTED]:
				tstr += "%s: (%s %s %s %s %s %s)\n" % (_("Size"), _("total"), HumanSize(x[PART_T_SIZE]), _("used"), HumanSize(x[PART_U_SIZE]), _("free"), HumanSize(x[PART_F_SIZE]))
				if x[PART_OPTIONS] != "":
					tstr += _("Parameters") + ": " + x[PART_OPTIONS]
			else:
				if x[PART_VOLUME]:
					tstr += _("Label") + ": " + x[PART_VOLUME]
				elif x[PART_UUID]:
					tstr += "UUID: " + x[PART_UUID]
			list.append((tstr, gLoadPixmap(picbig), gLoadPixmap(picsmall), x))
			lastposition=x[PART_START] + x[PART_CAPA]

		name = self.__device[DEV_DEV]
		if self.__device[DEV_MODEL]:
			name = self.__device[DEV_MODEL]
		free = _("nothing")
		if self.__device[DEV_SIZE] - lastposition > 1024:#mehr wie 1kB muss frei sein
			free = HumanSize(self.__device[DEV_SIZE] - lastposition)
		self.SetLabel("%s: %s    %s: %s    %s: %s" %(_("Device"), name, _("Size"), HumanSize(self.__device[DEV_SIZE]), _("free"), free))
		
		self.SetList(list)
		self.SetIndex(lastIndex)
		
	def selectionChanged(self):
		self.SetRB()
		self.SetGB()

		sel = self.getCurrentEntry()
		if sel and sel[3]:
			if sel[3][PART_ISMOUNTED]:
				self.SetRB(_("Unmount"))
			else:
				self.SetGB(_("Mount"))

	def KeyRed(self):#umount
		sel = self.getCurrentEntry()
		if sel and sel[3] and sel[3][PART_ISMOUNTED]==1:
			self.__myUnMount(sel[3])

	def KeyGreen(self):#mount
		sel = self.getCurrentEntry()
		if sel and sel[3] and sel[3][PART_ISMOUNTED]==0:
			self.__myMount(sel[3])

	def __myMount(self, dev):#mount
		ret=0
		if dev[PART_FS_TYPE] & FS_LUKS:
			if pathExists("/dev/mapper/" + dev[PART_UUID]):
				ret += libgeminimain.gFunktion(MOUNTPART, "mapper/" + dev[PART_UUID])
			else:
				if self.__Cryptsetup==False:
					self.session.open(MessageBox, _("Package '%s' not installed!") %"cryptsetup", MessageBox.TYPE_ERROR, timeout=5)
					return 1
				else:
					self.session.openWithCallback(boundFunction(self.__passwordCallback,dev), WidgetInput, title=_("Set password"), entryname=_("Password"))
		else:
			ret += libgeminimain.gFunktion(MOUNTPART, dev[PART_DEV])
		if ret != 0:
			self.session.open(MessageBox, _("Failed mount by '%s'") %dev[PART_DEVPATH], MessageBox.TYPE_ERROR, timeout=5)
		return ret
			
	def __myUnMount(self, dev):#umount
		ret=0
		if dev[PART_FS_TYPE] & FS_SWAP:
			ret += myExecute("swapoff " + dev[PART_DEVPATH],self.session)
			self.__fillListe()
		elif dev[PART_FS_TYPE] & FS_LUKS:
			if self.__Cryptsetup==False:
				self.session.open(MessageBox, _("Package '%s' not installed!") %"cryptsetup", MessageBox.TYPE_ERROR, timeout=5)
				return 1
			ret += libgeminimain.gFunktion(UMOUNTPART, "mapper/" + dev[PART_UUID])
			if ret==0:#luks schließen
				if pathExists("/dev/mapper/" + dev[PART_UUID]):
					ret += self.__closeLuks(dev)
		else:
			ret += libgeminimain.gFunktion(UMOUNTPART, dev[PART_DEV])
			ret += libgeminimain.gFunktion(UMOUNTPART, "disk/by-uuid/"+dev[PART_UUID])
		if ret != 0:
			self.session.open(MessageBox, _("Unmount failed!"), MessageBox.TYPE_ERROR, timeout=5)
		return ret

	def KeyBlue(self):
		menu=[]
		sel = self.getCurrentEntry()
		if sel and sel[3]:
			if sel[3][PART_FS_TYPE] & FS_SWAP:
				if cgevent.getConfig("swap_automount",1):
					menu.append(("%s%s %s *" %("Swap-",_("Partition mount automatically?"),_("on")),"auto_swap_on", None))
					menu.append(("%s%s %s" %("Swap-",_("Partition mount automatically?"),_("off")),"auto_swap_off", None))
				else:
					menu.append(("%s%s %s" %("Swap-",_("Partition mount automatically?"),_("on")),"auto_swap_on", None))
					menu.append(("%s%s %s *" %("Swap-",_("Partition mount automatically?"),_("off")),"auto_swap_off", None))
			else:
				menu.append((_("speed test"),"speedtest", sel[3]))
				menu.append((_("check filesystem"),"checkfilesystem", sel[3]))
				menu.append((_("set new Label"),"label", sel[3]))
				if sel[3][PART_FS_TYPE] & FS_LUKS and self.__Cryptsetup and pathExists("/dev/mapper/" + sel[3][PART_UUID]):
					menu.append((_("various information"),"luksinfo", sel[3]))
				menu.append(("--","--"))
				menu.append((_("formatting"),"format", sel[3]))
				
				if sel[3][PART_FS_TYPE] & FS_LUKS:
					if pathExists("/dev/mapper/" + sel[3][PART_UUID]) and sel[3][PART_ISMOUNTED]==0:
						menu.append(("--","--"))
						menu.append((_("close encryption"),"closecrypt", sel[3]))

		#Partitionen hinzufügen oder löschen wenn letzter Eintrag oder kein Eintrag
		if self.GetIndex() == len(self.GetList())-1 or len(self.GetList())==0:
			if self.__Parted:
				if len(menu):
					menu.append(("--","--"))
				if sel and sel[3]:
					menu.append((_("remove %s?") %_("Partition"),"removepart", sel[3]))
					freesize = self.__device[DEV_SIZE] - (sel[3][PART_START] + sel[3][PART_CAPA])
					if sel[3][PART_NUMBER]<4 and freesize>1024*1024:#max 4 Parts, min 1MB frei
						menu.append((_("add new Partition"),"addpart", sel[3]))
				else:
					menu.append((_("add new Partition"),"addpart", None))
		if len(menu):
			self.session.openWithCallback(self.__menuCallback, ChoiceBox, list=menu)

	def __menuCallback(self, val=None):
		if val == None:
			return
		device = val[2]
		if val[1]=="speedtest":
			if device[PART_ISMOUNTED]==0:
				if self.__myMount(device)!=0:
					return
			self.session.openWithCallback(boundFunction(self.__speedCallback,device), WidgetInput, title=_("speed test"), entryname= "%s %s (MB)" %(_("Size"),_("testfile")), default=100, limits=(100,2000), greenbutton=_("Start"))
			
		elif val[1]=="checkfilesystem":
			currfs = ctoolsclass.getFilesystemData(device[PART_FS])
			com=False
			if currfs and currfs[ctoolsclass.FS_FSCK]:
				if device[PART_FS_TYPE] & FS_LUKS:
					com=currfs[ctoolsclass.FS_FSCK] %("/dev/mapper/" + device[PART_UUID])
				else:
					com=currfs[ctoolsclass.FS_FSCK] %device[PART_DEVPATH]
			if com!=False:
				if device[PART_ISMOUNTED]==1:
					ret =self.__myUnMount(device)
					if ret > 0:
						return
				self.session.openWithCallback(boundFunction(self.__checkCallback,(com,device)), MessageBox, _("start %s") %_("check filesystem") + " ...\n" + _("That can last some time."))
		elif val[1]=="label":
			currfs = ctoolsclass.getFilesystemData(device[PART_FS])
			com=False
			if currfs and currfs[ctoolsclass.FS_TOOL]:
				com=currfs[ctoolsclass.FS_TOOL]
			if com!=False:
				if device[PART_ISMOUNTED]==1:
					ret =self.__myUnMount(device)
					if ret > 0:
						return
				self.session.openWithCallback(boundFunction(self.__labelCallback,(com,device)), WidgetInput, title=_("set new Label"), entryname=_("Device Label"), default=device[PART_VOLUME])
			else:
				self.session.open(MessageBox, _("set volume label") + "\n..." + _("not available"), MessageBox.TYPE_ERROR, timeout=5)
		elif val[1]=="format":
			if device[PART_ISMOUNTED]==1:
				if self.__myUnMount(device)==1:
					return
			elif device[PART_FS_TYPE] & FS_LUKS and pathExists("/dev/mapper/" + device[PART_UUID]):
				self.__closeLuks(device)
			self.session.openWithCallback(boundFunction(self.__formatCallback,device), Cformat, None, self.__Cryptsetup)
		#elif val[1]=="encrypt":
		#	self.session.openWithCallback(boundFunction(self.__encryptCallback,device), MessageBox, _("Attention!") + "\n" + _("Are you sure want to delete?\n\n") + _("Partition") + ": " + device[PART_DEV] + "\n\n" + _("All data on the partition will be lost!"))
		elif val[1]=="closecrypt":
			self.__closeLuks(device)
			self.__fillListe()
		elif val[1]=="auto_swap_on":
			cgevent.setConfig("swap_automount",1)
		elif val[1]=="auto_swap_off":
			cgevent.setConfig("swap_automount",0)
		elif val[1]=="removepart":
			self.session.openWithCallback(boundFunction(self.__remove_partCallback,device), MessageBox, _("Attention!") + "\n" + _("Are you sure want to delete?\n\n") + _("Partition") + ": " + device[PART_DEV] + "\n\n" + _("All data on the partition will be lost!"))
		elif val[1]=="addpart":
			freesize = self.__device[DEV_SIZE]
			if device:
				freesize = self.__device[DEV_SIZE] - (device[PART_START] + device[PART_CAPA])
			self.session.openWithCallback(boundFunction(self.__add_partCallback,device), Cformat, freesize, self.__Cryptsetup)
		elif val[1]=="luksinfo":
			from InfoScreens import LuksInfo
			self.session.open(LuksInfo, "/dev/mapper/" + device[PART_UUID])

	def __speedCallback(self, device, val):
		if val is not None:
			from InfoScreens import SpeedcheckInfo
			self.session.open(SpeedcheckInfo, device[PART_MPOINT] + "/.speedtestfile", str(val))

	def __remove_partCallback(self, device, start=False):
		if start:
			ret=0
			if device[PART_ISMOUNTED]==1:
				ret = self.__myUnMount(device)
			if device[PART_FS_TYPE] & FS_LUKS and self.__Cryptsetup:
				ret = self.__closeLuks(device)
			if ret==0:
				libgeminimain.setHWLock(1)
				cmd = "parted -s -a none %s rm %d && partprobe" %(self.__device[DEV_DEVPATH], device[PART_NUMBER])
				self.SetLabel(_("Please wait..."))
				self.Console.ePopen(cmd, self.__FinishedRemove)

	def __FinishedRemove(self, result, retval, extra_args = None):
		if retval==0:
			self.__fillListe()
		else:
			self.session.open(MessageBox, result, MessageBox.TYPE_ERROR, timeout=10)
			self.SetLabel()
		libgeminimain.setHWLock(0)
		
	def __add_partCallback(self, device, formatdata):
		cmd = ""
		if formatdata:
			size = formatdata[2]
			if device:
				startpos = device[PART_START] + device[PART_CAPA] + 1
				startprefix ="B"
				endprefix ="B"
				endpos = startpos+size
			else:
				startpos = 2048
				startprefix ="s"
				cmd += "parted --script %s mklabel gpt;"%self.__device[DEV_DEVPATH]
				endpos = size
				endprefix ="B"
				
			if size >= self.__device[DEV_SIZE] -1024*1024*20:
				endpos = 100
				endprefix ="%"
				
			#print ">>>>>>>>>>>>>>>>>>>>>>>>>>>",startpos,endpos,size,self.__device[DEV_SIZE], formatdata
			if size > 0 and endpos <= self.__device[DEV_SIZE]:
				libgeminimain.setHWLock(1)
				cmd += "parted --script --align=opt %s -- mkpart primary %s %d%s %d%s && partprobe" %(self.__device[DEV_DEVPATH], formatdata[0][0], startpos, startprefix, endpos, endprefix)
				self.SetLabel(_("Please wait..."))
				#print ">>>>>>>>>>>>>>>>>>>>>>>>>>>",cmd
				self.Console.ePopen(cmd, boundFunction(self.__FinishedAdd,(device,formatdata)))
				
	def __FinishedAdd(self, data, result, retval, extra_args = None):
		if retval==0:
			olddevice = data[0]
			formatdata = data[1]
			device=None
			for x in libgeminimain.getPyList(GETPARTLIST, self.__device[DEV_DEV]):
				device = x
			if device:
				if olddevice and olddevice[PART_DEVPATH] == device[PART_DEVPATH]:
					self.session.open(MessageBox, _("Create new partition!"), MessageBox.TYPE_ERROR, timeout=10)
					return
				self.__formatCallback(device,formatdata)
		else:
			self.session.open(MessageBox, _("Create new partition!") + "\n" + result, MessageBox.TYPE_ERROR, timeout=10)
		self.SetLabel()
		libgeminimain.setHWLock(0)

	def __checkCallback(self, data, val=False):
		if val:
			self.session.openWithCallback(boundFunction(self.__comCallback,data),ShowFileList, cmdlist=[data[0]])
			
	def __comCallback(self, data, val=None):
		device = data[1]
		if device[PART_ISMOUNTED]==1:
			self.__myMount(device)

	def __labelCallback(self, data, name):
		command = data[0]
		device = data[1]
		if name is not None:
			name = name.replace(" ", "_")
			
			if name != device[PART_VOLUME]:
				if device[PART_FS_TYPE] & FS_LUKS:
					com = command %(name, "/dev/mapper/" + device[PART_UUID])
				else:
					com = command %(name,device[PART_DEVPATH])
				if myExecute(com, self.session)==0:
					if device[PART_ISMOUNTED]==1:
						self.__myMount(device)
					else:
						self.__fillListe()
				else:
					self.session.open(MessageBox, _("Create new label failed!"), MessageBox.TYPE_ERROR, timeout=5)
		else:
			if device[PART_ISMOUNTED]==1:
				self.__myMount(device)

	def __formatCallback(self,device,formatdata):
		if formatdata:
			ret = 0
			currfs = formatdata[0]
			newname = formatdata[1]
			passwd = formatdata[3]
			largefile = formatdata[4]

			if passwd:
				ret = self.__createLuks(device,passwd)
				if ret==0:#neu einlesen wegen neuer UUID
					oldevice=device
					device=None
					for x in libgeminimain.getPyList(GETPARTLIST, self.__device[DEV_DEV]):
						if x[PART_DEVPATH] == oldevice[PART_DEVPATH]:
							device = x
							ret = self.__openLuks(x, passwd)
			
			if currfs and device and ret==0:
				if device[PART_FS_TYPE] & FS_LUKS and passwd:
					cmd = "%s%s %s" %(currfs[ctoolsclass.FS_MAKE], largefile, "/dev/mapper/" + device[PART_UUID])
					if newname != "":# + umbenennen
						cmd += " && "
						cmd += currfs[ctoolsclass.FS_TOOL] %(newname,"/dev/mapper/" + device[PART_UUID])
				else:
					cmd = "%s%s %s" %(currfs[ctoolsclass.FS_MAKE], largefile, device[PART_DEVPATH])
					if newname != "":# + umbenennen
						cmd += " && "
						cmd += currfs[ctoolsclass.FS_TOOL] %(newname,device[PART_DEVPATH])
			
				self.SetLabel(_("Please wait...") + " " + _("formatting"))
				kwargs={'func': C_FORMAT, 'command': cmd}
				BackGroundThread(kwargs)
		else:
			if device[PART_ISMOUNTED]==1:
				self.__myMount(device)
				
	def __passwordCallback(self,device,password):
		if password is not None and password!="":
			if self.__openLuks(device, password)==0:
				self.__myMount(device)

	def __createLuks(self, device, passwd):
		com = "echo -n '%s' | cryptsetup -q -c aes-cbc-essiv:sha256 -s 256 luksFormat %s" %(passwd,device[PART_DEVPATH])
		return myExecute(com, self.session)

	def __openLuks(self, device, password):
		ret=0
		if pathExists("/dev/mapper/" + device[PART_UUID])==False:
			com = "echo -n '%s' | cryptsetup luksOpen %s %s" %(password, device[PART_DEVPATH], device[PART_UUID])
			ret = myExecute(com, self.session)
		return ret

	def __closeLuks(self,device):
		ret=0
		if pathExists("/dev/mapper/" + device[PART_UUID]):
			ret = myExecute("cryptsetup luksClose %s" %device[PART_UUID], self.session)
		return ret
	
	#def __encryptCallback(self, device, ret=False):
	#	if ret:
	#		if device[PART_ISMOUNTED]==1:
	#			ret =self.__myUnMount(device)
	#			if ret > 0:
	#				return
	#		self.session.openWithCallback(boundFunction(self.__createLuks,device), Cformat, passwd="foobar")

	#def __passwordandformatCallback(self,device,password):
	#	if password is not None and password!="":
	#		if self.__openLuks(device,password)==0:
	#			self.session.openWithCallback(boundFunction(self.__formatCallback,device), Cformat)
