4 @brief Command output log widget
12 (C) 2007-2011 by the GRASS Development Team
13 This program is free software under the GNU General Public
14 License (>=v2). Read the file COPYING that comes with GRASS
17 @author Michael Barton (Arizona State University)
18 @author Martin Landa <landa.martin gmail.com>
19 @author Vaclav Petras <wenzeslaus gmail.com> (copy&paste customization)
33 from wx.lib.newevent
import NewEvent
45 from debug
import Debug
46 from preferences
import globalSettings
as UserSettings
47 from ghelp
import SearchModuleWindow
49 wxCmdOutput, EVT_CMD_OUTPUT = NewEvent()
50 wxCmdProgress, EVT_CMD_PROGRESS = NewEvent()
51 wxCmdRun, EVT_CMD_RUN = NewEvent()
52 wxCmdDone, EVT_CMD_DONE = NewEvent()
53 wxCmdAbort, EVT_CMD_ABORT = NewEvent()
55 def GrassCmd(cmd, stdout = None, stderr = None):
56 """!Return GRASS command thread"""
58 stdout = stdout, stderr = stderr)
61 """!Thread for GRASS commands"""
63 def __init__(self, parent, requestQ, resultQ, **kwds):
64 threading.Thread.__init__(self, **kwds)
77 CmdThread.requestId += 1
80 self.requestQ.put((CmdThread.requestId, args, kwds))
82 return CmdThread.requestId
85 """!Set starting id"""
86 CmdThread.requestId = id
89 os.environ[
'GRASS_MESSAGE_FORMAT'] =
'gui'
91 requestId, args, kwds = self.requestQ.get()
92 for key
in (
'callable',
'onDone',
'userData'):
94 vars()[key] = kwds[key]
99 if not vars()[
'callable']:
100 vars()[
'callable'] = GrassCmd
102 requestTime = time.time()
103 event = wxCmdRun(cmd = args[0],
105 wx.PostEvent(self.
parent, event)
108 self.
requestCmd = vars()[
'callable'](*args, **kwds)
110 self.requestCmd.abort()
111 if self.requestQ.empty():
114 self.resultQ.put((requestId, self.requestCmd.run()))
117 returncode = self.requestCmd.module.returncode
118 except AttributeError:
122 aborted = self.requestCmd.aborted
123 except AttributeError:
129 if UserSettings.Get(group=
'cmd', key=
'rasterColorTable', subkey=
'enabled')
and \
130 args[0][0][:2] ==
'r.':
131 colorTable = UserSettings.Get(group=
'cmd', key=
'rasterColorTable', subkey=
'selection')
133 if args[0][0] ==
'r.mapcalc':
135 mapName = args[0][1].
split(
'=', 1)[0].strip()
139 moduleInterface =
menuform.GUI(show =
None).ParseCommand(args[0])
140 outputParam = moduleInterface.get_param(value =
'output', raiseError =
False)
141 if outputParam
and outputParam[
'prompt'] ==
'raster':
142 mapName = outputParam[
'value']
145 argsColor = list(args)
146 argsColor[0] = [
'r.colors',
148 'color=%s' % colorTable ]
150 self.resultQ.put((requestId, self.requestCmdColor.run()))
152 event = wxCmdDone(cmd = args[0],
154 returncode = returncode,
157 onDone = vars()[
'onDone'],
158 userData = vars()[
'userData'])
161 wx.PostEvent(self.
parent, event)
164 """!Abort command(s)"""
167 self.requestCmd.abort()
168 if self.requestQ.empty():
172 """!Create and manage output console for commands run by GUI.
174 def __init__(self, parent, id = wx.ID_ANY, margin = False,
176 style = wx.TAB_TRAVERSAL | wx.FULL_REPAINT_ON_RESIZE,
178 wx.SplitterWindow.__init__(self, parent, id, style = style, *kwargs)
179 self.SetName(
"GMConsole")
205 range=100, pos=(110, 50), size=(-1, 25),
206 style=wx.GA_HORIZONTAL)
207 self.console_progressbar.Bind(EVT_CMD_PROGRESS, self.
OnCmdProgress)
215 self.cmd_output.Bind(EVT_CMD_OUTPUT, self.
OnCmdOutput)
217 self.Bind(EVT_CMD_RUN, self.
OnCmdRun)
223 if self.parent.GetName() !=
'LayerManager':
225 self.cmd_prompt.Hide()
231 style = wx.CP_DEFAULT_STYLE |
232 wx.CP_NO_TLW_RESIZE | wx.EXPAND)
234 self.searchPane.Collapse(
True)
253 label = _(
"&Clear output"), size=(100,-1))
255 label = _(
"C&lear cmd"), size=(100,-1))
256 if self.parent.GetName() !=
'LayerManager':
257 self.btn_cmd_clear.Hide()
259 label = _(
"&Save output"), size=(100,-1))
263 self.btn_abort.SetToolTipString(_(
"Abort the running command"))
264 self.btn_abort.Enable(
False)
266 self.btn_cmd_clear.Bind(wx.EVT_BUTTON, self.cmd_prompt.OnCmdErase)
267 self.btn_console_clear.Bind(wx.EVT_BUTTON, self.
ClearHistory)
268 self.btn_console_save.Bind(wx.EVT_BUTTON, self.
SaveHistory)
269 self.btn_abort.Bind(wx.EVT_BUTTON, self.
OnCmdAbort)
270 self.btn_abort.Bind(EVT_CMD_ABORT, self.
OnCmdAbort)
276 OutputSizer = wx.BoxSizer(wx.VERTICAL)
277 PromptSizer = wx.BoxSizer(wx.VERTICAL)
278 ButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
280 if self.
search and self.search.IsShown():
281 OutputSizer.Add(item=self.
searchPane, proportion=0,
282 flag=wx.EXPAND | wx.ALL, border=3)
283 OutputSizer.Add(item=self.
cmd_output, proportion=1,
284 flag=wx.EXPAND | wx.ALL, border=3)
286 flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=3)
288 PromptSizer.Add(item=self.
cmd_prompt, proportion=1,
289 flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=3)
292 flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE | wx.ALL, border=5)
294 flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE | wx.ALL, border=5)
296 flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE | wx.ALL, border=5)
297 ButtonSizer.Add(item=self.
btn_abort, proportion=0,
298 flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE | wx.ALL, border=5)
299 PromptSizer.Add(item=ButtonSizer, proportion=0,
300 flag=wx.ALIGN_CENTER)
302 OutputSizer.Fit(self)
303 OutputSizer.SetSizeHints(self)
305 PromptSizer.Fit(self)
306 PromptSizer.SetSizeHints(self)
308 self.panelOutput.SetSizer(OutputSizer)
309 self.panelPrompt.SetSizer(PromptSizer)
312 if self.parent.GetName() ==
'LayerManager':
314 self.SetMinimumPaneSize(self.btn_cmd_clear.GetSize()[1] + 50)
317 self.SetMinimumPaneSize(self.btn_cmd_clear.GetSize()[1] + 10)
319 self.SetSashGravity(1.0)
322 self.SetAutoLayout(
True)
326 """!Create search pane"""
327 border = wx.BoxSizer(wx.VERTICAL)
329 self.
search = SearchModuleWindow(parent = pane, cmdPrompt = self.
cmd_prompt)
331 border.Add(item = self.
search, proportion = 0,
332 flag = wx.EXPAND | wx.ALL, border = 1)
334 pane.SetSizer(border)
338 """!Collapse search module box"""
339 if self.searchPane.IsExpanded():
344 self.panelOutput.Layout()
345 self.panelOutput.SendSizeEvent()
350 @param prompt get prompt / output panel
352 @return wx.Panel reference
360 """!Redirect stdout/stderr
362 if Debug.GetLevel() == 0
and int(grass.gisenv().get(
'DEBUG', 0)) == 0:
367 enc = locale.getdefaultlocale()[1]
369 sys.stdout = codecs.getwriter(enc)(sys.__stdout__)
370 sys.stderr = codecs.getwriter(enc)(sys.__stderr__)
372 sys.stdout = sys.__stdout__
373 sys.stderr = sys.__stderr__
375 def WriteLog(self, text, style = None, wrap = None,
377 """!Generic method for writing log message in
380 @param line text line
381 @param style text style (see GMStc)
382 @param stdout write to stdout or stderr
385 self.cmd_output.SetStyle()
388 self._notebook.SetSelectionByName(
'output')
391 style = self.cmd_output.StyleDefault
394 p1 = self.cmd_output.GetEndStyled()
396 self.cmd_output.DocumentEnd()
398 for line
in text.splitlines():
404 self.cmd_output.AddTextWrapped(line, wrap=wrap)
406 p2 = self.cmd_output.GetCurrentPos()
408 self.cmd_output.StartStyling(p1, 0xff)
409 self.cmd_output.SetStyling(p2 - p1, style)
411 self.cmd_output.EnsureCaretVisible()
414 """!Write message in selected style"""
416 line =
'(' + str(pid) +
') ' + line
417 self.
WriteLog(line, style=self.cmd_output.StyleCommand, switchPage = switchPage)
420 """!Write message in warning style"""
421 self.
WriteLog(line, style=self.cmd_output.StyleWarning, switchPage =
True)
424 """!Write message in error style"""
425 self.
WriteLog(line, style = self.cmd_output.StyleError, switchPage =
True)
427 def RunCmd(self, command, compReg = True, switchPage = False,
429 """!Run command typed into console command prompt (GPrompt).
431 @todo Display commands (*.d) are captured and processed
432 separately by mapdisp.py. Display commands are rendered in map
433 display widget that currently has the focus (as indicted by
436 @param command command given as a list (produced e.g. by utils.split())
437 @param compReg True use computation region
438 @param switchPage switch to output page
439 @param onDone function to be called when command is finished
441 if len(command) == 0:
442 Debug.msg(2,
"GPrompt:RunCmd(): empty command")
448 fileHistory = codecs.open(os.path.join(env[
'GISDBASE'],
449 env[
'LOCATION_NAME'],
452 encoding =
'utf-8', mode =
'a')
459 fileHistory.write(
' '.join(command) + os.linesep)
464 if self.parent.GetName() ==
'LayerManager':
466 self.parent.cmdinput.SetHistoryItems()
467 except AttributeError:
470 if command[0]
in globalvar.grassCmd[
'all']:
473 if self.parent.GetName() ==
"LayerManager" and \
474 command[0][0:2] ==
"d." and \
475 'help' not in ' '.join(command[1:]):
478 layertype = {
'd.rast' :
'raster',
479 'd.rast3d' :
'3d-raster',
482 'd.shaded' :
'shaded',
483 'd.legend' :
'rastleg',
484 'd.rast.arrow' :
'rastarrow',
485 'd.rast.num' :
'rastnum',
487 'd.vect.thematic':
'thememap',
488 'd.vect.chart' :
'themechart',
490 'd.geodesic' :
'geodesic',
491 'd.rhumbline' :
'rhumb',
492 'd.labels' :
'labels',
493 'd.barscale' :
'barscale',
494 'd.redraw' :
'redraw'}[command[0]]
497 message = _(
"Command '%s' not yet implemented in the WxGUI. "
498 "Try adding it as a command layer instead.") % command[0])
501 if layertype ==
'barscale':
502 self.parent.curr_page.maptree.GetMapDisplay().OnAddBarscale(
None)
503 elif layertype ==
'rastleg':
504 self.parent.curr_page.maptree.GetMapDisplay().
OnAddLegend(
None)
505 elif layertype ==
'redraw':
506 self.parent.curr_page.maptree.GetMapDisplay().OnRender(
None)
509 lname, found = utils.GetLayerNameFromCmd(command, fullyQualified =
True,
510 layerType = layertype)
511 if self.parent.GetName() ==
"LayerManager":
512 self.parent.curr_page.maptree.AddLayer(ltype = layertype,
518 if sys.platform ==
'win32':
519 if command[0]
in globalvar.grassCmd[
'script']:
520 command[0] += globalvar.EXT_SCT
522 if command[0] !=
'r.mapcalc':
525 options = task.get_options()
526 hasParams = options[
'params']
and options[
'flags']
528 for p
in options[
'params']:
529 if p.get(
'prompt',
'') ==
'input' and \
530 p.get(
'element',
'') ==
'file' and \
531 p.get(
'age',
'new') ==
'old_file' and \
532 p.get(
'value',
'') ==
'-':
534 message = _(
"Unable to run command:\n%(cmd)s\n\n"
535 "Option <%(opt)s>: read from standard input is not "
536 "supported by wxGUI") % {
'cmd':
' '.join(command),
537 'opt': p.get(
'name',
'') })
542 if len(command) == 1
and hasParams:
547 print >> sys.stderr, e
552 self._notebook.SetSelectionByName(
'output')
554 self.parent.SetFocus()
560 tmpreg = os.getenv(
"GRASS_REGION")
561 if "GRASS_REGION" in os.environ:
562 del os.environ[
"GRASS_REGION"]
567 self.cmd_output_timer.Start(50)
570 if compReg
and tmpreg:
571 os.environ[
"GRASS_REGION"] = tmpreg
575 if len(command) == 1:
577 task = gtask.parse_interface(command[0])
589 self.cmd_output_timer.Start(50)
594 """!Clear history of commands"""
595 self.cmd_output.SetReadOnly(
False)
596 self.cmd_output.ClearAll()
597 self.cmd_output.SetReadOnly(
True)
598 self.console_progressbar.SetValue(0)
601 """!Return progress bar widget"""
605 """!Get widget used for logging
607 @param err True to get stderr widget
615 """!Save history of commands"""
616 self.
history = self.cmd_output.GetSelectedText()
618 self.
history = self.cmd_output.GetText()
624 wildcard =
"Text file (*.txt)|*.txt"
625 dlg = wx.FileDialog(self, message = _(
"Save file as..."), defaultDir = os.getcwd(),
626 defaultFile =
"grass_cmd_history.txt", wildcard = wildcard,
627 style = wx.SAVE | wx.FD_OVERWRITE_PROMPT)
631 if dlg.ShowModal() == wx.ID_OK:
634 output = open(path,
"w")
641 """!Get running command or None"""
642 return self.requestQ.get()
645 """!Enable or disable copying of selected text in to clipboard.
646 Effects prompt and output.
648 @param copy True for enable, False for disable
651 self.cmd_prompt.Bind(wx.stc.EVT_STC_PAINTED, self.cmd_prompt.OnTextSelectionChanged)
652 self.cmd_output.Bind(wx.stc.EVT_STC_PAINTED, self.cmd_output.OnTextSelectionChanged)
654 self.cmd_prompt.Unbind(wx.stc.EVT_STC_PAINTED)
655 self.cmd_output.Unbind(wx.stc.EVT_STC_PAINTED)
658 """!Update statusbar text"""
659 if event.GetString():
660 nItems = len(self.cmd_prompt.GetCommandItems())
661 self.parent.SetStatusText(_(
'%d modules match') % nItems, 0)
663 self.parent.SetStatusText(
'', 0)
668 """!Print command output"""
671 if self._notebook.GetSelection() != self._notebook.GetPageIndexByName(
'output'):
672 page = self._notebook.GetPageIndexByName(
'output')
673 textP = self._notebook.GetPageText(page)
676 self._notebook.SetPageText(page, textP)
679 if type ==
'warning':
680 messege =
'WARNING: ' + message
681 elif type ==
'error':
682 message =
'ERROR: ' + message
684 p1 = self.cmd_output.GetEndStyled()
685 self.cmd_output.GotoPos(p1)
696 pos = self.cmd_output.GetCurLine()[1]
699 self.cmd_output.SetCurrentPos(self.
linepos)
700 self.cmd_output.ReplaceSelection(c)
701 self.
linepos = self.cmd_output.GetCurrentPos()
704 if last_c
not in (
'0123456789'):
705 self.cmd_output.AddTextWrapped(
'\n', wrap=
None)
709 if '\n' not in message:
710 self.cmd_output.AddTextWrapped(message, wrap=60)
712 self.cmd_output.AddTextWrapped(message, wrap=
None)
714 p2 = self.cmd_output.GetCurrentPos()
717 self.cmd_output.StartStyling(p1, 0xff)
720 self.cmd_output.SetStyling(p2 - p1, self.cmd_output.StyleError)
721 elif type ==
'warning':
722 self.cmd_output.SetStyling(p2 - p1, self.cmd_output.StyleWarning)
723 elif type ==
'message':
724 self.cmd_output.SetStyling(p2 - p1, self.cmd_output.StyleMessage)
726 self.cmd_output.SetStyling(p2 - p1, self.cmd_output.StyleUnknown)
728 self.cmd_output.EnsureCaretVisible()
731 """!Update progress message info"""
732 self.console_progressbar.SetValue(event.value)
735 """!Abort running command"""
736 self.cmdThread.abort()
740 if self.parent.GetName() ==
'Modeler':
741 self.parent.OnCmdRun(event)
743 self.
WriteCmdLog(
'(%s)\n%s' % (str(time.ctime()),
' '.join(event.cmd)))
744 self.btn_abort.Enable()
747 """!Command done (or aborted)"""
748 if self.parent.GetName() ==
'Modeler':
749 self.parent.OnCmdDone(event)
753 self.
WriteLog(_(
'Please note that the data are left in inconsistent state '
754 'and may be corrupted'), self.cmd_output.StyleWarning)
755 self.
WriteCmdLog(
'(%s) %s (%d sec)' % (str(time.ctime()),
756 _(
'Command aborted'),
757 (time.time() - event.time)))
759 self.btn_abort.Enable(
False)
763 self.
WriteCmdLog(
'(%s) %s (%d sec)' % (str(time.ctime()),
764 _(
'Command finished'),
765 (time.time() - event.time)))
770 self.btn_abort.Enable(
False)
773 event.onDone(cmd = event.cmd, returncode = event.returncode)
775 self.console_progressbar.SetValue(0)
777 self.cmd_output_timer.Stop()
779 if event.cmd[0] ==
'g.gisenv':
783 if self.parent.GetName() ==
"LayerManager":
784 self.btn_abort.Enable(
False)
785 if event.cmd[0]
not in globalvar.grassCmd[
'all']
or \
786 event.cmd[0] ==
'r.mapcalc':
789 display = self.parent.GetLayerTree().GetMapDisplay()
790 if not display
or not display.IsAutoRendered():
792 mapLayers =
map(
lambda x: x.GetName(),
793 display.GetRender().GetListOfLayers(l_type =
'raster') +
794 display.GetRender().GetListOfLayers(l_type =
'vector'))
797 task =
menuform.GUI(show =
None).ParseCommand(event.cmd)
799 print >> sys.stderr, e
803 for p
in task.get_options()[
'params']:
804 if p.get(
'prompt',
'')
not in (
'raster',
'vector'):
806 mapName = p.get(
'value',
'')
807 if '@' not in mapName:
808 mapName = mapName +
'@' + grass.gisenv()[
'MAPSET']
809 if mapName
in mapLayers:
810 display.GetWindow().UpdateMap(render =
True)
812 elif self.parent.GetName() ==
'Modeler':
815 dialog = self.parent.parent
816 if hasattr(self.parent.parent,
"btn_abort"):
817 dialog.btn_abort.Enable(
False)
819 if hasattr(self.parent.parent,
"btn_cancel"):
820 dialog.btn_cancel.Enable(
True)
822 if hasattr(self.parent.parent,
"btn_clipboard"):
823 dialog.btn_clipboard.Enable(
True)
825 if hasattr(self.parent.parent,
"btn_help"):
826 dialog.btn_help.Enable(
True)
828 if hasattr(self.parent.parent,
"btn_run"):
829 dialog.btn_run.Enable(
True)
831 if event.returncode == 0
and not event.aborted:
833 winName = self.parent.parent.parent.GetName()
834 except AttributeError:
837 if winName ==
'LayerManager':
838 mapTree = self.parent.parent.parent.GetLayerTree()
839 elif winName ==
'LayerTree':
840 mapTree = self.parent.parent.parent
842 mapTree = self.parent.parent.parent.parent.GetLayerTree()
846 cmd = dialog.notebookpanel.createCmd(ignoreErrors =
True)
847 if hasattr(dialog,
"addbox")
and dialog.addbox.IsChecked():
849 for p
in dialog.task.get_options()[
'params']:
850 prompt = p.get(
'prompt',
'')
851 if prompt
in (
'raster',
'vector',
'3d-raster')
and \
852 p.get(
'age',
'old') ==
'new' and \
853 p.get(
'value',
None):
854 name, found = utils.GetLayerNameFromCmd(cmd, fullyQualified =
True,
855 param = p.get(
'name',
''))
857 if mapTree.GetMap().GetListOfLayers(l_name = name):
860 if prompt ==
'raster':
866 mapTree.AddLayer(ltype = prompt,
870 if hasattr(dialog,
"get_dcmd")
and \
871 dialog.get_dcmd
is None and \
872 hasattr(dialog,
"closebox")
and \
873 dialog.closebox.IsChecked()
and \
874 (event.returncode == 0
or event.aborted):
875 self.cmd_output.Update()
880 self.ProcessPendingEvents()
883 """!GMConsole standard output
885 Based on FrameOutErr.py
888 Purpose: Redirecting stdout / stderr
889 Author: Jean-Michel Fauth, Switzerland
890 Copyright: (c) 2005-2007 Jean-Michel Fauth
897 if len(s) == 0
or s ==
'\n':
900 for line
in s.splitlines():
904 evt = wxCmdOutput(text=line +
'\n',
906 wx.PostEvent(self.parent.cmd_output, evt)
909 """!GMConsole standard error output
911 Based on FrameOutErr.py
914 Purpose: Redirecting stdout / stderr
915 Author: Jean-Michel Fauth, Switzerland
916 Copyright: (c) 2005-2007 Jean-Michel Fauth
936 for line
in s.splitlines():
940 if 'GRASS_INFO_PERCENT' in line:
941 value = int(line.rsplit(
':', 1)[1].strip())
942 if value >= 0
and value < 100:
943 progressValue = value
946 elif 'GRASS_INFO_MESSAGE' in line:
947 self.type =
'message'
948 self.message += line.split(
':', 1)[1].strip() +
'\n'
949 elif 'GRASS_INFO_WARNING' in line:
950 self.type =
'warning'
951 self.message += line.split(
':', 1)[1].strip() +
'\n'
952 elif 'GRASS_INFO_ERROR' in line:
954 self.message += line.split(
':', 1)[1].strip() +
'\n'
955 elif 'GRASS_INFO_END' in line:
956 self.printMessage =
True
957 elif self.type ==
'':
960 evt = wxCmdOutput(text=line,
962 wx.PostEvent(self.parent.cmd_output, evt)
964 self.message += line.strip() +
'\n'
966 if self.printMessage
and len(self.message) > 0:
967 evt = wxCmdOutput(text=self.message,
969 wx.PostEvent(self.parent.cmd_output, evt)
973 self.printMessage =
False
976 if progressValue > -1:
978 evt = wxCmdProgress(value=progressValue)
979 wx.PostEvent(self.parent.console_progressbar, evt)
984 Based on FrameOutErr.py
987 Purpose: Redirecting stdout / stderr
988 Author: Jean-Michel Fauth, Switzerland
989 Copyright: (c) 2005-2007 Jean-Michel Fauth
992 def __init__(self, parent, id, margin=False, wrap=None):
993 wx.stc.StyledTextCtrl.__init__(self, parent, id)
995 self.SetUndoCollection(
True)
996 self.SetReadOnly(
True)
1007 self.SetMarginWidth(1, 0)
1008 self.SetMarginWidth(2, 0)
1010 self.SetMarginType(0, wx.stc.STC_MARGIN_NUMBER)
1011 self.SetMarginWidth(0, 30)
1013 self.SetMarginWidth(0, 0)
1018 self.SetViewWhiteSpace(
False)
1020 self.SetUseTabs(
False)
1022 self.SetSelBackground(
True,
"#FFFF00")
1023 self.SetUseHorizontalScrollBar(
True)
1028 self.Bind(wx.EVT_WINDOW_DESTROY, self.
OnDestroy)
1031 """!Copy selected text to clipboard and skip event.
1032 The same function is in TextCtrlAutoComplete class (prompt.py).
1038 """!Set styles for styled text output windows with type face
1039 and point size selected by user (Courier New 10 is default)"""
1043 typeface = settings.Get(group =
'appearance', key =
'outputfont', subkey =
'type')
1045 typeface =
"Courier New"
1047 typesize = settings.Get(group =
'appearance', key =
'outputfont', subkey =
'size')
1048 if typesize ==
None or typesize <= 0:
1050 typesize = float(typesize)
1057 self.
StyleOutputSpec =
"face:%s,size:%d,,fore:#000000,back:#FFFFFF" % (typeface, typesize)
1060 self.
StyleErrorSpec =
"face:%s,size:%d,,fore:#7F0000,back:#FFFFFF" % (typeface, typesize)
1073 self.StyleClearAll()
1082 """!The clipboard contents can be preserved after
1083 the app has exited"""
1085 wx.TheClipboard.Flush()
1089 """!Add string to text area.
1091 String is wrapped and linesep is also added to the end
1094 self.SetReadOnly(
False)
1097 txt = textwrap.fill(txt, wrap) +
'\n'
1103 self.parent.linePos = -1
1104 for seg
in txt.split(
'\r'):
1105 if self.parent.linePos > -1:
1106 self.SetCurrentPos(self.parent.linePos)
1107 self.ReplaceSelection(seg)
1109 self.parent.linePos = self.GetCurrentPos()
1112 self.parent.linePos = self.GetCurrentPos()
1115 except UnicodeDecodeError:
1116 enc = UserSettings.Get(group=
'atm', key=
'encoding', subkey=
'value')
1118 txt = unicode(txt, enc)
1119 elif 'GRASS_DB_ENCODING' in os.environ:
1120 txt = unicode(txt, os.environ[
'GRASS_DB_ENCODING'])
1122 txt = utils.EncodeString(txt)
1127 self.SetReadOnly(
True)