"""
Insert_Buffer_Properties.py - A Jython macro for jEdit for
inserting 'Buffer Local Properties' into the current buffer.
It will remember which properties were inserted for each mode
the last time it was used.

Copyright (C) 2002 Ollie Rutherfurd <oliver@rutherfurd.net>

$Id: Insert_Buffer_Properties.py 54 2003-11-03 16:05:35Z oliver $
"""

__version__ = '$Revision: 1.12 $'[11:-2]
__author__ = 'Ollie Rutherfurd'

from java.awt import BorderLayout
from java.awt.event import ActionListener, KeyEvent, KeyListener
from javax.swing import Box, BoxLayout, JButton, JCheckBox, JDialog, JLabel, JPanel, JScrollPane
from javax.swing.border import EmptyBorder
from org.gjt.sp.jedit import Macros
from org.gjt.sp.jedit.gui import JCheckBoxList
from org.gjt.sp.jedit.gui.JCheckBoxList import Entry


class BufferPropertiesDialog(JDialog,ActionListener,KeyListener):

	"""
	Dialog to insert buffer local properties for the current
	buffer into the current buffer.
	"""

	PROPERTIES = {"tabSize": 'int'
		,"mode": None
		,"indentSize": 'int'
		,"noTabs": 'bool'
		,"indentOnTab": 'bool'
		,"indentOnEnter": 'bool'
		,"wrap": 'str'
		,"maxLineLen": 'int'
		,"folding": 'str'
		,"collapseFolds": 'int'
		,"lineSeparator": None
		,"encoding": 'str'
		,"gzipped": 'bool'
		,"trailingEOL": 'bool'
		,"deepIndent": 'bool'
	}

	def __init__(self, view, title="Insert Buffer Properties", modal=0):
		JDialog.__init__(self, view, title, modal)

		self.view = view
		self.buffer = view.getTextArea().getBuffer()
		content = JPanel(BorderLayout())
		content.setBorder(EmptyBorder(10,10,10,10))
		self.setContentPane(content)
		content.add(JLabel("Properties:"), BorderLayout.NORTH)

		entries = []
		propName = 'macro.insert-buffer-properties.%s' % (self.buffer.getMode().getName(),)
		checkedProps = jEdit.getProperty(propName, '').split(',')
		commentProps = jEdit.getProperty('macro.insert-buffer-properties.commented.%s' % (self.buffer.getMode().getName(),), 'false')
		props = self.PROPERTIES.keys()
		props.sort()
		for prop in props:
			isChecked = prop in checkedProps
			entries.append(Entry(isChecked,prop))
		self.checkBox = JCheckBoxList(entries)
		self.commentProps = JCheckBox("Comment out inserted properties")
		self.commentProps.setSelected(commentProps == 'true')

		checkBoxesPane = JPanel(BorderLayout())
		checkBoxesPane.add(JScrollPane(self.checkBox), BorderLayout.CENTER)
		checkBoxesPane.add(self.commentProps, BorderLayout.SOUTH)

		content.add(checkBoxesPane, BorderLayout.CENTER)

		# buttons
		btnPanel = JPanel(border=EmptyBorder(12,50,0,50))
		btnPanel.setLayout(BoxLayout(btnPanel, BoxLayout.X_AXIS))
		btnPanel.add(Box.createGlue())
		self.okBtn = JButton("OK")
		self.cancelBtn = JButton("Cancel")
		self.okBtn.setPreferredSize(self.cancelBtn.getPreferredSize())
		self.getRootPane().setDefaultButton(self.okBtn)
		btnPanel.add(self.okBtn)
		btnPanel.add(Box.createHorizontalStrut(6))
		btnPanel.add(self.cancelBtn)
		btnPanel.add(Box.createGlue())
		content.add(btnPanel, BorderLayout.SOUTH)

		self.okBtn.addActionListener(self)
		self.cancelBtn.addActionListener(self)
		self.addKeyListener(self)
		self.checkBox.addKeyListener(self)

		self.pack()
		self.setSize(250,350)	# without this, dialog ends up pretty large
		self.setLocationRelativeTo(view)
		self.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE)

	def keyPressed(self,evt):
		if evt.getKeyCode() == KeyEvent.VK_ESCAPE:
			self.close()

	keyReleased = keyTyped = lambda self,evt: None

	def close(self):
		self.view = None
		self.buffer = None
		self.checkBox = None
		self.dispose()

	def actionPerformed(self,evt):
		if evt.getSource() == self.okBtn:
			self.insertSelected()
		self.close()

	def insertSelected(self):
		props = []
		for name in self.checkBox.getCheckedValues():
			# get mode name
			if name == 'mode':
				value = self.buffer.getMode().name
			# escape, and remove quotes
			elif name == 'lineSeparator':
				value = repr(self.buffer.getProperty(name))[1:-1]
			# boolean property
			elif self.PROPERTIES[name] == 'bool':
				if str(self.buffer.getProperty(name)) not in ('false','0'):
					value = 'true'
				else:
					value = 'false'
			# integer property
			elif self.PROPERTIES[name] == 'int':
				try:
					value = int(self.buffer.getProperty(name))
				except ValueError:
					value = 0
			# string property
			elif self.PROPERTIES[name] == 'str':
				value = self.buffer.getProperty(name)
				if value is None:
					value = ''
			# something we don't know about
			else:
				Macros.error(self.view, \
					'unexpected property type for %s: %s' \
					% (name,self.PROPERTIES[name],))
				continue

			props.append('%s=%s' % (name,value,))

		if len(props):
			# save current properties for this mode
			mode = self.buffer.getMode().getName()
			jEdit.setProperty('macro.insert-buffer-properties.%s' % (mode,), \
				','.join(self.checkBox.getCheckedValues()))
			if self.commentProps.isSelected():
				commentProps = 'true'
			else:
				commentProps = 'false'
			jEdit.setProperty('macro.insert-buffer-properties.commented.%s' \
				% (self.buffer.getMode().getName(),), commentProps)

			# insert properties into buffer
			props.sort()
			propstr = ':%s:' % ':'.join(props)
			# if not commenting properties, just insert them and return
			if not self.commentProps.isSelected():
				self.view.getTextArea().setSelectedText(propstr)
				return

			# properties should be commented out, first try for line
			# comment, then span comment
			lineComment = self.buffer.getProperty('lineComment')
			if lineComment:
				propstr = lineComment + ' ' + propstr
			elif self.buffer.getProperty('commentStart') and \
				init.buffer.getProperty('commentEnd'):
				propstr = self.buffer.getProperty('commentStart') \
					+ ' ' + propstr + ' ' \
					+ self.buffer.getProperty('commentEnd')

			self.view.getTextArea().setSelectedText(propstr)


if __name__ in ('__main__','main'):
	dlg = BufferPropertiesDialog(init.view)
	dlg.show()

# :indentSize=4:lineSeparator=\n:noTabs=false:tabSize=4:

