Newer
Older
Import / projects / LGN-IP3870 / t / orig / callhistory.py
from basemodel import Stage, NotifyStage, ListStage, YesNoStage
import baseui, config, uiconfig, runtime, calldb, time, phonebook, status
from phonedb import phonedb
from setting import setting

call_history_type = 'dialed', 'missed', 'received'

class CallHistoryStage(Stage):
	name = 'callhistory'
	def __init__(self, call_type, vm_flag=False, call_flag=False):
		# 진입만 해도 무조건 확인한 것으로 취급
		status.missed_call_count = 0
		self.vm_flag = vm_flag
		self.call_flag = call_flag
		self.choice_updated = False
		self.call_type = call_type

		if self.call_type != 'recent':
			self.calllist = calldb.get_list(self.call_type)
			choice = self.get_names(self.calllist)
			icon = self.make_icon(self.calllist)
			call_duration, calling_time, number = self.get_infos(self.calllist)
		else:
			choice, icon, call_duration, calling_time, number = self.make_recent_list()
		if self.call_flag:
			left = ''
		else:
			left = None
		if call_type == 'recent':
			self.ui = baseui.CallHistoryUI(subtitle=_('RECENT CALL'))
		elif call_type == 'received':
			self.ui = baseui.CallHistoryUI(subtitle=_('RECEIVED CALL'))
		elif call_type == 'dialed':
			self.ui = baseui.CallHistoryUI(subtitle=_('DIALED CALL'))
		elif call_type == 'missed':
			self.ui = baseui.CallHistoryUI(subtitle=_('MISSED CALL'))

		self.ui.set_list(choice, icon, call_duration, calling_time, number)

	def show(self):
		if self.vm_flag or self.call_flag:
			self.ui.set_left('')
		if self.choice_updated:
			focus = self.ui.get_focus()
			if self.call_type != 'recent':
				self.calllist = calldb.get_list(self.call_type)
				choice = self.get_names(self.calllist)
				icon = self.make_icon(self.calllist)
				call_duration, calling_time, number = self.get_infos(self.calllist)
			else:
				choice, icon, call_duration, calling_time, number = self.make_recent_list()
			self.ui.update_lists(choice, icon, call_duration, calling_time, number)
			#focus = self.ui.get_focus()
			if focus > len(choice)-1:
				self.ui.list.set_focus(len(choice)-1)
				self.ui.update_info(len(choice)-1)
			else:
				self.ui.list.set_focus(focus)
				self.ui.update_info(focus)
			self.choice_updated = False
		Stage.show(self)

	def make_recent_list(self):
		self.calllist = []
		choice = []
		icon = []
		call_duration = []
		calling_time = []
		pb_snapshot = []
		
		for i in range(3):
			sub_calllist = calldb.get_list(call_history_type[i])	# make individual list
			if len(sub_calllist):		# make total list
				for i in range(len(sub_calllist)):
					self.calllist.append(sub_calllist[i])

		# sorting
		self.sort()

		# make ui info
		choice = self.get_names(self.calllist)
		icon = self.make_icon(self.calllist)
		call_duration, calling_time, number = self.get_infos(self.calllist)

		return choice, icon, call_duration, calling_time, number
				
	def sort(self):
		def sort_func(x, y):
			xname = x[2]
			yname = y[2]
			return -(cmp(xname, yname))	# newer time is upper
		self.calllist.sort(sort_func)
		
	def get_names(self, calllist):
		choice = []
		for number, calltype, calltime, snapshot, index in calllist:
			if number == 'P' or number == '':
				choice.append(_('No identification'))
			elif number == 'O':
				choice.append(_('Not available'))
			else:
				choice.append(number)
		return choice

	def get_infos(self, calllist):
		call_duration = []
		calling_time = []
		number_list = []

		#runtime.mmiDebug.mmiTrace('########### calllist = ', calllist)
		for number, calltype, calltime, snapshot, index in calllist:
			detail = calldb.get_detail(call_history_type[calltype], index)
			if detail.video_time:
				#duration
				sec = detail.video_duration % 60
				min = (detail.video_duration / 60) % 60 
				hour = (detail.video_duration / 60) / 60
				duration = "%02d:%02d:%02d" % (hour, min, sec)
				call_duration.append(duration)
				# calling_time
				year, mon, day, hour, min, sec = time.localtime(detail.video_time)[:6]
			else:
				#duration
				sec = detail.duration % 60
				min = (detail.duration / 60) % 60 
				hour = (detail.duration / 60) / 60
				duration = "%02d:%02d:%02d" % (hour, min, sec)
				call_duration.append(duration)
				# calling_time
				year, mon, day, hour, min, sec = time.localtime(detail.time)[:6]
			date = "%02d/%02d" % (mon, day)
			if hour > 12:
				#call_time = "%02d:%02dPM" % ((hour-12), min)
				call_time = "%s%02d:%02d" % (_('PM'), (hour-12), min)
			elif hour == 12:
				#call_time = "%02d:%02dPM" % (hour, min)
				call_time = "%s%02d:%02d" % (_('PM'), hour, min)
			elif hour == 0:
				#call_time = "%02d:%02dAM" % ((hour+12), min)
				call_time = "%s%02d:%02d" % (_('AM'), (hour+12), min)
			else:
				#call_time = "%02d:%02dAM" % (hour, min)
				call_time = "%s%02d:%02d" % (_('AM'), hour, min)
			calling_time.append(date + ' ' + call_time)

			# number
			number_list.append(detail.number)

		return call_duration, calling_time, number_list

	def make_icon(self, calllist):
		callhistory_icons = []
		for number, calltype, calltime, snapshot, index in calllist:
			detail = calldb.get_detail(call_history_type[calltype], index)
			type = detail.call_type
			if detail.video_time:	# videocall				
				if type == calldb.CALL_MISSED:
					if setting.in_restrict:
						restrict_flag = False
						for item in setting.in_restrict_nums:
							if detail.number == item:
								restrict_flag = True
								break

						if restrict_flag:								
							callhistory_icons.append(uiconfig.list_icon_call_history_restrict_video )
						else:
							callhistory_icons.append(uiconfig.list_icon_call_history_missed_video )	
					else:
						callhistory_icons.append(uiconfig.list_icon_call_history_missed_video )
				elif type == calldb.CALL_RECEIVED:
					callhistory_icons.append(uiconfig.list_icon_call_history_received_video )
				elif type == calldb.CALL_DIALED:
					callhistory_icons.append(uiconfig.list_icon_call_history_dialed_video )
			else:	# voicecall
				if type == calldb.CALL_MISSED:
					if setting.in_restrict:
						restrict_flag = False
						for item in setting.in_restrict_nums:
							if detail.number == item:
								restrict_flag = True
								break

						if restrict_flag:								
							callhistory_icons.append(uiconfig.list_icon_call_history_restrict_voice )
						else:
							callhistory_icons.append(uiconfig.list_icon_call_history_missed_voice )	
					else:
						callhistory_icons.append(uiconfig.list_icon_call_history_missed_voice )				
				elif type == calldb.CALL_RECEIVED:
					callhistory_icons.append(uiconfig.list_icon_call_history_received_voice )
				elif type == calldb.CALL_DIALED:
					callhistory_icons.append(uiconfig.list_icon_call_history_dialed_voice )

		return callhistory_icons

	def change_choice(self):
		self.choice_updated = True

	def handle_key(self, key):
		if self.vm_flag:
			if key in (config.Red, config.Menu4, 'CLR'):
				#runtime.eaHandler.deactivateApplication()
				#runtime.manager.back_stage()
				runtime.eaHandler.endCall()
				return True
			elif key in (config.OffHook, config.Green, config.Video, config.Menu2, config.Menu3):
				stage = NotifyStage(_('Please finish using feature(web browser, message, media player).'), vm_flag=True)
				runtime.manager.stack_stage(stage)
				return True
			elif key in (config.Menu1, config.OnHook, 'OK'):
				return True
		if self.call_flag:
			if key in (config.Menu1, 'OK'):
				return True			
			elif key in (config.OnHook, config.Red):
				runtime.manager.back_stage()
				return True
				
		if key == config.Menu1:
			if len(self.calllist):
				if self.call_type != 'recent':
					mesg_detail = calldb.get_detail(self.call_type, self.calllist[self.ui.get_focus()][4])
					mesg_name = self.calllist[self.ui.get_focus()][0]
				else:
					mesg_detail = calldb.get_detail(call_history_type[self.calllist[self.ui.get_focus()][1]], self.calllist[self.ui.get_focus()][4])			
					mesg_name = self.calllist[self.ui.get_focus()][0]
				if mesg_name == mesg_detail.number:
					pbname = ''
				else:
					pbname = mesg_name
				self.change_choice()
				runtime.manager.stack_stage(CallHistoryOptionStage(number=mesg_detail.number, pbname=pbname, call_type=self.call_type, call_index=self.ui.get_focus()))
			return True
		#elif key == config.Menu2 or key == 'Left':
		elif key == 'Left':
		
			if self.call_type =='recent':
				runtime.manager.change_stage(CallHistoryStage('missed', self.vm_flag, self.call_flag))
			elif self.call_type =='missed':
				runtime.manager.change_stage(CallHistoryStage('dialed', self.vm_flag, self.call_flag))
			elif self.call_type =='dialed':
				runtime.manager.change_stage(CallHistoryStage('received', self.vm_flag, self.call_flag))
			elif self.call_type =='received':
				runtime.manager.change_stage(CallHistoryStage('recent',self.vm_flag,self.call_flag))
			return True
		#elif key == config.Menu3 or key == 'Right':
		elif key == 'Right':
			if self.call_type =='recent':
				runtime.manager.change_stage(CallHistoryStage('received', self.vm_flag, self.call_flag))
			elif self.call_type =='received':
				runtime.manager.change_stage(CallHistoryStage('dialed', self.vm_flag, self.call_flag))
			elif self.call_type =='dialed':
				runtime.manager.change_stage(CallHistoryStage('missed', self.vm_flag, self.call_flag))
			elif self.call_type =='missed':
				runtime.manager.change_stage(CallHistoryStage('recent', self.vm_flag, self.call_flag))
			return True
		elif key == 'CLR' or key == config.Menu4:
			#runtime.manager.back_stage('phonebook')
			runtime.manager.back_stage()
			return True
		elif key == 'OK':
			if len(self.calllist):
				if self.call_type != 'recent':
					status.calldb_editing_detail = calldb.get_detail(self.call_type, self.calllist[self.ui.get_focus()][4])
				else:
					status.calldb_editing_detail = calldb.get_detail(call_history_type[self.calllist[self.ui.get_focus()][1]], self.calllist[self.ui.get_focus()][4])
				if phonedb.has_number(status.calldb_editing_detail.number):
					stage = phonebook.PhonebookNotifyStage(_('Number already in phonebook'))
				elif phonedb.count() >= config.phone_db_size:
					stage = phonebook.PhonebookNotifyStage(_('Memory full'))
				elif status.calldb_editing_detail.number == '':
					stage = phonebook.PhonebookNotifyStage(_('No number available'))
				elif len(status.calldb_editing_detail.number) > 20:
					stage = phonebook.PhonebookNotifyStage(_('Max 20 characters exceeded'))
				else:
					stage = phonebook.AddPhoneBookStage(number = status.calldb_editing_detail.number)
					self.change_choice()
				runtime.manager.stack_stage(stage)				
			return True	
		elif key == config.Menu2 or key == config.Green:
			if len(self.calllist):
				if self.call_type != 'recent':
					mesg_detail = calldb.get_detail(self.call_type, self.calllist[self.ui.get_focus()][4])
				else:
					mesg_detail = calldb.get_detail(call_history_type[self.calllist[self.ui.get_focus()][1]], self.calllist[self.ui.get_focus()][4])			
				status.dial_number = mesg_detail.number
				self.handle_call(False)
			return True
		elif key == config.Menu3 or key == config.Video:
			if len(self.calllist):
				if self.call_type != 'recent':
					mesg_detail = calldb.get_detail(self.call_type, self.calllist[self.ui.get_focus()][4])
				else:
					mesg_detail = calldb.get_detail(call_history_type[self.calllist[self.ui.get_focus()][1]], self.calllist[self.ui.get_focus()][4])			
				status.dial_number = mesg_detail.number
				self.handle_call(True)
			return True
		else:
			return self.ui.handle_key(key)

	def handle_call(self, video_call=False):
		from runtime import mmiDebug as MD
		if status.video_mode != status.VideoIdle:
			MD.mmiTrace('PHONEBOOK dialing: cancel(CALL)')
			return
		if not status.dial_number:
			return	
			
		#status.dial_number = self.ui.get_priority_number()
		runtime.mmedia.unload()
		
		MD.mmiTrace('status.dial_number = ', status.dial_number)
		from mmiSoundPath import SP_State, Device, SP_Context
		from dectHandler import DectCallManager
		
		status.videocall_byuser = video_call
		
		dectStatus = runtime.dectCallManager.getDectStatus()
		if status.dial_number and dectStatus == DectCallManager.IDLE:
			spkOffHook = runtime.SP_context.SPK_OffHook(dialNumber=True)
		else:
			spkOffHook = runtime.SP_context.SPK_OffHook(dialNumber=False)
		if spkOffHook.next():
			if spkOffHook.next():
				if dectStatus == DectCallManager.IDLE:
					runtime.mmiDebug.mmiTrace('call start')
					#runtime.vdci_stop_tone()
					runtime.SP_context.stopTonePlay()
					runtime.SP_context.setBaseStatus(SP_Context.DIALING)
					if status.videocall_byuser:
						runtime.manager.start_call(number=status.dial_number, video_call=True)
					else:
						runtime.manager.start_call(number=status.dial_number, video_call=False)
				else:
					if dectStatus == DectCallManager.IDLE:
						runtime.SP_context.speaker.setTone(config.PLAY_DIAL_TONE)				
					else:
						runtime.SP_context.speaker.setTone(config.PLAY_BUSY_TONE)				
					runtime.SP_context.startTonePlay()								
			else:
				if spkOffHook.next():
					status.dial_number = ''
					status.dialed_by_user = False

					#runtime.vdci_stop_tone()
					runtime.SP_context.stopTonePlay()
					runtime.manager.stop_call(IdleStage)
				else:
					spkOffHook.next() # SP_HS_OffHook_SPK_OffHook 상태를 위한 것.
					if dectStatus == DectCallManager.IDLE:
						runtime.SP_context.speaker.setTone(config.PLAY_DIAL_TONE)				
					else:
						runtime.SP_context.speaker.setTone(config.PLAY_BUSY_TONE)				
					runtime.SP_context.startTonePlay()	


class CallHistoryOptionStage(ListStage):
	def __init__(self, number=None, pbname=None, call_type=None, call_index=None):
		self.choice = _('MSG SEND'), _('Phonebook new'), _('DELETE'), _('Delete all calls')
		self.title = _('OPTIONS')

		ListStage.__init__(self)
		self.number = number
		self.pbname = pbname
		self.call_type = call_type
		self.call_index = call_index
		
	def activate(self, index):
		if index == 0:
			if self.number == None or self.pbname == None:
				return False
			if self.number == '':
				stage = phonebook.PhonebookNotifyStage(_('No number available'))
				runtime.manager.stack_stage(stage)
				return False
			if len(self.number) > 20:
				stage = phonebook.PhonebookNotifyStage(_('Max 20 characters exceeded'))
				runtime.manager.stack_stage(stage)
				return True
			from eaHandler import EaHandler				
			runtime.eaHandler.sendMmsMessageInMmi(self.number, self.pbname)

			
		elif index == 1:
			if self.number == None or self.pbname == None:
				return False
			if phonedb.has_number(self.number):
				stage = phonebook.PhonebookNotifyStage(_('Number already in phonebook'))
			elif phonedb.count() >= config.phone_db_size:
				stage = phonebook.PhonebookNotifyStage(_('Memory full'))
			elif self.number == '':
				stage = phonebook.PhonebookNotifyStage(_('No number available'))
			elif len(self.number) > 20:
				stage = phonebook.PhonebookNotifyStage(_('Max 20 characters exceeded'))
			else:
				stage = phonebook.AddPhoneBookStage(number = self.number)
				pre_stage = runtime.manager.find_stage('callhistory')
				if pre_stage:
					pre_stage.change_choice()
			runtime.manager.stack_stage(stage)				
		elif index == 2:
			if self.call_type == None or self.call_index == None:
				return False
			runtime.manager.stack_stage(CallHistoryDeleteYesNoStage(delete_all=False, call_type=self.call_type, call_index=self.call_index))
		elif index == 3:
			runtime.manager.stack_stage(CallHistoryDeleteYesNoStage(delete_all=True, call_type=self.call_type))
		else:
			pass
		

class CallHistoryDeleteYesNoStage(YesNoStage):
	title = _('DELETE')
	icon = uiconfig.baloon_call_log_delete_icon
	def __init__(self, delete_all=True, call_type='', call_index=0):
		self.delete_all = delete_all
		self.call_type = call_type
		self.call_index = call_index
		YesNoStage.__init__(self, _('Delete this entry?'), self.yes_cb, self.no_cb, '', self.icon)

	def yes_cb(self):
		if self.delete_all:
			def destory_all():
				missed_lists = calldb.get_list('missed')
				dialed_lists = calldb.get_list('dialed')
				received_lists = calldb.get_list('received')			
				if (len(missed_lists) == 0) and (len(dialed_lists) == 0) and (len(received_lists) == 0):
					stage = NotifyStage(_('Empty call history'), uiconfig.baloon_call_log_icon)
					runtime.manager.change_stage(stage, True)
				else:
					if runtime.manager.find_stage('callhistory'):
						runtime.manager.back_stage('callhistory')
					else:
						from model import IdleStage
						runtime.manager.change_stage(IdleStage, True)
				return False
				
			if self.call_type == 'recent':
				calldb.delete_db('all')
				stage = NotifyStage(_('All calls deleted!'), uiconfig.baloon_call_log_delete_icon, destory_all)
			else:
				calldb.delete_db(self.call_type)
				if self.call_type =='received':
					stage = NotifyStage(_('Recv call history deleted'), uiconfig.baloon_call_log_delete_icon, destory_all)
				elif self.call_type =='dialed':
					stage = NotifyStage(_('Send call history deleted'), uiconfig.baloon_call_log_delete_icon, destory_all)
				else:				
					stage = NotifyStage(_('Missed call history deleted'), uiconfig.baloon_call_log_delete_icon, destory_all)
			runtime.manager.change_stage(stage)
		else:
			def destroy():
				missed_lists = calldb.get_list('missed')
				dialed_lists = calldb.get_list('dialed')
				received_lists = calldb.get_list('received')
				if (len(missed_lists) == 0) and (len(dialed_lists) == 0) and (len(received_lists) == 0):
					stage = NotifyStage(_('Empty call history'), uiconfig.baloon_call_log_icon)
					runtime.manager.change_stage(stage, True)
				else:
					if runtime.manager.find_stage('callhistory'):
						runtime.manager.back_stage('callhistory')
					else:			
						runtime.manager.change_stage(CallHistoryStage(self.call_type))
				return False

			if self.call_type != 'recent':
				calldb.remove_call_log(self.call_type, self.call_index)
			else:
				callhistorystage = runtime.manager.find_stage('callhistory')
				if callhistorystage:
					calldb.remove_call_log(call_history_type[callhistorystage.calllist[self.call_index][1]], callhistorystage.calllist[self.call_index][4])
			stage = NotifyStage(_('Entry deleted'), uiconfig.baloon_call_log_delete_icon, destroy)
			runtime.manager.change_stage(stage)
				
	def no_cb(self):
		runtime.manager.back_stage()