Ejemplo n.º 1
0
	def getEventRow(self, event):
		return (
			event.id,
			pixbufFromFile(event.icon),
			event.summary,
			event.getShownDescription(),
		)
Ejemplo n.º 2
0
	def appendTrash(self):
		self.trashIter = self.trees.append(None, (
			-1,
			pixbufFromFile(ui.eventTrash.icon),
			ui.eventTrash.title,
			"",
		))
		for event in ui.eventTrash:
			self.appendEventRow(self.trashIter, event)
Ejemplo n.º 3
0
	def appendTrash(self):
		self.trashIter = self.trees.append(None, (
			-1,
			pixbufFromFile(ui.eventTrash.icon),
			ui.eventTrash.title,
			'',
		))
		for event in ui.eventTrash:
			self.appendEventRow(self.trashIter, event)
Ejemplo n.º 4
0
	def getEventRow(self, event):
		pixbuf = pixbufFromFile(event.icon)
		if event.icon and pixbuf is None:
			print("getEventRow: invalid icon=%r for event id=%s in group=%s" % (event.icon, event.id, event.parent))
		return (
			event.id,
			pixbuf,
			event.summary,
			event.getShownDescription(),
		)
Ejemplo n.º 5
0
	def editTrash(self, obj=None):
		TrashEditorDialog(parent=self).run()
		self.trees.set_value(
			self.trashIter,
			1,
			pixbufFromFile(ui.eventTrash.icon),
		)
		self.trees.set_value(
			self.trashIter,
			2,
			ui.eventTrash.title,
		)
Ejemplo n.º 6
0
	def editTrash(self, obj=None):
		TrashEditorDialog(parent=self).run()
		self.trees.set_value(
			self.trashIter,
			1,
			pixbufFromFile(ui.eventTrash.icon),
		)
		self.trees.set_value(
			self.trashIter,
			2,
			ui.eventTrash.title,
		)
Ejemplo n.º 7
0
	def _do_search(self):
		if self.groupCheck.get_active():
			groupIds = [
				self.groupCombo.get_active()
			]
		else:
			groupIds = ui.eventGroups.getEnableIds()
		###
		conds = {}
		if self.textCSensCheck.get_active():
			conds["text"] = self.textInput.get_text()
		else:
			conds["text_lower"] = self.textInput.get_text().lower()
		if self.timeFromCheck.get_active():
			conds["time_from"] = self.timeFromInput.get_epoch(calTypes.primary)
		if self.timeToCheck.get_active():
			conds["time_to"] = self.timeToInput.get_epoch(calTypes.primary)
		if self.modifiedFromCheck.get_active():
			conds["modified_from"] = self.modifiedFromInput.get_epoch(calTypes.primary)
		if self.typeCheck.get_active():
			index = self.typeCombo.get_active()
			cls = event_lib.classes.event[index]
			conds["type"] = cls.name
		###
		self.trees.clear()
		for gid in groupIds:
			group = ui.eventGroups[gid]
			for evData in group.search(conds):
				self.trees.append(None, (
					group.id,
					evData["id"],
					group.title,
					pixbufFromFile(evData["icon"]),
					evData["summary"],
					evData["description"],
				))
		self.resultLabel.set_label(
			_("Found %s events") % _(len(self.trees))
		)
Ejemplo n.º 8
0
 def editEventByPath(self, path):
     from scal3.ui_gtk.event.editor import EventEditorDialog
     try:
         gid = self.trees[path][0]
         eid = self.trees[path][1]
     except:
         return
     group = ui.eventGroups[gid]
     event = group[eid]
     event = EventEditorDialog(
         event,
         title=_("Edit ") + event.desc,
         parent=self,
     ).run()
     if event is None:
         return
     ###
     ui.eventDiff.add("e", event)
     ###
     eventIter = self.trees.get_iter(path)
     self.trees.set_value(eventIter, 3, pixbufFromFile(event.icon))
     self.trees.set_value(eventIter, 4, event.summary)
     self.trees.set_value(eventIter, 5, event.getShownDescription())
Ejemplo n.º 9
0
	def editEventByPath(self, path):
		from scal3.ui_gtk.event.editor import EventEditorDialog
		try:
			gid = self.trees[path][0]
			eid = self.trees[path][1]
		except:
			return
		group = ui.eventGroups[gid]
		event = group[eid]
		event = EventEditorDialog(
			event,
			title=_("Edit ") + event.desc,
			parent=self,
		).run()
		if event is None:
			return
		###
		ui.eventDiff.add("e", event)
		###
		eventIter = self.trees.get_iter(path)
		self.trees.set_value(eventIter, 3, pixbufFromFile(event.icon))
		self.trees.set_value(eventIter, 4, event.summary)
		self.trees.set_value(eventIter, 5, event.getShownDescription())
Ejemplo n.º 10
0
 def _do_search(self):
     if self.groupCheck.get_active():
         groupIds = [self.groupCombo.get_active()]
     else:
         groupIds = ui.eventGroups.getEnableIds()
     ###
     conds = {}
     if self.textCSensCheck.get_active():
         conds["text"] = self.textInput.get_text()
     else:
         conds["text_lower"] = self.textInput.get_text().lower()
     if self.timeFromCheck.get_active():
         conds["time_from"] = self.timeFromInput.get_epoch(calTypes.primary)
     if self.timeToCheck.get_active():
         conds["time_to"] = self.timeToInput.get_epoch(calTypes.primary)
     if self.modifiedFromCheck.get_active():
         conds["modified_from"] = self.modifiedFromInput.get_epoch(
             calTypes.primary)
     if self.typeCheck.get_active():
         index = self.typeCombo.get_active()
         cls = event_lib.classes.event[index]
         conds["type"] = cls.name
     ###
     self.trees.clear()
     for gid in groupIds:
         group = ui.eventGroups[gid]
         for evData in group.search(conds):
             self.trees.append(None, (
                 group.id,
                 evData["id"],
                 group.title,
                 pixbufFromFile(evData["icon"]),
                 evData["summary"],
                 evData["description"],
             ))
     self.resultLabel.set_label(_("Found %s events") % _(len(self.trees)))
Ejemplo n.º 11
0
	def __init__(self, wcal):
		from scal3.ui_gtk.utils import pixbufFromFile
		Column.__init__(self, wcal)
		self.connect("draw", self.onExposeEvent)
		self.moonPixbuf = pixbufFromFile("full_moon_48px.png")
		self.showPhaseNumber = False
Ejemplo n.º 12
0
class EventManagerDialog(gtk.Dialog, MyDialog, ud.BaseCalObj):## FIXME
	_name = 'eventMan'
	desc = _('Event Manager')
	def onShow(self, widget):
		self.move(*ui.eventManPos)
		self.onConfigChange()
	def onDeleteEvent(self, obj, gevent):
		## onResponse is going to be called after onDeleteEvent
		## just return True, no need to do anything else
		return True
	def onResponse(self, dialog, response_id):
		ui.eventManPos = self.get_position()
		ui.saveLiveConf()
		###
		self.hide()
		self.emit('config-change')
	#def findEventByPath(self, eid, path):
	#	groupIndex, eventIndex = path
	#
	def onConfigChange(self, *a, **kw):
		ud.BaseCalObj.onConfigChange(self, *a, **kw)
		###
		if not self.isLoaded:
			if self.get_property('visible'):
				self.waitingDo(self.reloadEvents)## FIXME
			return
		###
		for action, eid, gid, path in ui.eventDiff:
			if action == '-':
				try:
					eventIter = self.eventsIter[eid]
				except KeyError:
					if gid in self.loadedGroupIds:
						print('trying to delete non-existing event row, eid=%s, path=%s'%(eid, path))
				else:
					self.trees.remove(eventIter)
			elif action == '+':
				if gid in self.loadedGroupIds:
					parentIndex, eventIndex = path
					#print(gid, self.loadedGroupIds, parentIndex)
					parentIter = self.trees.get_iter((parentIndex,))
					event = ui.getEvent(gid, eid)
					self.insertEventRow(parentIter, eventIndex, event)
			elif action == 'e':
				try:
					eventIter = self.eventsIter[eid]
				except KeyError:
					if gid in self.loadedGroupIds:
						print('trying to edit non-existing event row, eid=%s, path=%s'%(eid, path))
				else:
					event = ui.getEvent(gid, eid)
					self.updateEventRowByIter(event, eventIter)
		###
		for gid in ui.changedGroups:
			group = ui.eventGroups[gid]
			groupIter = self.groupIterById[gid]
			for i, value in enumerate(self.getGroupRow(group)):
				self.trees.set_value(groupIter, i, value)
		ui.changedGroups = []
		###
		for gid in ui.reloadGroups:
			self.reloadGroupEvents(gid)
		ui.reloadGroups = []
		###
		if ui.reloadTrash:
			if self.trashIter:
				self.trees.remove(self.trashIter)
			self.appendTrash()
		ui.reloadTrash = False
	def __init__(self, **kwargs):
		checkEventsReadOnly() ## FIXME
		gtk.Dialog.__init__(self, **kwargs)
		self.initVars()
		ud.windowList.appendItem(self)
		####
		self.syncing = None ## or a tuple of (groupId, statusText)
		self.groupIterById = {}
		self.trashIter = None
		self.isLoaded = False
		self.loadedGroupIds = set()
		self.eventsIter = {}
		####
		self.set_title(_('Event Manager'))
		self.resize(600, 300)
		self.connect('delete-event', self.onDeleteEvent)
		self.set_transient_for(None)
		self.set_type_hint(gdk.WindowTypeHint.NORMAL)
		##
		dialog_add_button(self, gtk.STOCK_OK, _('_OK'), gtk.ResponseType.OK)
		#self.connect('response', lambda w, e: self.hide())
		self.connect('response', self.onResponse)
		self.connect('show', self.onShow)
		#######
		self.searchWin = EventSearchWindow()
		#######
		menubar = gtk.MenuBar()
		####
		fileItem = MenuItem(_('_File'))
		fileMenu = gtk.Menu()
		fileItem.set_submenu(fileMenu)
		menubar.append(fileItem)
		##
		addGroupItem = MenuItem(_('Add New Group'))
		addGroupItem.set_sensitive(not event_lib.readOnly)
		addGroupItem.connect('activate', self.addGroupBeforeSelection)
		## or before selected group? FIXME
		fileMenu.append(addGroupItem)
		##
		searchItem = MenuItem(_('_Search Events'))## FIXME right place?
		searchItem.connect('activate', self.mbarSearchClicked)
		fileMenu.append(searchItem)
		##
		exportItem = MenuItem(_('_Export'))
		exportItem.connect('activate', self.mbarExportClicked)
		fileMenu.append(exportItem)
		##
		importItem = MenuItem(_('_Import'))
		importItem.set_sensitive(not event_lib.readOnly)
		importItem.connect('activate', self.mbarImportClicked)
		fileMenu.append(importItem)
		##
		orphanItem = MenuItem(_('Check for Orphan Events'))
		orphanItem.set_sensitive(not event_lib.readOnly)
		orphanItem.connect('activate', self.mbarOrphanClicked)
		fileMenu.append(orphanItem)
		####
		editItem = MenuItem(_('_Edit'))
		if event_lib.readOnly:
			editItem.set_sensitive(False)
		else:
			editMenu = gtk.Menu()
			editItem.set_submenu(editMenu)
			menubar.append(editItem)
			##
			editEditItem = MenuItem(_('Edit'))
			editEditItem.connect('activate', self.mbarEditClicked)
			editMenu.append(editEditItem)
			editMenu.connect('show', self.mbarEditMenuPopup)
			self.mbarEditItem = editEditItem
			##
			editMenu.append(gtk.SeparatorMenuItem())
			##
			cutItem = MenuItem(_('Cu_t'))
			cutItem.connect('activate', self.mbarCutClicked)
			editMenu.append(cutItem)
			self.mbarCutItem = cutItem
			##
			copyItem = MenuItem(_('_Copy'))
			copyItem.connect('activate', self.mbarCopyClicked)
			editMenu.append(copyItem)
			self.mbarCopyItem = copyItem
			##
			pasteItem = MenuItem(_('_Paste'))
			pasteItem.connect('activate', self.mbarPasteClicked)
			editMenu.append(pasteItem)
			self.mbarPasteItem = pasteItem
			##
			editMenu.append(gtk.SeparatorMenuItem())
			##
			dupItem = MenuItem(_('_Duplicate'))
			dupItem.connect('activate', self.duplicateSelectedObj)
			editMenu.append(dupItem)
			self.mbarDupItem = dupItem
		####
		viewItem = MenuItem(_('_View'))
		viewMenu = gtk.Menu()
		viewItem.set_submenu(viewMenu)
		menubar.append(viewItem)
		##
		collapseItem = MenuItem(_('Collapse All'))
		collapseItem.connect('activate', self.collapseAllClicked)
		viewMenu.append(collapseItem)
		##
		expandItem = MenuItem(_('Expand All'))
		expandItem.connect('activate', self.expandAllClicked)
		viewMenu.append(expandItem)
		##
		viewMenu.append(gtk.SeparatorMenuItem())
		##
		self.showDescItem = gtk.CheckMenuItem(_('Show _Description'))
		self.showDescItem.set_active(ui.eventManShowDescription)
		self.showDescItem.connect('toggled', self.showDescItemToggled)
		viewMenu.append(self.showDescItem)
		####
		#testItem = MenuItem(_('Test'))
		#testMenu = gtk.Menu()
		#testItem.set_submenu(testMenu)
		#menubar.append(testItem)
		###
		#item = MenuItem('')
		#item.connect('activate', )
		#testMenu.append(item)
		####
		menubar.show_all()
		pack(self.vbox, menubar)
		#######
		treeBox = gtk.HBox()
		#####
		self.treev = gtk.TreeView()
		self.treev.set_search_column(2)
		#self.treev.set_headers_visible(False)## FIXME
		#self.treev.get_selection().set_mode(gtk.SelectionMode.MULTIPLE)## FIXME
		#self.treev.set_rubber_banding(gtk.SelectionMode.MULTIPLE)## FIXME
		#self.treev.connect('realize', self.onTreeviewRealize)
		self.treev.get_selection().connect('changed', self.treeviewCursorChanged)## FIXME
		self.treev.connect('button-press-event', self.treeviewButtonPress)
		self.treev.connect('row-activated', self.rowActivated)
		self.treev.connect('key-press-event', self.keyPress)
		#####
		swin = gtk.ScrolledWindow()
		swin.add(self.treev)
		swin.set_policy(gtk.PolicyType.AUTOMATIC, gtk.PolicyType.AUTOMATIC)
		pack(treeBox, swin, 1, 1)
		###
		toolbar = gtk.Toolbar()
		toolbar.set_orientation(gtk.Orientation.VERTICAL)
		size = gtk.IconSize.SMALL_TOOLBAR
		###
		tb = toolButtonFromStock(gtk.STOCK_GO_UP, size)
		set_tooltip(tb, _('Move up'))
		tb.connect('clicked', self.moveUpByButton)
		toolbar.insert(tb, -1)
		###
		tb = toolButtonFromStock(gtk.STOCK_GO_DOWN, size)
		set_tooltip(tb, _('Move down'))
		tb.connect('clicked', self.moveDownByButton)
		toolbar.insert(tb, -1)
		###
		tb = toolButtonFromStock(gtk.STOCK_COPY, size)
		set_tooltip(tb, _('Duplicate'))
		tb.connect('clicked', self.duplicateSelectedObj)
		toolbar.insert(tb, -1)
		###
		pack(treeBox, toolbar)
		#####
		pack(self.vbox, treeBox, 1, 1)
		#######
		self.trees = gtk.TreeStore(int, GdkPixbuf.Pixbuf, str, str)
		## event: eid,  event_icon,   event_summary, event_description
		## group: gid,  group_pixbuf, group_title,   ?description
		## trash: -1,        trash_icon,   _('Trash'),    ''
		self.treev.set_model(self.trees)
		###
		col = gtk.TreeViewColumn()
		cell = gtk.CellRendererPixbuf()
		pack(col, cell)
		col.add_attribute(cell, 'pixbuf', 1)
		col.set_property('expand', False)
		self.treev.append_column(col)
		###
		col = gtk.TreeViewColumn(
			_('Summary'),
			gtk.CellRendererText(),
			text=2,
		)
		col.set_resizable(True)
		col.set_property('expand', True)
		self.treev.append_column(col)
		###
		self.colDesc = gtk.TreeViewColumn(
			_('Description'),
			gtk.CellRendererText(),
			text=3,
		)
		self.colDesc.set_property('expand', True)
		if ui.eventManShowDescription:
			self.treev.append_column(self.colDesc)
		###
		#self.treev.set_search_column(2)## or 3
		###
		self.toPasteEvent = None ## (path, bool move)
		#####
		self.sbar = gtk.Statusbar()
		self.sbar.set_direction(gtk.TextDirection.LTR)
		#self.sbar.set_has_resize_grip(False)
		pack(self.vbox, self.sbar)
		#####
		self.vbox.show_all()
	def canPasteToGroup(self, group):
		if self.toPasteEvent is None:
			return False
		if not group.acceptsEventTypes:
			return False
		## check event type here? FIXME
		return True
	def checkEventToAdd(self, group, event):
		if not group.checkEventToAdd(event):
			showError(
				_('Group type "%s" can not contain event type "%s"')%(group.desc, event.desc),
				self,
			)
			raise RuntimeError('Invalid event type for this group')
	getGroupRow = lambda self, group:\
		common.getGroupRow(group) + ('',)
	getEventRow = lambda self, event: (
		event.id,
		pixbufFromFile(event.icon),
		event.summary,
		event.getShownDescription(),
	)
	def appendEventRow(self, parentIter, event):
		eventIter = self.trees.append(parentIter, self.getEventRow(event))
		self.eventsIter[event.id] = eventIter
		return eventIter
	def insertEventRow(self, parentIter, position, event):
		eventIter = self.trees.insert(parentIter, position, self.getEventRow(event))
		self.eventsIter[event.id] = eventIter
		return eventIter
	def insertEventRowAfter(self, parentIter, siblingIter, event):
		eventIter = self.trees.insert_after(parentIter, siblingIter, self.getEventRow(event))
		self.eventsIter[event.id] = eventIter
		return eventIter
	def insertGroup(self, position, group):
		self.groupIterById[group.id] = groupIter = self.trees.insert(
			None,
			position,
			self.getGroupRow(group),
		)
		return groupIter
	def appendGroupEvents(self, group, groupIter):
		for event in group:
			self.appendEventRow(groupIter, event)
		self.loadedGroupIds.add(group.id)
	def insertGroupTree(self, position, group):
		groupIter = self.insertGroup(position, group)
		if group.enable:
			self.appendGroupEvents(group, groupIter)
	def appendGroup(self, group):
		self.groupIterById[group.id] = groupIter = self.trees.insert_before(
			None,
			self.trashIter,
			self.getGroupRow(group),
		)
		return groupIter
	def appendGroupTree(self, group):
		groupIter = self.appendGroup(group)
		if group.enable:
			self.appendGroupEvents(group, groupIter)
	def appendTrash(self):
		self.trashIter = self.trees.append(None, (
			-1,
			pixbufFromFile(ui.eventTrash.icon),
			ui.eventTrash.title,
			'',
		))
		for event in ui.eventTrash:
			self.appendEventRow(self.trashIter, event)
	def reloadGroupEvents(self, gid):
		groupIter = self.groupIterById[gid]
		assert self.trees.get_value(groupIter, 0) == gid
		##
		self.removeIterChildren(groupIter)
		##
		group = ui.eventGroups[gid]
		if not gid in self.loadedGroupIds:
			return
		for event in group:
			self.appendEventRow(groupIter, event)
	def reloadEvents(self):
		self.trees.clear()
		self.appendTrash()
		for group in ui.eventGroups:
			self.appendGroupTree(group)
		self.treeviewCursorChanged()
		####
		ui.changedGroups = []
		ui.reloadGroups = []
		ui.reloadTrash = False
		####
		self.isLoaded = True
	def getObjsByPath(self, path):
		obj_list = []
		for i in range(len(path)):
			it = self.trees.get_iter(path[:i+1])
			obj_id = self.trees.get_value(it, 0)
			if i==0:
				if obj_id==-1:
					obj_list.append(ui.eventTrash)
				else:
					obj_list.append(ui.eventGroups[obj_id])
			else:
				obj_list.append(obj_list[i-1][obj_id])
		return obj_list
	def genRightClickMenu(self, path):
		## how about multi-selection? FIXME
		## and Select _All menu item
		obj_list = self.getObjsByPath(path)
		#print(len(obj_list))
		menu = gtk.Menu()
		if len(obj_list)==1:
			group = obj_list[0]
			if group.name == 'trash':
				#print('right click on trash', group.title)
				menu.add(eventWriteMenuItem(
					'Edit',
					gtk.STOCK_EDIT,
					self.editTrash,
				))
				menu.add(eventWriteMenuItem(
					'Empty Trash',
					gtk.STOCK_CLEAR,
					self.emptyTrash,
				))
				#menu.add(gtk.SeparatorMenuItem())
				#menu.add(eventWriteMenuItem(
				#	'Add New Group',
				#	gtk.STOCK_NEW,
				#	self.addGroupBeforeSelection,
				#))## FIXME
			else:
				#print('right click on group', group.title)
				menu.add(eventWriteMenuItem(
					'Edit',
					gtk.STOCK_EDIT,
					self.editGroupFromMenu,
					path,
				))
				eventTypes = group.acceptsEventTypes
				if eventTypes is None:
					eventTypes = event_lib.classes.event.names
				if len(eventTypes) > 3:
					menu.add(eventWriteMenuItem(
						_('Add Event'),
						gtk.STOCK_ADD,
						self.addGenericEventToGroupFromMenu,
						path,
						group,
					))
				else:
					for eventType in eventTypes:
						#if eventType == 'custom':## FIXME
						#	desc = _('Add ') + _('Event')
						#else:
						label = _('Add ') + event_lib.classes.event.byName[eventType].desc
						menu.add(eventWriteMenuItem(
							label,
							gtk.STOCK_ADD,
							self.addEventToGroupFromMenu,
							path,
							group,
							eventType,
							label,
						))
				pasteItem = eventWriteMenuItem(
					'Paste Event',
					gtk.STOCK_PASTE,
					self.pasteEventFromMenu,
					path,
				)
				menu.add(pasteItem)
				pasteItem.set_sensitive(self.canPasteToGroup(group))
				##
				if group.remoteIds:
					aid, remoteGid = group.remoteIds
					try:
						account = ui.eventAccounts[aid]
					except KeyError:
						myRaise()
					else:
						if account.enable:
							menu.add(gtk.SeparatorMenuItem())
							menu.add(eventWriteMenuItem(
								'Synchronize',
								gtk.STOCK_CONNECT,## or gtk.STOCK_REFRESH FIXME
								self.syncGroupFromMenu,
								path,
								account,
							))
						#else:## FIXME
				##
				menu.add(gtk.SeparatorMenuItem())
				#menu.add(eventWriteMenuItem(
				#	'Add New Group',
				#	gtk.STOCK_NEW,
				#	self.addGroupBeforeGroup,
				#	path,
				#))## FIXME
				menu.add(eventWriteMenuItem(
					'Duplicate',
					gtk.STOCK_COPY,
					self.duplicateGroupFromMenu,
					path,
				))
				###
				dupAllItem = labelStockMenuItem(
					'Duplicate with All Events',
					gtk.STOCK_COPY,
					self.duplicateGroupWithEventsFromMenu,
					path,
				)
				menu.add(dupAllItem)
				dupAllItem.set_sensitive(not event_lib.readOnly and bool(group.idList))
				###
				menu.add(gtk.SeparatorMenuItem())
				menu.add(eventWriteMenuItem(
					'Delete Group',
					gtk.STOCK_DELETE,
					self.deleteGroupFromMenu,
					path,
				))
				menu.add(gtk.SeparatorMenuItem())
				##
				#menu.add(eventWriteMenuItem(
				#	'Move Up',
				#	gtk.STOCK_GO_UP,
				#	self.moveUpFromMenu,
				#	path,
				#))
				#menu.add(eventWriteMenuItem(
				#	'Move Down',
				#	gtk.STOCK_GO_DOWN,
				#	self.moveDownFromMenu,
				#	path,
				#))
				##
				menu.add(labelStockMenuItem(
					_('Export'),
					gtk.STOCK_CONVERT,
					self.groupExportFromMenu,
					group,
				))
				###
				sortItem = labelStockMenuItem(
					_('Sort Events'),
					gtk.STOCK_SORT_ASCENDING,
					self.groupSortFromMenu,
					path,
				)
				menu.add(sortItem)
				sortItem.set_sensitive(not event_lib.readOnly and bool(group.idList))
				###
				convertItem = labelStockMenuItem(
					_('Convert Calendar Type'),
					gtk.STOCK_CONVERT,
					self.groupConvertModeFromMenu,
					group,
				)
				menu.add(convertItem)
				convertItem.set_sensitive(not event_lib.readOnly and bool(group.idList))
				###
				for newGroupType in group.canConvertTo:
					menu.add(eventWriteMenuItem(
						_('Convert to %s')%event_lib.classes.group.byName[newGroupType].desc,
						None,
						self.groupConvertTo,
						group,
						newGroupType,
					))
				###
				bulkItem = labelStockMenuItem(
					_('Bulk Edit Events'),
					gtk.STOCK_EDIT,
					self.groupBulkEditFromMenu,
					group,
					path,
				)
				menu.add(bulkItem)
				bulkItem.set_sensitive(not event_lib.readOnly and bool(group.idList))
				###
				for actionName, actionFuncName in group.actions:
					menu.add(eventWriteMenuItem(
						_(actionName),
						None,
						self.groupActionClicked,
						group,
						actionFuncName,
					))
		elif len(obj_list) == 2:
			group, event = obj_list
			#print('right click on event', event.summary)
			if group.name != 'trash':
				menu.add(eventWriteMenuItem(
					'Edit',
					gtk.STOCK_EDIT,
					self.editEventFromMenu,
					path,
				))
			####
			moveToItem = eventWriteMenuItem(
				_('Move to %s')%'...',
				None,## FIXME
			)
			moveToMenu = gtk.Menu()
			for new_group in ui.eventGroups:
				if new_group.id == group.id:
					continue
				#if not new_group.enable:## FIXME
				#	continue
				new_groupPath = self.trees.get_path(self.groupIterById[new_group.id])
				if event.name in new_group.acceptsEventTypes:
					new_groupItem = ImageMenuItem()
					new_groupItem.set_label(new_group.title)
					##
					image = gtk.Image()
					image.set_from_pixbuf(newColorCheckPixbuf(new_group.color, 20, True))
					new_groupItem.set_image(image)
					##
					new_groupItem.connect(
						'activate',
						self.moveEventToPathFromMenu,
						path,
						new_groupPath,
					)
					##
					moveToMenu.add(new_groupItem)
			moveToItem.set_submenu(moveToMenu)
			menu.add(moveToItem)
			####
			menu.add(gtk.SeparatorMenuItem())
			####
			menu.add(eventWriteMenuItem(
				'Cut',
				gtk.STOCK_CUT,
				self.cutEvent,
				path,
			))
			menu.add(eventWriteMenuItem(
				'Copy',
				gtk.STOCK_COPY,
				self.copyEvent,
				path,
			))
			##
			if group.name == 'trash':
				menu.add(gtk.SeparatorMenuItem())
				menu.add(eventWriteMenuItem(
					'Delete',
					gtk.STOCK_DELETE,
					self.deleteEventFromTrash,
					path,
				))
			else:
				pasteItem = eventWriteMenuItem(
					'Paste',
					gtk.STOCK_PASTE,
					self.pasteEventFromMenu,
					path,
				)
				menu.add(pasteItem)
				pasteItem.set_sensitive(self.canPasteToGroup(group))
				##
				menu.add(gtk.SeparatorMenuItem())
				menu.add(labelImageMenuItem(
					_('Move to %s')%ui.eventTrash.title,
					ui.eventTrash.icon,
					self.moveEventToTrashFromMenu,
					path,
				))
		else:
			return
		menu.show_all()
		return menu
	def openRightClickMenu(self, path, etime=None):
		menu = self.genRightClickMenu(path)
		if not menu:
			return
		if etime is None:
			etime = gtk.get_current_event_time()
		self.tmpMenu = menu
		menu.popup(None, None, None, None, 3, etime)
	#def onTreeviewRealize(self, gevent):
	#	#self.reloadEvents()## FIXME
	#	pass
	def rowActivated(self, treev, path, col):
		if len(path)==1:
			if treev.row_expanded(path):
				treev.collapse_row(path)
			else:
				treev.expand_row(path, False)
		elif len(path)==2:
			self.editEventByPath(path)
	def keyPress(self, treev, gevent):
		#from scal3.time_utils import getGtkTimeFromEpoch
		#print(gevent.time-getGtkTimeFromEpoch(now())## FIXME)
		#print(now()-gdk.CURRENT_TIME/1000.0)
		## gdk.CURRENT_TIME == 0## FIXME
		## gevent.time == gtk.get_current_event_time() ## OK
		kname = gdk.keyval_name(gevent.keyval).lower()
		if kname=='menu':## Simulate right click (key beside Right-Ctrl)
			path = treev.get_cursor()[0]
			if path:
				menu = self.genRightClickMenu(path)
				if not menu:
					return
				rect = treev.get_cell_area(path, treev.get_column(1))
				x = rect.x
				if rtl:
					x -= 100
				else:
					x += 50
				dx, dy = treev.translate_coordinates(self, x, rect.y + rect.height)
				foo, wx, wy = self.get_window().get_origin()
				self.tmpMenu = menu
				menu.popup(
					None,
					None,
					lambda *args: (
						wx+dx,
						wy+dy+20,
						True,
					),
					None,
					3,
					gevent.time,
				)
		elif kname=='delete':
			self.moveSelectionToTrash()
		else:
			#print(kname)
			return False
		return True
	def mbarExportClicked(self, obj):
		MultiGroupExportDialog(parent=self).run()
	def mbarImportClicked(self, obj):
		EventsImportWindow(self).present()
	def mbarSearchClicked(self, obj):
		self.searchWin.present()
	def _do_checkForOrphans(self):
		newGroup = ui.eventGroups.checkForOrphans()
		if newGroup is not None:
			self.appendGroupTree(newGroup)
	def mbarOrphanClicked(self, obj):
		self.waitingDo(self._do_checkForOrphans)
	def mbarEditMenuPopup(self, obj):
		path = self.treev.get_cursor()[0]
		selected = bool(path)
		eventSelected = selected and len(path)==2
		###
		self.mbarEditItem.set_sensitive(selected)
		self.mbarCutItem.set_sensitive(eventSelected)
		self.mbarCopyItem.set_sensitive(eventSelected)
		self.mbarDupItem.set_sensitive(selected)
		###
		self.mbarPasteItem.set_sensitive(
			selected and self.canPasteToGroup(self.getObjsByPath(path)[0])
		)
	def mbarEditClicked(self, obj):
		path = self.treev.get_cursor()[0]
		if not path:
			return
		if len(path)==1:
			self.editGroupByPath(path)
		elif len(path)==2:
			self.editEventByPath(path)
	def mbarCutClicked(self, obj):
		path = self.treev.get_cursor()[0]
		if not path:
			return
		if len(path)==2:
			self.toPasteEvent = (path, True)
	def mbarCopyClicked(self, obj):
		path = self.treev.get_cursor()[0]
		if not path:
			return
		if len(path)==2:
			self.toPasteEvent = (path, False)
	def mbarPasteClicked(self, obj):
		path = self.treev.get_cursor()[0]
		if not path:
			return
		self.pasteEventToPath(path)
	collapseAllClicked = lambda self, obj: self.treev.collapse_all()
	expandAllClicked = lambda self, obj: self.treev.expand_all()
	def _do_showDescItemToggled(self):
		active = self.showDescItem.get_active()
		#self.showDescItem.set_active(active)
		ui.eventManShowDescription = active
		ui.saveLiveConf()## FIXME
		if active:
			self.treev.append_column(self.colDesc)
		else:
			self.treev.remove_column(self.colDesc)
	def showDescItemToggled(self, obj=None):
		self.waitingDo(self._do_showDescItemToggled)
	def treeviewCursorChanged(self, selection=None):
		path = self.treev.get_cursor()[0]
		## update eventInfoBox
		#print('treeviewCursorChanged', path)
		if not self.syncing:
			text = ''
			if path:
				if len(path)==1:
					group, = self.getObjsByPath(path)
					if group.name == 'trash':
						text = _('contains %s events')%_(len(group))
					else:
						text = _('contains %s events and %s occurences')%(
							_(len(group)),
							_(group.occurCount),
						) + _(',') + ' ' + _('Group ID: %s')%_(group.id)
					modified = group.modified
				elif len(path)==2:
					group, event = self.getObjsByPath(path)
					text = _('Event ID: %s')%_(event.id)
					modified = event.modified
				text += '%s %s: %s'%(
					_(','),
					_('Last Modified'),
					locale_man.textNumEncode(core.epochDateTimeEncode(modified)),
				)
			try:
				sbar = self.sbar
			except AttributeError:
				pass
			else:
				message_id = self.sbar.push(0, text)
		return True
	def _do_onGroupModify(self, group):
		group.afterModify()
		group.save()## FIXME
		try:
			if group.name == 'universityTerm':## FIXME
				groupIter = self.groupIterById[group.id]
				n = self.trees.iter_n_children(groupIter)
				for i in range(n):
					eventIter = self.trees.iter_nth_child(groupIter, i)
					eid = self.trees.get(eventIter, 0)[0]
					self.trees.set(eventIter, 2, group[eid].summary)
		except:
			myRaise()
	def onGroupModify(self, group):
		self.waitingDo(self._do_onGroupModify, group)
	def treeviewButtonPress(self, treev, gevent):
		pos_t = treev.get_path_at_pos(int(gevent.x), int(gevent.y))
		if not pos_t:
			return
		path, col, xRel, yRel = pos_t
		if not path:
			return
		if gevent.button == 3:
			self.openRightClickMenu(path, gevent.time)
		elif gevent.button == 1:
			if not col:
				return
			if not rectangleContainsPoint(
				treev.get_cell_area(path, col),
				gevent.x,
				gevent.y,
			):
				return
			obj_list = self.getObjsByPath(path)
			if len(obj_list) == 1:## group, not event
				group = obj_list[0]
				if group.name != 'trash':
					cell = col.get_cells()[0]
					try:
						cell.get_property('pixbuf')
					except:
						pass
					else:
						group.enable = not group.enable
						groupIter = self.trees.get_iter(path)
						self.trees.set_value(
							groupIter,
							1,
							common.getGroupPixbuf(group),
						)
						ui.eventGroups.save()
						#group.save()
						if group.enable and \
							self.trees.iter_n_children(groupIter) == 0 and \
							len(group) > 0:
								for event in group:
									self.appendEventRow(groupIter, event)
								self.loadedGroupIds.add(group.id)
						self.onGroupModify(group)
						treev.set_cursor(path)
						return True
	def insertNewGroup(self, groupIndex):
		from scal3.ui_gtk.event.group.editor import GroupEditorDialog
		group = GroupEditorDialog(parent=self).run()
		if group is None:
			return
		ui.eventGroups.insert(groupIndex, group)
		ui.eventGroups.save()
		beforeGroupIter = self.trees.get_iter((groupIndex,))
		self.groupIterById[group.id] = self.trees.insert_before(
			#self.trees.get_iter_root(),## parent
			self.trees.iter_parent(beforeGroupIter),
			beforeGroupIter,## sibling
			self.getGroupRow(group),
		)
		self.onGroupModify(group)
		self.loadedGroupIds.add(group.id)
	def addGroupBeforeGroup(self, menu, path):
		self.insertNewGroup(path[0])
	def addGroupBeforeSelection(self, obj=None):
		path = self.treev.get_cursor()[0]
		if path:
			groupIndex = path[0]
		else:
			groupIndex = len(self.trees)-1
		self.insertNewGroup(groupIndex)
	def duplicateGroup(self, path):
		index, = path
		group, = self.getObjsByPath(path)
		newGroup = group.copy()
		ui.duplicateGroupTitle(newGroup)
		newGroup.afterModify()
		newGroup.save()
		ui.eventGroups.insert(index+1, newGroup)
		ui.eventGroups.save()
		self.groupIterById[newGroup.id] = self.trees.insert(
			None,
			index+1,
			self.getGroupRow(newGroup),
		)
	def duplicateGroupWithEvents(self, path):
		index, = path
		group, = self.getObjsByPath(path)
		newGroup = group.deepCopy()
		ui.duplicateGroupTitle(newGroup)
		newGroup.save()
		ui.eventGroups.insert(index+1, newGroup)
		ui.eventGroups.save()
		newGroupIter = self.groupIterById[newGroup.id] = self.trees.insert(
			None,
			index+1,
			self.getGroupRow(newGroup),
		)
		for event in newGroup:
			self.appendEventRow(newGroupIter, event)
		self.loadedGroupIds.add(newGroup.id)
	def syncGroupFromMenu(self, menu, path, account):
		index, = path
		group, = self.getObjsByPath(path)
		if not group.remoteIds:
			return
		aid, remoteGid = group.remoteIds
		info = {
			'group': group.title,
			'account': account.title,
		}
		account.showError = showError
		while gtk.events_pending():
			gtk.main_iteration_do(False)
		#try:
		self.waitingDo(account.sync, group, remoteGid)
		'''
		except Exception as e:
			showError(
				_('Error in synchronizing group \"%(group)s\" with account \"%(account)s\"')%info
					+ '\n' + str(e),
				self,
			)
		else:
			showInfo(
				_('Successful synchronizing of group \"%(group)s\" with account \"%(account)s\"')%info,
				self,
			)
		'''
		self.reloadGroupEvents(group.id)
	duplicateGroupFromMenu = lambda self, menu, path: self.duplicateGroup(path)
	duplicateGroupWithEventsFromMenu = lambda self, menu, path: \
		self.duplicateGroupWithEvents(path)
	def duplicateSelectedObj(self, button=None):
		path = self.treev.get_cursor()[0]
		if not path:
			return
		if len(path)==1:
			self.duplicateGroup(path)
		elif len(path)==2:## FIXME
			self.toPasteEvent = (path, False)
			self.pasteEventToPath(path)
	def editGroupByPath(self, path):
		from scal3.ui_gtk.event.group.editor import GroupEditorDialog
		group, = self.getObjsByPath(path)
		if group.name == 'trash':
			self.editTrash()
		else:
			group = GroupEditorDialog(group, parent=self).run()
			if group is None:
				return
			groupIter = self.trees.get_iter(path)
			for i, value in enumerate(self.getGroupRow(group)):
				self.trees.set_value(groupIter, i, value)
			self.onGroupModify(group)
	editGroupFromMenu = lambda self, menu, path: self.editGroupByPath(path)
	def _do_deleteGroup(self, path, group):
		trashedIds = group.idList
		if core.eventTrashLastTop:
			for eid in reversed(trashedIds):
				event = group[eid]
				self.insertEventRow(self.trashIter, 0, event)
		else:
			for eid in trashedIds:
				event = group[eid]
				self.appendEventRow(self.trashIter, event)
		ui.deleteEventGroup(group)
		self.trees.remove(self.trees.get_iter(path))
	def deleteGroup(self, path):
		index, = path
		group, = self.getObjsByPath(path)
		eventCount = len(group)
		if eventCount > 0:
			if not confirm(
				_('Press OK if you want to delete group "%s" and move its %s events to trash')%(
					group.title,
					_(eventCount),
				),
				parent=self,
			):
				return
		self.waitingDo(self._do_deleteGroup, path, group)
	deleteGroupFromMenu = lambda self, menu, path: self.deleteGroup(path)
	def addEventToGroupFromMenu(self, menu, path, group, eventType, title):
		event = addNewEvent(
			group,
			eventType,
			title=title,
			parent=self,
		)
		if event is None:
			return
		groupIter = self.trees.get_iter(path)
		if group.id in self.loadedGroupIds:
			self.appendEventRow(groupIter, event)
		self.treeviewCursorChanged()
	def addGenericEventToGroupFromMenu(self, menu, path, group):
		event = addNewEvent(
			group,
			group.acceptsEventTypes[0],
			typeChangable=True,
			title=_('Add Event'),
			parent=self,
		)
		if event is None:
			return
		groupIter = self.trees.get_iter(path)
		if group.id in self.loadedGroupIds:
			self.appendEventRow(groupIter, event)
		self.treeviewCursorChanged()
	def updateEventRow(self, event):
		self.updateEventRowByIter(
			event,
			self.eventsIter[event.id],
		)
	def updateEventRowByIter(self, event, eventIter):
		for i, value in enumerate(self.getEventRow(event)):
			self.trees.set_value(eventIter, i, value)
		self.treeviewCursorChanged()
	def editEventByPath(self, path):
		from scal3.ui_gtk.event.editor import EventEditorDialog
		group, event = self.getObjsByPath(path)
		if group.name == 'trash':## FIXME
			return
		event = EventEditorDialog(
			event,
			title=_('Edit ')+event.desc,
			parent=self,
		).run()
		if event is None:
			return
		self.updateEventRow(event)
	editEventFromMenu = lambda self, menu, path: self.editEventByPath(path)
	def moveEventToPathFromMenu(self, menu, path, tarPath):
		self.toPasteEvent = (path, True)
		self.pasteEventToPath(tarPath, False)
	def moveEventToTrash(self, path):
		group, event = self.getObjsByPath(path)
		if not confirmEventTrash(event, parent=self):
			return
		ui.moveEventToTrash(group, event)
		self.trees.remove(self.trees.get_iter(path))
		if core.eventTrashLastTop:
			self.insertEventRow(self.trashIter, 0, event)
		else:
			self.appendEventRow(self.trashIter, event)
	moveEventToTrashFromMenu = lambda self, menu, path: self.moveEventToTrash(path)
	def moveSelectionToTrash(self):
		path = self.treev.get_cursor()[0]
		if not path:
			return
		objs = self.getObjsByPath(path)
		if len(path)==1:
			self.deleteGroup(path)
		elif len(path)==2:
			self.moveEventToTrash(path)
	def deleteEventFromTrash(self, menu, path):
		trash, event = self.getObjsByPath(path)
		trash.delete(event.id)## trash == ui.eventTrash
		trash.save()
		self.trees.remove(self.trees.get_iter(path))
	def removeIterChildren(self, _iter):
		while True:
			childIter = self.trees.iter_children(_iter)
			if childIter is None:
				break
			self.trees.remove(childIter)
	def emptyTrash(self, menu):
		ui.eventTrash.empty()
		self.removeIterChildren(self.trashIter)
		self.treeviewCursorChanged()
	def editTrash(self, obj=None):
		TrashEditorDialog(parent=self).run()
		self.trees.set_value(
			self.trashIter,
			1,
			pixbufFromFile(ui.eventTrash.icon),
		)
		self.trees.set_value(
			self.trashIter,
			2,
			ui.eventTrash.title,
		)
	def moveUp(self, path):
		srcIter = self.trees.get_iter(path)
		if len(path)==1:
			if path[0]==0:
				return
			if self.trees.get_value(srcIter, 0)==-1:
				return
			tarIter = self.trees.get_iter((path[0]-1))
			self.trees.move_before(srcIter, tarIter)
			ui.eventGroups.moveUp(path[0])
			ui.eventGroups.save()
		elif len(path)==2:
			parentObj, event = self.getObjsByPath(path)
			parentLen = len(parentObj)
			parentIndex, eventIndex = path
			#print(eventIndex, parentLen)
			if eventIndex > 0:
				tarIter = self.trees.get_iter((parentIndex, eventIndex-1))
				self.trees.move_before(srcIter, tarIter)## or use self.trees.swap FIXME
				parentObj.moveUp(eventIndex)
				parentObj.save()
			else:
				## move event to end of previous group
				#if parentObj.name == 'trash':
				#	return
				if parentIndex < 1:
					return
				newParentIter = self.trees.get_iter((parentIndex - 1))
				newParentId = self.trees.get_value(newParentIter, 0)
				if newParentId==-1:## could not be!
					return
				newGroup = ui.eventGroups[newParentId]
				self.checkEventToAdd(newGroup, event)
				self.trees.remove(srcIter)
				self.appendEventRow(newParentIter, event)
				###
				parentObj.remove(event)
				parentObj.save()
				newGroup.append(event)
				newGroup.save()
		else:
			raise RuntimeError('invalid tree path %s'%path)
		newPath = self.trees.get_path(srcIter)
		if len(path)==2:
			self.treev.expand_to_path(newPath)
		self.treev.set_cursor(newPath)
		self.treev.scroll_to_cell(newPath)
	def moveDown(self, path):
		srcIter = self.trees.get_iter(path)
		if len(path)==1:
			if self.trees.get_value(srcIter, 0)==-1:
				return
			tarIter = self.trees.get_iter((path[0]+1))
			if self.trees.get_value(tarIter, 0)==-1:
				return
			self.trees.move_after(srcIter, tarIter)## or use self.trees.swap FIXME
			ui.eventGroups.moveDown(path[0])
			ui.eventGroups.save()
		elif len(path)==2:
			parentObj, event = self.getObjsByPath(path)
			parentLen = len(parentObj)
			parentIndex, eventIndex = path
			#print(eventIndex, parentLen)
			if eventIndex < parentLen-1:
				tarIter = self.trees.get_iter((parentIndex, eventIndex+1))
				self.trees.move_after(srcIter, tarIter)
				parentObj.moveDown(eventIndex)
				parentObj.save()
			else:
				## move event to top of next group
				if parentObj.name == 'trash':
					return
				newParentIter = self.trees.get_iter((parentIndex + 1))
				newParentId = self.trees.get_value(newParentIter, 0)
				if newParentId==-1:
					return
				newGroup = ui.eventGroups[newParentId]
				self.checkEventToAdd(newGroup, event)
				self.trees.remove(srcIter)
				srcIter = self.insertEventRow(newParentIter, 0, event)
				###
				parentObj.remove(event)
				parentObj.save()
				newGroup.insert(0, event)
				newGroup.save()
		else:
			raise RuntimeError('invalid tree path %s'%path)
		newPath = self.trees.get_path(srcIter)
		if len(path)==2:
			self.treev.expand_to_path(newPath)
		self.treev.set_cursor(newPath)
		self.treev.scroll_to_cell(newPath)
	moveUpFromMenu = lambda self, menu, path: self.moveUp(path)
	moveDownFromMenu = lambda self, menu, path: self.moveDown(path)
	def moveUpByButton(self, button):
		path = self.treev.get_cursor()[0]
		if not path:
			return
		self.moveUp(path)
	def moveDownByButton(self, button):
		path = self.treev.get_cursor()[0]
		if not path:
			return
		self.moveDown(path)
	def groupExportFromMenu(self, menu, group):
		SingleGroupExportDialog(group, parent=self).run()
	def groupSortFromMenu(self, menu, path):
		index, = path
		group, = self.getObjsByPath(path)
		if GroupSortDialog(group, parent=self).run():
			if group.id in self.loadedGroupIds:
				groupIter = self.trees.get_iter(path)
				expanded = self.treev.row_expanded(path)
				self.removeIterChildren(groupIter)
				for event in group:
					self.appendEventRow(groupIter, event)
				if expanded:
					self.treev.expand_row(path, False)
	def groupConvertModeFromMenu(self, menu, group):
		GroupConvertModeDialog(group, parent=self).run()
	def _do_groupConvertTo(self, group, newGroupType):
		idsCount = len(group.idList)
		newGroup = ui.eventGroups.convertGroupTo(group, newGroupType)
		## reload it's events in tree? FIXME
		## summary and description haven't changed!
		idsCount2 = len(newGroup.idList)
		if idsCount2 != idsCount:
			self.reloadGroupEvents(newGroup.id)
		self.treeviewCursorChanged()
	def groupConvertTo(self, menu, group, newGroupType):
		self.waitingDo(self._do_groupConvertTo, group, newGroupType)
	def _do_groupBulkEdit(self, dialog, group, path):
		expanded = self.treev.row_expanded(path)
		dialog.doAction()
		dialog.destroy()
		self.trees.remove(self.trees.get_iter(path))
		self.insertGroupTree(path[0], group)
		if expanded:
			self.treev.expand_row(path, False)
		self.treev.set_cursor(path)
	def groupBulkEditFromMenu(self, menu, group, path):
		from scal3.ui_gtk.event.bulk_edit import EventsBulkEditDialog
		dialog = EventsBulkEditDialog(group, parent=self)
		if dialog.run()==gtk.ResponseType.OK:
			self.waitingDo(self._do_groupBulkEdit, dialog, group, path)
	def groupActionClicked(self, menu, group, actionFuncName):
		func = getattr(group, actionFuncName)
		self.waitingDo(func, parentWin=self)
	def cutEvent(self, menu, path):
		self.toPasteEvent = (path, True)
	def copyEvent(self, menu, path):
		self.toPasteEvent = (path, False)
	pasteEventFromMenu = lambda self, menu, tarPath: self.pasteEventToPath(tarPath)
	def pasteEventToPath(self, tarPath, doScroll=True):
		if not self.toPasteEvent:
			return
		srcPath, move = self.toPasteEvent
		srcGroup, srcEvent = self.getObjsByPath(srcPath)
		tarGroup = self.getObjsByPath(tarPath)[0]
		self.checkEventToAdd(tarGroup, srcEvent)
		if len(tarPath)==1:
			tarGroupIter = self.trees.get_iter(tarPath)
			tarEventIter = None
			tarEventIndex = len(tarGroup)
		elif len(tarPath)==2:
			tarGroupIter = self.trees.get_iter(tarPath[:1])
			tarEventIter = self.trees.get_iter(tarPath)
			tarEventIndex = tarPath[1]
		####
		if move:
			srcGroup.remove(srcEvent)
			srcGroup.save()
			tarGroup.insert(tarEventIndex, srcEvent)
			tarGroup.save()
			self.trees.remove(self.trees.get_iter(srcPath))
			newEvent = srcEvent
		else:
			newEvent = srcEvent.copy()
			newEvent.save()
			tarGroup.insert(tarEventIndex, newEvent)
			tarGroup.save()
		####
		if tarEventIter:
			newEventIter = self.insertEventRowAfter(tarGroupIter, tarEventIter, newEvent)
		else:
			newEventIter = self.appendEventRow(tarGroupIter, newEvent)
		if doScroll:
			self.treev.set_cursor(self.trees.get_path(newEventIter))
		self.toPasteEvent = None
	#def selectAllEventInGroup(self, menu):## FIXME
	#	pass
	#def selectAllEventInTrash(self, menu):## FIXME
	#	pass
	def onDeleteEvent(self, obj, event):
		self.hide()
		return True
Ejemplo n.º 13
0
 def __init__(self, wcal):
     from scal3.ui_gtk.utils import pixbufFromFile
     Column.__init__(self, wcal)
     self.connect("draw", self.onExposeEvent)
     self.moonPixbuf = pixbufFromFile("full_moon_48px.png")
     self.showPhaseNumber = False