awips2/cave/com.raytheon.viz.avnconfig/localization/aviation/python/EditDialog.py
Max Schenkelberg 6f60751ec6 Issue #2033 moved avnfps and text workstation files into respective plugins.
Change-Id: If95cb839ad81ca2a842ff7f6926847ac3928d8f2

Former-commit-id: 77e1a4d8f5237e5fae930c1e00589c752f8b3738
2013-08-15 12:21:43 -05:00

501 lines
16 KiB
Python

##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
#
# Name:
# EditDialog.py
# GFS1-NHD:A3646.0000-SCRIPT;22
#
# Status:
# DELIVERED
#
# History:
# Revision 22 (DELIVERED)
# Created: 03-FEB-2007 08:47:40 OBERFIEL
# Verify Send Dialog was not updated on the new forecaster
# transmit flag resource.
#
# Revision 21 (DELIVERED)
# Created: 28-JUN-2006 14:08:14 TROJAN
# spr 7188: fixed undo/redo functionality
#
# Revision 20 (DELIVERED)
# Created: 15-FEB-2006 14:34:46 TROJAN
# fixes transient dialog behavior - spr 7091
#
# Revision 19 (DELIVERED)
# Created: 06-JUL-2005 20:50:38 TROJAN
# spr 6910
#
# Revision 18 (DELIVERED)
# Created: 07-MAY-2005 11:32:33 OBERFIEL
# Added Item Header Block
#
# Revision 17 (DELIVERED)
# Created: 04-APR-2005 15:51:04 TROJAN
# spr 6775
#
# Revision 16 (APPROVED)
# Created: 21-MAR-2005 16:53:04 TROJAN
# spr 6740
#
# Revision 15 (APPROVED)
# Created: 21-MAR-2005 16:46:26 TROJAN
# spr 6740
#
# Revision 14 (DELIVERED)
# Created: 30-SEP-2004 18:56:02 TROJAN
# stdr 874
#
# Revision 13 (APPROVED)
# Created: 01-JUL-2004 14:59:19 OBERFIEL
# Update
#
# Revision 12 (DELIVERED)
# Created: 08-JAN-2004 21:39:56 PCMS
# Updating for code cleanup
#
# Revision 11 (APPROVED)
# Created: 05-NOV-2003 19:07:51 OBERFIEL
# Initial version for 2.0
#
# Revision 10 (DELIVERED)
# Created: 24-APR-2003 14:54:48 TROJAN
# sprs 5055, 5056, 5057, 5070
#
# Revision 9 (DELIVERED)
# Created: 10-APR-2003 15:26:57 TROJAN
# spr 4997
#
# Revision 8 (BUILD_RELEASE)
# Created: 28-FEB-2003 12:35:56 TROJAN
# spr 4754 4823
#
# Revision 7 (DELIVERED)
# Created: 11-JUN-2002 19:11:05 PCMS
# Prevented wrapping lines in error dialogs. Enabled ability
# to change cursor color.
#
# Revision 6 (DELIVERED)
# Created: 29-MAY-2002 22:17:51 PCMS
# Adding dialog to edit resource configuration file
#
# Revision 5 (DELIVERED)
# Created: 21-MAY-2002 19:16:52 PCMS
# updating for 5.2.2 s5
#
# Revision 4 (DELIVERED)
# Created: 13-MAY-2002 22:30:28 PCMS
# Fixed placement of dialog boxes.
#
# Revision 3 (DELIVERED)
# Created: 30-OCT-2001 19:11:51 PCMS
# Adding capability to iconify dialog windows
#
# Revision 2 (DELIVERED)
# Created: 02-OCT-2001 17:48:23 PCMS
# Updating for gui changes
#
# Revision 1 (DELIVERED)
# Created: 20-AUG-2001 20:30:36 MOELLER
# Initial version
#
# Change Document History:
# 1:
# Change Document: GFS1-NHD_SPR_7242
# Action Date: 20-MAR-2007 09:51:12
# Relationship Type: Affected
# Status: CLOSED
# Title: AvnFPS: Privilege to transmit products should be user configurable
#
#
import logging, os
from Tkinter import *
import Pmw
from Balloon import Balloon
import Avn, AvnDialog, Busy, EditorTools, SearchDialog
HelpEdit = {
'title': 'Editor Help',
'content': """
This is a generic text editor. Edit any text file via the file
selection dialog that is invoked by pressing the 'Open' button.
Menu items:
File:
Print invokes print dialog
Edit:
provides the usual editing functions (i.e. Cut, Copy, Paste,
and Find/Replace). The menu can be also invoked by pressing
right mouse button within the text window area.
Buttons:
Clear: clears text window.
Open: invokes file selection dialog
Save: saves content of the text window
Save as: invokes file selection dialog
Toggles:
Insert: toggles insert/overwrite mode
Wrap: toggles word wrap
The currently loaded (if any) file name is displayed in a label above the
text window.
"""
}
_Logger = logging.getLogger(__name__)
###############################################################################
class Editor(AvnDialog.Dialog):
"""A simple editor"""
def __init__(self, parent, **kw):
AvnDialog.Dialog.__init__(self, parent, **kw)
self.title(Avn.Name + ' Text Editor')
self.appInit(**kw)
self.__getOptions()
self.__createMenuBar()
# from AvnDialog
self.createMessageBar(self.interior())
self.__createMainWindow()
self.appFinish()
self.initialiseoptions(Editor)
def appInit(self):
self._tkInsert = IntVar()
self._tkWrap = StringVar()
self._workdir = None
def appFinish(self):
self.configure(command=self.close)
def __createMenuBar(self):
self.menubar = Pmw.MenuBar(self.interior(),
hull_relief='raised',
hull_borderwidth=1,
)
self.menubar.pack(side='top', fill='x')
self.menubar.addmenu('Help', 'Help actions', side='right')
self.menubar.addmenuitem('Help', 'command',
label='Key bindings',
command=Avn.curry(self.showHelp, EditorTools.Help),
)
self.menubar.addmenuitem('Help', 'command',
label='Usage',
command=Avn.curry(self.showHelp, HelpEdit),
)
self.menubar.addmenu('File', 'Main actions', side='left')
self.menubar.addmenuitem('File', 'command',
'Invoke print dialog',
label = 'Print',
command=self.showPrintDialog,
)
self.menubar.addmenuitem('File', 'separator')
self.menubar.addmenuitem('File', 'command',
label = 'Close',
command=self.close,
)
self.menubar.addmenu('Edit', 'Editing actions', side='left')
self.menubar.addmenuitem('Edit', 'command',
label = 'Cut',
command=self.__cut,
)
self.menubar.addmenuitem('Edit', 'command',
label = 'Copy',
command=self.__copy,
)
self.menubar.addmenuitem('Edit', 'command',
label = 'Paste',
command=self.__paste,
)
self.menubar.addmenuitem('Edit', 'command',
label = 'Find',
command=self.__find,
)
self.menubar.addmenuitem('Edit', 'command',
label = 'Undo',
command=self.__undo,
)
self.menubar.addmenuitem('Edit', 'command',
label = 'Redo',
command=self.__redo,
)
def __createMainWindow(self):
# shortcut buttons
cmdbtnbox = Pmw.ButtonBox(self.interior())
btn = cmdbtnbox.add('Clear', command=self.clear)
Balloon().bind(btn, 'Clear text area')
btn = cmdbtnbox.add('Open', command=self.open)
Balloon().bind(btn, 'Open file')
btn = cmdbtnbox.add('Save', command=self.save)
Balloon().bind(btn, 'Save file with current name')
btn = cmdbtnbox.add('Save As', command=self.saveAs)
Balloon().bind(btn, 'Saves file')
cmdbtnbox.alignbuttons()
cmdbtnbox.pack(side='top', expand='no', fill='x')
frame = Frame(self.interior())
self.filelabel = Label(frame,
relief='ridge',
justify='left')
self.filelabel.pack(side='left', expand='yes', fill='x')
checkbutton = Checkbutton(frame,
text='Insert',
variable=self._tkInsert,
)
checkbutton.pack(side='left', padx=2)
checkbutton = Checkbutton(frame,
text='Wrap',
onvalue='word',
offvalue='none',
variable=self._tkWrap,
command=self.__toggleWrap,
)
checkbutton.pack(side='left', padx=2)
frame.pack(side='top', expand='no', fill='x')
# scrolled text
self.scrolledtext = Pmw.ScrolledText(self.interior(),
borderframe=1,
hscrollmode='static',
vscrollmode='static',
text_setgrid=TRUE,
text_undo=TRUE,
# text_maxundo=16,
)
self.scrolledtext.pack(side='bottom', expand='yes', fill='both')
self.scrolledtext.configure(text_wrap=self._tkWrap.get())
# shortcut
t = self.text = self.scrolledtext.component('text')
t.bind('<KeyPress>', self.__keyPress)
t.bind('<Button-3>', self.__popupMenu)
t.bind('<Insert>', self.__toggleInsert)
t.bind('<Control-u>', self.__undo)
t.bind('<Control-r>', self.__redo)
self._lastix = t.index('insert')
def __createPopupMenu(self):
self.popmenu = Menu(self._hull,
tearoff=0,
type='normal',
)
self.popmenu.add_command(label='Cut', command=self.__cut)
self.popmenu.add_command(label='Copy', command=self.__copy)
self.popmenu.add_command(label='Paste', command=self.__paste)
self.popmenu.add_command(label='Undo', command=self.__undo)
self.popmenu.add_command(label='Redo', command=self.__redo)
def __createSearchDialog(self):
self.searchdialog = SearchDialog.Dialog(self._hull, self.text)
self.searchdialog.transient(master=self._hull)
AvnDialog.setGeometry(self, self.searchdialog)
def __getOptions(self):
value = self.option_get('insert', '')
if value:
self._tkInsert.set(int(value))
value = self.option_get('wrap', '')
if not value:
value = 'none'
self._tkWrap.set(value)
#############################################################################
# editing methods
def __copy(self):
self.text.selection_own()
try:
selection = self.text.selection_get()
self.text.clipboard_clear()
self.text.clipboard_append(selection)
return 1
except:
return 0
def __cut(self):
if not self.__copy():
return
start, end = self.text.tag_ranges('sel')
self.text.delete(start, end)
def __find(self, event=None):
if not hasattr(self, 'searchdialog'):
self.__createSearchDialog()
self.searchdialog.show()
self.searchdialog.focus_set()
def __keyPress(self, e):
if not self._tkInsert.get() and e.widget.get('insert') != '\n' \
and e.char and e.keysym != 'Delete':
e.widget.delete('insert')
def __paste(self):
try:
self.text.insert('insert',
self.text.selection_get(selection='CLIPBOARD'))
except:
pass
def __popupMenu(self, e):
if not hasattr(self, 'popmenu'):
self.__createPopupMenu()
self.popmenu.tk_popup(e.widget.winfo_rootx() + e.x,
e.widget.winfo_rooty() + e.y)
def __toggleInsert(self, e=None):
if self._tkInsert.get():
self._tkInsert.set(0)
else:
self._tkInsert.set(1)
return 'break'
def __toggleWrap(self):
if not hasattr(self, 'scrolledtext'):
return
self.scrolledtext.configure(text_wrap=self._tkWrap.get())
def __undo(self, e=None):
try:
self.text.edit_undo()
except TclError:
self.messagebar().message('userevent', 'Nothing to undo')
def __redo(self, e=None):
try:
self.text.edit_redo()
except TclError:
self.messagebar().message('userevent', 'Nothing to redo')
##############################################################################
# menu methods
def clear(self):
self.scrolledtext.clear()
self.filelabel.configure(text='')
self.text.edit_modified(0)
def close(self, event=None):
if int(self.option_get('confirmClose', '')) != 0 and \
self.text.edit_modified():
if not Busy.askokcancel('Abort changes?',
self.interior()):
return
self.text.edit_modified(0)
self.withdraw()
def display(self, above=None):
AvnDialog.Dialog.display(self, above)
self.scrolledtext.focus_set()
def open(self, event=None):
filename = Busy.askopenfilename(self.interior(),
initialdir=self._workdir, filetypes=[('all', '*')])
try:
self.getFile(filename)
except IOError:
msg = 'Cannot read %s' % filename
_Logger.exception(msg)
Busy.showerror(msg, self.interior())
self.filelabel.configure(text='')
def getFile(self, filename):
if not filename:
return
if self.text.edit_modified() and not Busy.askokcancel( \
'File not saved. Really want to continue?',
self.interior()):
return
self.scrolledtext.clear()
self.scrolledtext.importfile(filename)
self.filelabel.configure(text=filename)
self._lastix = self.text.index('insert')
self.text.edit_reset()
self.text.edit_modified(0)
def finish(self, *filenames):
try:
self.getFile(*filenames)
except IOError:
pass
def save(self, event=None):
filename = self.filelabel.cget('text')
if not filename:
Busy.showerror('No file name', self.interior())
return
self.__save(filename)
def saveAs(self, event=None):
filename = Busy.asksaveasfilename(self.interior(),
initialdir=self._workdir)
if not filename:
return
self.__save(filename)
def setworkdir(self, dir='.'):
self._workdir=dir
def showPrintDialog(self):
if not hasattr(self, 'printdialog'):
self.printdialog = AvnDialog.PrintDialog(self._hull,
self.__print)
self.printdialog.transient(self.interior())
self.printdialog.show()
self.printdialog.focus_set()
##############################################################################
# other methods
def __print(self, result):
if result is None or result == 'Close':
self.printdialog.withdraw()
return
cmd = self.printdialog.get().strip()
if not cmd:
return
content = self.scrolledtext.get().strip()
(chldin, chldout) = os.popen4(cmd, -1)
chldin.write(content)
chldin.close()
msg = chldout.read()
if msg:
_Logger.debug(msg)
Busy.showinfo(msg, self.interior())
else:
msg = 'Sent to printer'
_Logger.info(msg)
self.messagebar().message('userevent', msg)
self.printdialog.withdraw()
return
def __save(self, filename):
try:
file(filename, 'w').write('%s\n' % \
self.scrolledtext.get().strip().expandtabs())
self.text.edit_modified(0)
msg = 'Saved file %s' % filename
_Logger.info(msg)
self.messagebar().message('userevent', msg)
except IOError:
msg = 'Cannot save file %s' % filename
_Logger.exception(msg)
Busy.showerror(msg, self.interior())