~ubuntu-branches/ubuntu/quantal/python-pyo/quantal

« back to all changes in this revision

Viewing changes to utils/E-Pyo.py

  • Committer: Package Import Robot
  • Author(s): Tiago Bortoletto Vaz
  • Date: 2012-07-03 23:45:41 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120703234541-jh5jg00lvljnwq8m
Tags: 0.6.2-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 
10
10
"""
11
11
from __future__ import with_statement
12
 
import sys, os, string, inspect, keyword, wx, codecs, subprocess, unicodedata, contextlib, StringIO, shutil, copy, pprint, random, time
13
 
from types import UnicodeType, MethodType
 
12
import sys, os, string, inspect, keyword, wx, codecs, subprocess, unicodedata, contextlib, StringIO, shutil, copy, pprint, random, time, threading
 
13
from types import UnicodeType, MethodType, ListType
14
14
from wx.lib.wordwrap import wordwrap
15
15
from wx.lib.embeddedimage import PyEmbeddedImage
16
16
import wx.lib.colourselect as csel
36
36
                'utf_32_be', 'utf-32 (Little Endian)': 'utf_32_le'}
37
37
 
38
38
APP_NAME = 'E-Pyo'
39
 
APP_VERSION = '0.6.1'
 
39
APP_VERSION = PYO_VERSION
40
40
OSX_APP_BUNDLED = False
41
41
WIN_APP_BUNDLED = False
42
 
if PLATFORM == "win32":
43
 
    TEMP_PATH = os.path.join(os.path.expanduser('~'), "My Documents", ".epyo")
44
 
else:
45
 
    TEMP_PATH = os.path.join(os.path.expanduser('~'), '.epyo')
 
42
 
 
43
TEMP_PATH = os.path.join(os.path.expanduser('~'), '.epyo')
46
44
if not os.path.isdir(TEMP_PATH):
47
45
    os.mkdir(TEMP_PATH)
48
46
 
56
54
exec text in locals()
57
55
PREFERENCES = copy.deepcopy(epyo_prefs)
58
56
 
 
57
tmp_version = PREFERENCES.get("version", "no_version_pref")
 
58
if tmp_version != APP_VERSION:
 
59
    tmp_version = APP_VERSION
 
60
    print "Erasing preferences..."
 
61
    shutil.rmtree(os.path.join(TEMP_PATH, "doc"), True)
 
62
    PREFERENCES = {}
 
63
PREFERENCES["version"] = tmp_version
 
64
 
59
65
RESOURCES_PATH = PREFERENCES.get("resources_path", TEMP_PATH)
60
66
 
61
67
TEMP_FILE = os.path.join(TEMP_PATH, 'epyo_tempfile.py')
103
109
if OSX_APP_BUNDLED:
104
110
    tmphome = os.environ["PYTHONHOME"]
105
111
    tmppath = os.environ["PYTHONPATH"]
106
 
    cmd = 'export -n PYTHONHOME PYTHONPATH;env;%s -c "import pyo";export PYTHONHOME=%s;export PYTHONPATH=%s' % (WHICH_PYTHON, tmphome, tmppath)
107
 
    cmd2 = 'export -n PYTHONHOME PYTHONPATH;env;%s -c "import wx";export PYTHONHOME=%s;export PYTHONPATH=%s' % (WHICH_PYTHON, tmphome, tmppath)
 
112
    tmpexecpath = os.environ["EXECUTABLEPATH"]
 
113
    tmprscpath = os.environ["RESOURCEPATH"]
 
114
    tmpargv0 = os.environ["ARGVZERO"]
 
115
    cmd = 'export -n PYTHONHOME PYTHONPATH EXECUTABLEPATH RESOURCEPATH ARGVZERO;env;%s -c "import pyo";export PYTHONHOME=%s;export PYTHONPATH=%s;export EXECUTABLEPATH=%s;export RESOURCEPATH=%s;export ARGVZERO=%s' % (WHICH_PYTHON, tmphome, tmppath, tmpexecpath, tmprscpath, tmpargv0)
 
116
    cmd2 = 'export -n PYTHONHOME PYTHONPATH EXECUTABLEPATH RESOURCEPATH ARGVZERO;env;%s -c "import wx";export PYTHONHOME=%s;export PYTHONPATH=%s;export EXECUTABLEPATH=%s;export RESOURCEPATH=%s;export ARGVZERO=%s' % (WHICH_PYTHON, tmphome, tmppath, tmpexecpath, tmprscpath, tmpargv0)
108
117
else:
109
118
    cmd = '%s -c "import pyo"' % WHICH_PYTHON
110
119
    cmd2 = '%s -c "import wx"' % WHICH_PYTHON
255
264
    lv = len(value)
256
265
    return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3))
257
266
 
258
 
################## AppleScript for Mac bundle ##################
259
 
if OSX_APP_BUNDLED:
260
 
    terminal_close_server_script = """tell application "Terminal" 
261
 
    close window 1
262
 
end tell
263
 
    """
264
 
    terminal_close_server_script = convert_line_endings(terminal_close_server_script, 1)
265
 
    terminal_close_server_script_path = os.path.join(TEMP_PATH, "terminal_close_server_script.scpt")
266
 
 
267
 
    terminal_server_script = """tell application "Terminal"
268
 
    do script ""
269
 
    set a to get id of front window
270
 
    set custom title of window id a to "E-Pyo Output"
271
 
    set custom title of tab 1 of window id a to "E-Pyo Output"
272
 
    set current settings of first window to settings set "Homebrew"
273
 
    set the number of columns of window 1 to 80
274
 
    set the number of rows of window 1 to 30
275
 
    set the position of window 1 to {810, 25}
276
 
end tell
277
 
    """
278
 
    terminal_server_script = convert_line_endings(terminal_server_script, 1)
279
 
    terminal_server_script_path = os.path.join(TEMP_PATH, "terminal_server_script.scpt")
280
 
    f = open(terminal_server_script_path, "w")
281
 
    f.write(terminal_server_script)
282
 
    f.close()
283
 
    pid = subprocess.Popen(["osascript", terminal_server_script_path]).pid
284
 
    
285
 
    terminal_client_script = """set my_path to quoted form of POSIX path of "%s"
286
 
set my_file to quoted form of POSIX path of "%s"
287
 
set which_python to quoted form of POSIX path of "%s"
288
 
tell application "System Events"
289
 
    tell application process "Terminal"
290
 
    set frontmost to true
291
 
    keystroke "clear"
292
 
    keystroke return
293
 
    delay 0.25
294
 
    keystroke "cd " & my_path
295
 
    keystroke return
296
 
    delay 0.25
297
 
    keystroke "%s" & which_python & " " & my_file & " &"
298
 
    keystroke return
299
 
    delay 0.25
300
 
    end tell
301
 
    tell application process "E-Pyo"
302
 
    set frontmost to true
303
 
    end tell
304
 
end tell
305
 
    """
306
 
    terminal_client_script_path = os.path.join(TEMP_PATH, "terminal_client_script.scpt")
307
 
 
308
267
################## TEMPLATES ##################
309
268
HEADER_TEMPLATE = """#!/usr/bin/env python
310
269
# encoding: utf-8
743
702
 
744
703
snip_faces = {'face': DEFAULT_FONT_FACE, 'size': FONT_SIZE}
745
704
 
 
705
class RunningThread(threading.Thread):
 
706
    def __init__(self, path, cwd, outputlog, removeProcess):
 
707
        threading.Thread.__init__(self)
 
708
        self.path = path
 
709
        self.cwd = cwd
 
710
        self.outputlog = outputlog
 
711
        self.removeProcess = removeProcess
 
712
        self.terminated = False
 
713
        self.pid = None
 
714
    
 
715
    def setFileName(self, filename):
 
716
        self.filename = filename
 
717
 
 
718
    def setPID(self, pid):
 
719
        self.pid = pid
 
720
 
 
721
    def kill(self):
 
722
        self.terminated = True
 
723
        if PLATFORM == "win32":
 
724
            try:
 
725
                os.system("tskill %d" % self.proc.pid)
 
726
            except:
 
727
                print "'tskill' doesn't seem to be installed on the system. It is needed to be able to kill a process."
 
728
        else:
 
729
            self.proc.terminate()
 
730
        if self.proc.poll() == None:
 
731
            self.proc.kill()
 
732
 
 
733
    def run(self):
 
734
        if OSX_APP_BUNDLED:
 
735
            vars_to_remove = "PYTHONHOME PYTHONPATH EXECUTABLEPATH RESOURCEPATH ARGVZERO PYTHONOPTIMIZE"
 
736
            prelude = "export -n %s;export PATH=/usr/local/bin:/usr/local/lib:$PATH;" % vars_to_remove
 
737
            if CALLER_NEED_TO_INVOKE_32_BIT:
 
738
                self.proc = subprocess.Popen(['%s%s%s "%s"' % (prelude, SET_32_BIT_ARCH, WHICH_PYTHON, self.path)], 
 
739
                                shell=True, cwd=self.cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
740
            else:
 
741
                self.proc = subprocess.Popen(['%s%s "%s"' % (prelude, WHICH_PYTHON, self.path)], cwd=self.cwd, 
 
742
                                    shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
743
        elif PLATFORM == "darwin":
 
744
            if CALLER_NEED_TO_INVOKE_32_BIT:
 
745
                self.proc = subprocess.Popen(['%s%s "%s"' % (SET_32_BIT_ARCH, WHICH_PYTHON, self.path)], 
 
746
                                shell=True, cwd=self.cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
747
            else:
 
748
                self.proc = subprocess.Popen(['%s "%s"' % (WHICH_PYTHON, self.path)], cwd=self.cwd, 
 
749
                                shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
750
        elif PLATFORM == "win32":
 
751
            self.proc = subprocess.Popen([WHICH_PYTHON, self.path], cwd=self.cwd, shell=False, 
 
752
                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
753
        else:
 
754
            self.proc = subprocess.Popen([WHICH_PYTHON, self.path], cwd=self.cwd, 
 
755
                                shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
756
 
 
757
        while self.proc.poll() == None and not self.terminated:
 
758
            time.sleep(.25)
 
759
        stdout, stderr = self.proc.communicate()
 
760
        header = '=== Output log of process "%s", launched: %s ===\n' % (self.filename, time.strftime('"%d %b %Y %H:%M:%S"', time.localtime()))
 
761
        output = header + stdout + stderr
 
762
        if "StartNotification name = default" in output:
 
763
            output = output.replace("StartNotification name = default", "")
 
764
        if "epyo_tempfile.py" in output:
 
765
            try:
 
766
                findpos = output.find("epyo_tempfile.py")
 
767
                pos = findpos
 
768
                while (output[pos] != '"'):
 
769
                    pos -= 1
 
770
                startpos = pos + 1
 
771
                pos = findpos
 
772
                while (output[pos] != '"'):
 
773
                    pos += 1
 
774
                endpos = pos
 
775
                output = output[:startpos] + self.filename + output[endpos:]
 
776
                pos = startpos + len(self.filename)
 
777
                slinepos = pos + 8
 
778
                pos = slinepos
 
779
                while (output[pos] != ',' and output[pos] != '\n'):
 
780
                    pos += 1
 
781
                elinepos = pos
 
782
                linenum = int(output[slinepos:elinepos].strip())
 
783
                output = output[:slinepos] + str(linenum-2) + output[elinepos:]
 
784
            except:
 
785
                pass
 
786
        if self.terminated:
 
787
            output = output + "\n=== Process killed. ==="
 
788
        self.outputlog(output)
 
789
        self.removeProcess(self.pid, self.filename)
 
790
 
746
791
class KeyCommandsFrame(wx.Frame):
747
792
    def __init__(self, parent):
748
793
        wx.Frame.__init__(self, parent, wx.ID_ANY, title="Editor Key Commands List", size=(650,550))
1632
1677
        self.server_pipe = None
1633
1678
        self.back_server_started = False
1634
1679
 
 
1680
        self.processID = 0
 
1681
        self.processes = {}
 
1682
 
1635
1683
        self.print_data = wx.PrintData()
1636
1684
        self.print_data.SetPaperId(wx.PAPER_LETTER)
1637
1685
 
1717
1765
        self.Bind(wx.EVT_MENU, self.saveListPaste, id=202)
1718
1766
        menu2.Append(203, "Load Pasting List")
1719
1767
        self.Bind(wx.EVT_MENU, self.loadListPaste, id=203)
 
1768
        menu2.Append(204, "Edit Pasting List")
 
1769
        self.Bind(wx.EVT_MENU, self.editPastingList, id=204)
1720
1770
        menu2.AppendSeparator()
1721
1771
        menu2.Append(107, "Remove Trailing White Space")
1722
1772
        self.Bind(wx.EVT_MENU, self.removeTrailingWhiteSpace, id=107)
1785
1835
        self.Bind(wx.EVT_MENU, self.showHideFolderPanel, id=50)
1786
1836
        self.showMarkItem = menu4.Append(49, "Show Markers Panel", kind=wx.ITEM_CHECK)
1787
1837
        self.Bind(wx.EVT_MENU, self.showHideMarkersPanel, id=49)
 
1838
        self.showOutputItem = menu4.Append(48, "Show Output Panel", kind=wx.ITEM_CHECK)
 
1839
        self.Bind(wx.EVT_MENU, self.showHideOutputPanel, id=48)
1788
1840
        menu4.AppendSeparator()
1789
1841
        menu4.Append(190, "Open Documentation Frame\tShift+Ctrl+D")
1790
1842
        self.Bind(wx.EVT_MENU, self.showDocFrame, id=190)
1889
1941
 
1890
1942
        self.showProjectTree(PREFERENCES.get("show_folder_panel", 0))
1891
1943
        self.showMarkersPanel(PREFERENCES.get("show_markers_panel", 0))
 
1944
        self.showOutputPanel(PREFERENCES.get("show_output_panel", 1))
1892
1945
 
1893
1946
        if INSTALLATION_ERROR_MESSAGE != "":
1894
1947
            report = wx.MessageDialog(self, INSTALLATION_ERROR_MESSAGE, "Installation Report", wx.OK|wx.ICON_INFORMATION|wx.STAY_ON_TOP)
2017
2070
            if dlg.ShowModal() == wx.ID_OK:
2018
2071
                path = ensureNFD(dlg.GetPath())
2019
2072
                with open(path, "w") as f:
2020
 
                    for line in self.pastingList:
2021
 
                        if not line.endswith("\n"):
2022
 
                            line = line + "\n"
2023
 
                        f.write(line)
 
2073
                    f.write(str(self.pastingList))
2024
2074
 
2025
2075
    def loadListPaste(self, evt):
2026
2076
        dlg = wx.FileDialog(self, message="Choose a file", 
2027
2077
            defaultDir=os.path.expanduser("~"), style=wx.OPEN)
2028
2078
        if dlg.ShowModal() == wx.ID_OK:
2029
2079
            path = dlg.GetPath()
 
2080
            self.pastingList = []
2030
2081
            with open(path, "r") as f:
2031
 
                self.pastingList = f.readlines()
 
2082
                try:
 
2083
                    pastingList = eval(f.read())
 
2084
                    if type(pastingList) == ListType:
 
2085
                        self.pastingList = pastingList
 
2086
                except:
 
2087
                    f.seek(0)
 
2088
                    for line in f:
 
2089
                        if line.replace("\n", "").strip() != "":
 
2090
                            self.pastingList.append(line)
 
2091
 
 
2092
    def editPastingList(self, evt):
 
2093
        f = PastingListEditorFrame(self, self.pastingList)
 
2094
        f.Show()
2032
2095
 
2033
2096
    def selectall(self, evt):
2034
2097
        self.panel.editor.SelectAll()
2206
2269
            ed.setStyle()
2207
2270
        self.panel.project.setStyle()
2208
2271
        self.panel.markers.scroll.setStyle()
 
2272
        self.panel.outputlog.editor.setStyle()
2209
2273
 
2210
2274
        PREFERENCES["pref_style"] = st
2211
2275
 
2241
2305
        state = evt.GetInt()
2242
2306
        self.showMarkersPanel(state)
2243
2307
 
 
2308
    def showHideOutputPanel(self, evt):
 
2309
        state = evt.GetInt()
 
2310
        self.showOutputPanel(state)
 
2311
 
2244
2312
    def showProjectTree(self, state):
2245
2313
        self.showProjItem.Check(state)
2246
2314
        PREFERENCES["show_folder_panel"] = state
2248
2316
            if self.panel.project.IsShownOnScreen():
2249
2317
                return
2250
2318
            if not self.panel.splitter.IsSplit():
2251
 
                self.panel.splitter.SplitVertically(self.panel.left_splitter, self.panel.notebook, 175)
 
2319
                self.panel.splitter.SplitVertically(self.panel.left_splitter, self.panel.right_splitter, 175)
2252
2320
                h = self.panel.GetSize()[1]
2253
2321
                self.panel.left_splitter.SplitHorizontally(self.panel.project, self.panel.markers, h*3/4)
2254
2322
                self.panel.left_splitter.Unsplit(self.panel.markers)
2268
2336
            if self.panel.markers.IsShownOnScreen():
2269
2337
                return
2270
2338
            if not self.panel.splitter.IsSplit():
2271
 
                self.panel.splitter.SplitVertically(self.panel.left_splitter, self.panel.notebook, 175)
 
2339
                self.panel.splitter.SplitVertically(self.panel.left_splitter, self.panel.right_splitter, 175)
2272
2340
                h = self.panel.GetSize()[1]
2273
2341
                self.panel.left_splitter.SplitHorizontally(self.panel.project, self.panel.markers, h*3/4)
2274
2342
                self.panel.left_splitter.Unsplit(self.panel.project)
2281
2349
            else:
2282
2350
                self.panel.splitter.Unsplit(self.panel.left_splitter)
2283
2351
 
 
2352
    def showOutputPanel(self, state):
 
2353
        self.showOutputItem.Check(state)
 
2354
        PREFERENCES["show_output_panel"] = state
 
2355
        if state:
 
2356
            if self.panel.outputlog.IsShownOnScreen():
 
2357
                return
 
2358
            h = self.panel.GetSize()[1]
 
2359
            self.panel.right_splitter.SplitHorizontally(self.panel.notebook, self.panel.outputlog, h*4/5 - h)
 
2360
        else:
 
2361
            if not self.panel.outputlog.IsShownOnScreen():
 
2362
                return
 
2363
            self.panel.right_splitter.Unsplit(self.panel.outputlog)
2284
2364
 
2285
2365
    ### New / Open / Save / Delete ###
2286
2366
    def new(self, event):
2443
2523
            newtext += line + "\n"
2444
2524
        return newtext
2445
2525
 
 
2526
    def appendLog(self, text):
 
2527
        self.panel.outputlog.setLog(text)
 
2528
 
2446
2529
    def run(self, path):
2447
2530
        cwd = self.getCurrentWorkingDirectory()
2448
 
        if OSX_APP_BUNDLED:
2449
 
            if CALLER_NEED_TO_INVOKE_32_BIT:
2450
 
                script = terminal_client_script % (cwd, path, WHICH_PYTHON, SET_32_BIT_ARCH)
2451
 
            else:
2452
 
                script = terminal_client_script % (cwd, path, WHICH_PYTHON, "")
2453
 
            script = convert_line_endings(script, 1)
2454
 
            with codecs.open(terminal_client_script_path, "w", encoding="utf-8") as f:
2455
 
                f.write(script)
2456
 
            pid = subprocess.Popen(["osascript", terminal_client_script_path]).pid
2457
 
        elif PLATFORM == "darwin":
2458
 
            if CALLER_NEED_TO_INVOKE_32_BIT:
2459
 
                pid = subprocess.Popen(["%s%s %s" % (SET_32_BIT_ARCH, WHICH_PYTHON, path)], cwd=cwd, shell=True).pid
2460
 
            else:
2461
 
                pid = subprocess.Popen([WHICH_PYTHON, path], cwd=cwd).pid
2462
 
        elif PLATFORM == "linux2":
2463
 
            pid = subprocess.Popen([WHICH_PYTHON, path], cwd=cwd).pid
2464
 
        elif PLATFORM == "win32":
2465
 
            pid = subprocess.Popen([WHICH_PYTHON, path], cwd=cwd).pid
 
2531
        th = RunningThread(path, cwd, self.appendLog, self.panel.outputlog.removeProcess)
 
2532
        if "Untitled-" in self.panel.editor.path:
 
2533
            filename = self.panel.editor.path
 
2534
        else:
 
2535
            filename = os.path.split(self.panel.editor.path)[1]
 
2536
        th.setFileName(filename)
 
2537
        th.setPID(self.processID)
 
2538
        self.processes[self.processID] = [th, filename]
 
2539
        self.panel.outputlog.addProcess(self.processID, filename)
 
2540
        self.processID += 1
 
2541
        th.start()
2466
2542
 
2467
2543
    def runner(self, event):
2468
2544
        text = self.panel.editor.GetTextUTF8()
2629
2705
        except:
2630
2706
            pass
2631
2707
        self.panel.OnQuit()
2632
 
        if OSX_APP_BUNDLED:
2633
 
            with open(terminal_close_server_script_path, "w") as f:
2634
 
                f.write(terminal_close_server_script)
2635
 
            subprocess.Popen(["osascript", terminal_close_server_script_path])
2636
2708
        self.Destroy()
2637
2709
 
2638
2710
    def getPrintData(self):
2685
2757
        self.splitter.SetMinimumPaneSize(150)
2686
2758
 
2687
2759
        self.left_splitter = wx.SplitterWindow(self.splitter, -1, style=wx.SP_LIVE_UPDATE|wx.SP_3DSASH)
 
2760
        self.right_splitter = wx.SplitterWindow(self.splitter, -1, style=wx.SP_LIVE_UPDATE|wx.SP_3DSASH)
 
2761
        #self.right_splitter.SetMinimumPaneSize(150)
2688
2762
 
2689
2763
        self.project = ProjectTree(self.left_splitter, self, (-1, -1))
2690
2764
        self.markers = MarkersPanel(self.left_splitter, self, (-1, -1))
2691
2765
 
2692
 
        self.notebook = FNB.FlatNotebook(self.splitter, size=(0,-1), 
 
2766
        self.notebook = FNB.FlatNotebook(self.right_splitter, size=(-1,-1), 
2693
2767
                        style=FNB.FNB_FF2|FNB.FNB_X_ON_TAB|FNB.FNB_NO_X_BUTTON|FNB.FNB_DROPDOWN_TABS_LIST|FNB.FNB_HIDE_ON_SINGLE_TAB)
2694
2768
        self.addNewPage()
2695
 
 
2696
 
        self.splitter.SplitVertically(self.left_splitter, self.notebook, 175)
 
2769
        self.outputlog = OutputLogPanel(self.right_splitter, self, size=(-1,150))
 
2770
 
 
2771
        self.right_splitter.SplitHorizontally(self.notebook, self.outputlog, (self.GetSize()[1]*4/5) - self.GetSize()[1])
 
2772
 
 
2773
        self.splitter.SplitVertically(self.left_splitter, self.right_splitter, 175)
2697
2774
        self.splitter.Unsplit(self.left_splitter)
2698
2775
 
2699
2776
        mainBox.Add(self.splitter, 1, wx.EXPAND)
3418
3495
        if self.GetLineUTF8(prevline).strip().endswith(":"):
3419
3496
            indent = self.GetLineIndentation(prevline)
3420
3497
            self.addText(" "*(indent+4), False)
 
3498
        elif self.GetLineIndentation(prevline) != 0 and self.GetLineUTF8(prevline).strip() != "":
 
3499
            indent = self.GetLineIndentation(prevline)
 
3500
            self.addText(" "*indent, False)
3421
3501
 
3422
3502
    def processTab(self, currentword, autoCompActive, charat, pos):
3423
3503
        propagate = self.showAutoComp()
3766
3846
                line = line + 1
3767
3847
        return line
3768
3848
 
 
3849
class SimpleEditor(stc.StyledTextCtrl):
 
3850
    def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style= wx.NO_BORDER):
 
3851
        stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
 
3852
 
 
3853
        self.panel = parent
 
3854
 
 
3855
        self.alphaStr = string.lowercase + string.uppercase + '0123456789'
 
3856
 
 
3857
        self.Colourise(0, -1)
 
3858
        self.SetCurrentPos(0)
 
3859
        self.SetIndent(4)
 
3860
        self.SetBackSpaceUnIndents(True)
 
3861
        self.SetTabIndents(True)
 
3862
        self.SetTabWidth(4)
 
3863
        self.SetUseTabs(False)
 
3864
        self.SetEOLMode(wx.stc.STC_EOL_LF)
 
3865
        self.SetPasteConvertEndings(True)
 
3866
        self.SetControlCharSymbol(32)
 
3867
        self.SetLayoutCache(True)
 
3868
 
 
3869
        self.SetViewWhiteSpace(0)
 
3870
        self.SetViewEOL(0)
 
3871
        self.SetEdgeMode(0)
 
3872
        self.SetWrapMode(stc.STC_WRAP_WORD)
 
3873
 
 
3874
        self.SetUseAntiAliasing(True)
 
3875
        self.SetEdgeColour(STYLES["lineedge"]['colour'])
 
3876
        self.SetEdgeColumn(78)
 
3877
        self.SetReadOnly(True)
 
3878
        self.setStyle()
 
3879
 
 
3880
    def setStyle(self):
 
3881
        def buildStyle(forekey, backkey=None, smallsize=False):
 
3882
            if smallsize:
 
3883
                st = "face:%s,fore:%s,size:%s" % (STYLES['face'], STYLES[forekey]['colour'], STYLES['size2'])
 
3884
            else:
 
3885
                st = "face:%s,fore:%s,size:%s" % (STYLES['face'], STYLES[forekey]['colour'], STYLES['size'])
 
3886
            if backkey:
 
3887
                st += ",back:%s" % STYLES[backkey]['colour']
 
3888
            if STYLES[forekey].has_key('bold'):
 
3889
                if STYLES[forekey]['bold']:
 
3890
                    st += ",bold"
 
3891
                if STYLES[forekey]['italic']:
 
3892
                    st += ",italic"
 
3893
                if STYLES[forekey]['underline']:
 
3894
                    st += ",underline"
 
3895
            return st
 
3896
        self.StyleSetSpec(stc.STC_STYLE_DEFAULT, buildStyle('default', 'background'))
 
3897
        self.StyleClearAll()  # Reset all to be like the default
 
3898
 
 
3899
        self.StyleSetSpec(stc.STC_STYLE_DEFAULT, buildStyle('default', 'background'))
 
3900
        self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, buildStyle('linenumber', 'marginback', True))
 
3901
        self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, buildStyle('default') + ",size:5")
 
3902
        self.SetEdgeColour(STYLES["lineedge"]['colour'])
 
3903
        self.SetCaretForeground(STYLES['caret']['colour'])
 
3904
        self.SetSelBackground(1, STYLES['selback']['colour'])
 
3905
        self.SetFoldMarginColour(True, STYLES['foldmarginback']['colour'])
 
3906
        self.SetFoldMarginHiColour(True, STYLES['foldmarginback']['colour'])
 
3907
 
 
3908
class OutputLogEditor(SimpleEditor):
 
3909
    def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style= wx.NO_BORDER):
 
3910
        SimpleEditor.__init__(self, parent=parent, ID=ID, pos=pos, size=size, style=style)
 
3911
 
 
3912
    def setLog(self, text):
 
3913
        self.SetReadOnly(False)
 
3914
        self.SetText(text)
 
3915
        self.SetReadOnly(True)
 
3916
 
 
3917
class OutputLogPanel(wx.Panel):
 
3918
    def __init__(self, parent, mainPanel, size=(175,400)):
 
3919
        wx.Panel.__init__(self, parent, wx.ID_ANY, size=size, style=wx.SUNKEN_BORDER)
 
3920
        self.mainPanel = mainPanel
 
3921
 
 
3922
        self.running = 0
 
3923
        tsize = (30, 30)
 
3924
        close_panel_bmp = catalog['close_panel_icon.png'].GetBitmap()
 
3925
 
 
3926
        self.sizer = wx.BoxSizer(wx.VERTICAL)
 
3927
 
 
3928
        toolbarbox = wx.BoxSizer(wx.HORIZONTAL)
 
3929
        self.toolbar = wx.ToolBar(self, -1, size=(-1,36))
 
3930
        self.toolbar.SetMargins((5, 0))
 
3931
        font, psize = self.toolbar.GetFont(), self.toolbar.GetFont().GetPointSize()
 
3932
        if PLATFORM == "darwin":
 
3933
            font.SetPointSize(psize-1)
 
3934
        self.toolbar.SetToolBitmapSize(tsize)
 
3935
        
 
3936
        if PLATFORM == "win32":
 
3937
            self.toolbar.AddSeparator()
 
3938
        title = wx.StaticText(self.toolbar, -1, "Output panel")
 
3939
        title.SetFont(font)
 
3940
        self.toolbar.AddControl(title)
 
3941
        self.toolbar.AddSeparator()
 
3942
        if PLATFORM == "win32":
 
3943
            self.toolbar.AddSeparator()
 
3944
        self.processPopup = wx.Choice(self.toolbar, -1, choices=[])
 
3945
        self.processPopup.SetFont(font)
 
3946
        self.toolbar.AddControl(self.processPopup)
 
3947
        if PLATFORM == "win32":
 
3948
            self.toolbar.AddSeparator()
 
3949
        self.processKill = wx.Button(self.toolbar, -1, label="Kill", size=(40,-1))
 
3950
        self.processKill.SetFont(font)        
 
3951
        self.toolbar.AddControl(self.processKill)
 
3952
        self.processKill.Bind(wx.EVT_BUTTON, self.killProcess)
 
3953
        if PLATFORM == "win32":
 
3954
            self.toolbar.AddSeparator()
 
3955
        self.runningLabel = wx.StaticText(self.toolbar, -1, "Running: 0")
 
3956
        self.runningLabel.SetFont(font)
 
3957
        self.toolbar.AddControl(self.runningLabel)
 
3958
        self.toolbar.AddSeparator()
 
3959
        self.copyLog = wx.Button(self.toolbar, -1, label="Copy log", size=(70,-1))
 
3960
        self.copyLog.SetFont(font)
 
3961
        self.toolbar.AddControl(self.copyLog)
 
3962
        self.copyLog.Bind(wx.EVT_BUTTON, self.onCopy)
 
3963
        self.toolbar.AddSeparator()
 
3964
        zoomLabel = wx.StaticText(self.toolbar, -1, "Zoom:")
 
3965
        zoomLabel.SetFont(font)
 
3966
        self.toolbar.AddControl(zoomLabel)
 
3967
        if PLATFORM == "win32":
 
3968
            self.toolbar.AddSeparator()
 
3969
        self.zoomer = wx.SpinCtrl(self.toolbar, -1, "0", size=(60, -1))
 
3970
        self.zoomer.SetRange(-10,10)
 
3971
        self.toolbar.AddControl(self.zoomer)
 
3972
        self.zoomer.Bind(wx.EVT_SPINCTRL, self.onZoom)
 
3973
        self.toolbar.Realize()
 
3974
        toolbarbox.Add(self.toolbar, 1, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 0)
 
3975
 
 
3976
        tb2 = wx.ToolBar(self, -1, size=(-1,36))
 
3977
        tb2.SetToolBitmapSize(tsize)
 
3978
        tb2.AddLabelTool(17, "Close Panel", close_panel_bmp, shortHelp="Close Panel")
 
3979
        tb2.Realize()
 
3980
        toolbarbox.Add(tb2, 0, wx.ALIGN_RIGHT, 0)
 
3981
 
 
3982
        wx.EVT_TOOL(self, 17, self.onCloseOutputPanel)
 
3983
 
 
3984
        self.sizer.Add(toolbarbox, 0, wx.EXPAND)
 
3985
 
 
3986
        self.editor = OutputLogEditor(self, size=(-1, -1))
 
3987
        self.sizer.Add(self.editor, 1, wx.EXPAND|wx.ALL, 0)
 
3988
 
 
3989
        self.SetSizer(self.sizer)
 
3990
 
 
3991
    def onZoom(self, evt):
 
3992
        self.editor.SetZoom(self.zoomer.GetValue())
 
3993
 
 
3994
    def onCopy(self, evt):
 
3995
        self.editor.SelectAll()
 
3996
        self.editor.Copy()
 
3997
        self.editor.SetAnchor(0)
 
3998
 
 
3999
    def addProcess(self, procID, filename):
 
4000
        self.processPopup.Append("%d :: %s" % (procID, filename))
 
4001
        self.processPopup.SetStringSelection("%d :: %s" % (procID, filename))
 
4002
        self.running += 1
 
4003
        self.runningLabel.SetLabel("Running: %d" % self.running)
 
4004
 
 
4005
    def removeProcess(self, procID, filename):
 
4006
        str = "%d :: %s" % (procID, filename)
 
4007
        del self.mainPanel.mainFrame.processes[procID]
 
4008
        self.processPopup.Delete(self.processPopup.GetItems().index(str))
 
4009
        self.running -= 1
 
4010
        self.runningLabel.SetLabel("Running: %d" % self.running)
 
4011
 
 
4012
    def killProcess(self, evt):
 
4013
        str = self.processPopup.GetStringSelection()
 
4014
        if str != "":
 
4015
            procID = int(str.split("::")[0].strip())
 
4016
            thread = self.mainPanel.mainFrame.processes[procID][0]
 
4017
            thread.kill()
 
4018
 
 
4019
    def setLog(self, text):
 
4020
        self.editor.setLog(text)
 
4021
 
 
4022
    def onCloseOutputPanel(self, evt):
 
4023
        self.mainPanel.mainFrame.showOutputPanel(False)
 
4024
 
 
4025
class PastingListEditorFrame(wx.Frame):
 
4026
    def __init__(self, parent, pastingList):
 
4027
        wx.Frame.__init__(self, parent, wx.ID_ANY, title="Pasting List Editor ", size=(700,500))
 
4028
        self.parent = parent
 
4029
        self.menuBar = wx.MenuBar()
 
4030
        menu1 = wx.Menu()
 
4031
        menu1.Append(351, "Close\tCtrl+W")
 
4032
        self.menuBar.Append(menu1, 'File')
 
4033
        self.SetMenuBar(self.menuBar)
 
4034
 
 
4035
        self.Bind(wx.EVT_MENU, self.close, id=351)
 
4036
        self.Bind(wx.EVT_CLOSE, self.close)
 
4037
 
 
4038
        mainSizer = wx.BoxSizer(wx.VERTICAL)
 
4039
        panel = scrolled.ScrolledPanel(self)
 
4040
        self.editors = []
 
4041
        if PLATFORM == "darwin":
 
4042
            heightSum = 22
 
4043
        else:
 
4044
            heightSum = 50
 
4045
        if pastingList != []:
 
4046
            for line in pastingList:
 
4047
                editor = SimpleEditor(panel, style=wx.SUNKEN_BORDER)
 
4048
                editor.SetReadOnly(False)
 
4049
                height = editor.TextHeight(0) * len(line.splitlines()) + editor.TextHeight(0) * 2
 
4050
                heightSum += height
 
4051
                editor.SetMinSize((-1, height))
 
4052
                editor.SetMaxSize((-1, height))
 
4053
                mainSizer.Add(editor, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 0)
 
4054
                self.editors.append(editor)
 
4055
                if not line.endswith("\n"):
 
4056
                    line = line + "\n"
 
4057
                try:
 
4058
                    editor.AddTextUTF8(line)
 
4059
                except:
 
4060
                    editor.AddText(line)
 
4061
 
 
4062
        Y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
 
4063
        if heightSum > Y - 100:
 
4064
            self.SetSize((-1, Y - 100))
 
4065
        else:
 
4066
            self.SetSize((-1, heightSum))
 
4067
        panel.SetSizer(mainSizer)
 
4068
        panel.SetAutoLayout(1)
 
4069
        panel.SetupScrolling()
 
4070
 
 
4071
    def close(self, evt):
 
4072
        pastingList = []
 
4073
        for editor in self.editors:
 
4074
            text = editor.GetTextUTF8()
 
4075
            if text.replace("\n", "").strip() != "":
 
4076
                pastingList.append(text)
 
4077
        self.parent.pastingList = pastingList
 
4078
        self.Destroy()
 
4079
 
3769
4080
TOOL_ADD_FILE_ID = 10
3770
4081
TOOL_ADD_FOLDER_ID = 11
3771
4082
class ProjectTree(wx.Panel):
4182
4493
        ctrlSizer = wx.BoxSizer(wx.HORIZONTAL)
4183
4494
        self.entry_exe = wx.TextCtrl(self, size=(500,-1), value=WHICH_PYTHON)
4184
4495
        self.entry_exe.SetFont(entryfont)
 
4496
        if PLATFORM == "win32":
 
4497
            self.entry_exe.SetEditable(False)
4185
4498
        ctrlSizer.Add(self.entry_exe, 0, wx.ALL|wx.EXPAND, 5)
4186
4499
        but = wx.Button(self, id=wx.ID_ANY, label="Choose...")
4187
4500
        but.Bind(wx.EVT_BUTTON, self.setExecutable)
4189
4502
        but2 = wx.Button(self, id=wx.ID_ANY, label="Revert")
4190
4503
        but2.Bind(wx.EVT_BUTTON, self.revertExecutable)
4191
4504
        ctrlSizer.Add(but2, 0, wx.ALL, 5)
 
4505
        if PLATFORM == "win32":
 
4506
            but.Disable()
 
4507
            but2.Disable()
4192
4508
        mainSizer.Add(ctrlSizer, 0, wx.BOTTOM|wx.LEFT|wx.RIGHT, 5)
4193
4509
 
4194
4510
        lbl = wx.StaticText(self, label="Resources Folder:")
4806
5122
 
4807
5123
    app = wx.PySimpleApp()
4808
5124
    X,Y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X), wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
4809
 
    if X < 800: X -= 50
4810
 
    else: X = 800
4811
 
    if Y < 700: Y -= 50
4812
 
    else: Y = 700
 
5125
    if X < 850: X -= 50
 
5126
    else: X = 850
 
5127
    if Y < 750: Y -= 50
 
5128
    else: Y = 750
4813
5129
    frame = MainFrame(None, -1, title='E-Pyo Editor', pos=(10,25), size=(X, Y))
4814
5130
    frame.Show()
4815
5131
    app.MainLoop()