Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeWidgets/Data/OWPythonScript.py

    r11216 r11330  
    33<description>Executes python script.</description> 
    44<icon>icons/PythonScript.svg</icon> 
    5 <contact>Miha Stajdohar (miha.stajdohar(@at@)gmail.com)</contact>  
     5<contact>Miha Stajdohar (miha.stajdohar(@at@)gmail.com)</contact> 
    66<priority>3150</priority> 
    77""" 
     8import sys 
     9import os 
     10import code 
     11import keyword 
     12 
     13from PyQt4.QtGui import ( 
     14    QSyntaxHighlighter, QPlainTextEdit, QTextCharFormat, QTextCursor, 
     15    QTextDocument, QPlainTextDocumentLayout, QBrush, QFont, QColor, QPalette, 
     16    QStyledItemDelegate, QStyleOptionViewItemV4, QLineEdit, QListView, 
     17    QSizePolicy, QAction, QMenu, QKeySequence, QSplitter, QToolButton, 
     18    QItemSelectionModel, QFileDialog 
     19) 
     20 
     21from PyQt4.QtCore import Qt, QRegExp, QByteArray 
     22from PyQt4.QtCore import SIGNAL 
     23 
    824from OWWidget import * 
    925 
    10 import sys, traceback 
     26from OWItemModels import PyListModel, ModelActionsWidget 
     27 
    1128import OWGUI 
    1229import Orange 
    13  
    14 import code 
    1530 
    1631 
     
    2944        self.decoratorFormat = QTextCharFormat() 
    3045        self.decoratorFormat.setForeground(QBrush(Qt.darkGray)) 
    31          
    32         self.keywords = ["def", "if", "else", "elif", "for", "while", "with", "try", "except", 
    33                          "finally", "not", "in", "lambda", "None", "import", "class", "return", "print", 
    34                          "yield", "break", "continue", "raise", "or", "and", "True", "False", "pass", 
    35                          "from", "as"] 
    36         self.rules = [(QRegExp(r"\b%s\b" % keyword), self.keywordFormat) for keyword in self.keywords] + \ 
    37                      [(QRegExp(r"\bdef\s+([A-Za-z_]+[A-Za-z0-9_]+)\s*\("), self.defFormat), 
    38                       (QRegExp(r"\bclass\s+([A-Za-z_]+[A-Za-z0-9_]+)\s*\("), self.defFormat), 
     46 
     47        self.keywords = list(keyword.kwlist) 
     48 
     49        self.rules = [(QRegExp(r"\b%s\b" % kwd), self.keywordFormat) 
     50                      for kwd in self.keywords] + \ 
     51                     [(QRegExp(r"\bdef\s+([A-Za-z_]+[A-Za-z0-9_]+)\s*\("), 
     52                       self.defFormat), 
     53                      (QRegExp(r"\bclass\s+([A-Za-z_]+[A-Za-z0-9_]+)\s*\("), 
     54                       self.defFormat), 
    3955                      (QRegExp(r"'.*'"), self.stringFormat), 
    4056                      (QRegExp(r'".*"'), self.stringFormat), 
    4157                      (QRegExp(r"#.*"), self.commentFormat), 
    42                       (QRegExp(r"@[A-Za-z_]+[A-Za-z0-9_]+"), self.decoratorFormat)] 
    43                       
     58                      (QRegExp(r"@[A-Za-z_]+[A-Za-z0-9_]+"), 
     59                       self.decoratorFormat)] 
     60 
     61        self.multilineStart = QRegExp(r"(''')|" + r'(""")') 
     62        self.multilineEnd = QRegExp(r"(''')|" + r'(""")') 
     63 
    4464        QSyntaxHighlighter.__init__(self, parent) 
    45          
     65 
    4666    def highlightBlock(self, text): 
    4767        for pattern, format in self.rules: 
     
    5575                    self.setFormat(exp.pos(0), len(str(exp.cap(0))), format) 
    5676                index = exp.indexIn(text, index + length) 
    57                  
    58         ## Multi line strings 
    59         start = QRegExp(r"(''')|" + r'(""")') 
    60         end = QRegExp(r"(''')|" + r'(""")') 
     77 
     78        # Multi line strings 
     79        start = self.multilineStart 
     80        end = self.multilineEnd 
     81 
    6182        self.setCurrentBlockState(0) 
    6283        startIndex, skip = 0, 0 
     
    7192                commentLen = endIndex - startIndex + 3 
    7293            self.setFormat(startIndex, commentLen, self.stringFormat) 
    73             startIndex, skip = start.indexIn(text, startIndex + commentLen + 3), 3 
    74                  
     94            startIndex, skip = (start.indexIn(text, 
     95                                              startIndex + commentLen + 3), 
     96                                3) 
     97 
     98 
    7599class PythonScriptEditor(QPlainTextEdit): 
    76100    INDENT = 4 
     101 
    77102    def lastLine(self): 
    78103        text = str(self.toPlainText()) 
     
    81106        text = text[index: pos].lstrip("\n") 
    82107        return text 
    83      
     108 
    84109    def keyPressEvent(self, event): 
    85110        if event.key() == Qt.Key_Return: 
    86111            text = self.lastLine() 
    87112            indent = len(text) - len(text.lstrip()) 
    88             if text.strip() == "pass" or text.strip().startswith("return"): 
     113            if text.strip() == "pass" or text.strip().startswith("return "): 
    89114                indent = max(0, indent - self.INDENT) 
    90115            elif text.strip().endswith(":"): 
     
    102127            else: 
    103128                QPlainTextEdit.keyPressEvent(self, event) 
    104                  
     129 
    105130        else: 
    106131            QPlainTextEdit.keyPressEvent(self, event) 
    107          
     132 
     133 
    108134class PythonConsole(QPlainTextEdit, code.InteractiveConsole): 
    109     def __init__(self, locals = None, parent=None): 
     135    def __init__(self, locals=None, parent=None): 
    110136        QPlainTextEdit.__init__(self, parent) 
    111137        code.InteractiveConsole.__init__(self, locals) 
     
    113139        self.loop = self.interact() 
    114140        self.loop.next() 
    115          
     141 
    116142    def setLocals(self, locals): 
    117143        self.locals = locals 
    118          
     144 
    119145    def interact(self, banner=None): 
    120146        try: 
     
    126152        except AttributeError: 
    127153            sys.ps2 = "... " 
    128         cprt = 'Type "help", "copyright", "credits" or "license" for more information.' 
     154        cprt = ('Type "help", "copyright", "credits" or "license" ' 
     155                'for more information.') 
    129156        if banner is None: 
    130157            self.write("Python %s on %s\n%s\n(%s)\n" % 
     
    153180                self.resetbuffer() 
    154181                more = 0 
    155                  
     182 
    156183    def raw_input(self, prompt): 
    157184        input = str(self.document().lastBlock().previous().text()) 
    158185        return input[len(prompt):] 
    159          
     186 
    160187    def new_prompt(self, prompt): 
    161188        self.write(prompt) 
    162189        self.newPromptPos = self.textCursor().position() 
    163          
     190 
    164191    def write(self, data): 
    165192        cursor = QTextCursor(self.document()) 
     
    168195        self.setTextCursor(cursor) 
    169196        self.ensureCursorVisible() 
    170          
     197 
    171198    def push(self, line): 
    172199        if self.history[0] != line: 
    173200            self.history.insert(0, line) 
    174201        self.historyInd = 0 
    175         more = 0 
     202 
    176203        saved = sys.stdout, sys.stderr 
    177204        try: 
     
    180207        finally: 
    181208            sys.stdout, sys.stderr = saved 
    182              
     209 
    183210    def setLine(self, line): 
    184211        cursor = QTextCursor(self.document()) 
     
    188215        cursor.insertText(line) 
    189216        self.setTextCursor(cursor) 
    190          
     217 
    191218    def keyPressEvent(self, event): 
    192219        if event.key() == Qt.Key_Return: 
     
    204231        else: 
    205232            QPlainTextEdit.keyPressEvent(self, event) 
    206              
     233 
    207234    def historyUp(self): 
    208235        self.setLine(self.history[self.historyInd]) 
    209236        self.historyInd = min(self.historyInd + 1, len(self.history) - 1) 
    210          
     237 
    211238    def historyDown(self): 
    212239        self.setLine(self.history[self.historyInd]) 
    213240        self.historyInd = max(self.historyInd - 1, 0) 
    214          
     241 
    215242    def complete(self): 
    216243        pass 
    217      
    218 from OWItemModels import PyListModel, ModelActionsWidget 
     244 
    219245 
    220246class Script(object): 
    221247    Modified = 1 
    222     MissingFromFilesystem = 2  
     248    MissingFromFilesystem = 2 
     249 
    223250    def __init__(self, name, script, flags=0, sourceFileName=None): 
    224251        self.name = name 
     
    228255        self.modifiedScript = None 
    229256 
     257 
    230258class ScriptItemDelegate(QStyledItemDelegate): 
    231259    def __init__(self, parent): 
    232260        QStyledItemDelegate.__init__(self, parent) 
    233          
     261 
    234262    def displayText(self, variant, locale): 
    235263        script = variant.toPyObject() 
     
    238266        else: 
    239267            return QString(script.name) 
    240      
     268 
    241269    def paint(self, painter, option, index): 
    242270        script = index.data(Qt.DisplayRole).toPyObject() 
    243         tmp_palette = None 
     271 
    244272        if script.flags & Script.Modified: 
    245273            option = QStyleOptionViewItemV4(option) 
     
    248276        QStyledItemDelegate.paint(self, painter, option, index) 
    249277 
    250          
    251278    def createEditor(self, parent, option, index): 
    252279        return QLineEdit(parent) 
    253      
     280 
    254281    def setEditorData(self, editor, index): 
    255282        script = index.data(Qt.DisplayRole).toPyObject() 
    256283        editor.setText(script.name) 
    257          
     284 
    258285    def setModelData(self, editor, model, index): 
    259286        model[index.row()].name = str(editor.text()) 
    260          
     287 
     288 
    261289class OWPythonScript(OWWidget): 
    262      
    263     settingsList = ["codeFile", "libraryListSource", "currentScriptIndex", "splitterState"] 
    264                      
     290 
     291    settingsList = ["codeFile", "libraryListSource", "currentScriptIndex", 
     292                    "splitterState"] 
     293 
    265294    def __init__(self, parent=None, signalManager=None): 
    266295        OWWidget.__init__(self, parent, signalManager, 'Python Script') 
    267          
    268         self.inputs = [("in_data", ExampleTable, self.setExampleTable), ("in_distance", orange.SymMatrix, self.setDistanceMatrix), ("in_learner", orange.Learner, self.setLearner), ("in_classifier", orange.Classifier, self.setClassifier)] 
    269         self.outputs = [("out_data", ExampleTable), ("out_distance", orange.SymMatrix), ("out_learner", orange.Learner), ("out_classifier", orange.Classifier, Dynamic)] 
    270  
    271         try: 
    272             self.inputs.append(("in_network", Orange.network.Graph, self.setNetwork)) 
    273             self.outputs.append(("out_network", Orange.network.Graph)) 
    274         except: 
    275             pass 
     296 
     297        self.inputs = [("in_data", Orange.data.Table, self.setExampleTable), 
     298                       ("in_distance", Orange.misc.SymMatrix, 
     299                        self.setDistanceMatrix), 
     300                       ("in_learner", Orange.core.Learner, self.setLearner), 
     301                       ("in_classifier", Orange.core.Classifier, 
     302                        self.setClassifier), 
     303                       ("in_object", object, self.setObject)] 
     304 
     305        self.outputs = [("out_data", Orange.data.Table), 
     306                        ("out_distance", Orange.misc.SymMatrix), 
     307                        ("out_learner", Orange.core.Learner), 
     308                        ("out_classifier", Orange.core.Classifier, Dynamic), 
     309                        ("out_object", object, Dynamic)] 
    276310 
    277311        self.in_data = None 
    278         self.in_network = None 
    279312        self.in_distance = None 
    280313        self.in_learner = None 
    281314        self.in_classifier = None 
    282          
     315        self.in_object = None 
     316        self.auto_execute = False 
     317 
    283318        self.codeFile = '' 
    284         self.libraryListSource = [Script("Hello world", "print 'Hello world'\n")] 
     319        self.libraryListSource = [Script("Hello world", 
     320                                         "print 'Hello world'\n")] 
    285321        self.currentScriptIndex = 0 
    286322        self.splitterState = None 
    287323        self.loadSettings() 
    288          
     324 
    289325        for s in self.libraryListSource: 
    290326            s.flags = 0 
    291          
     327 
    292328        self._cachedDocuments = {} 
    293          
     329 
    294330        self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') 
    295         label = OWGUI.label(self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ 
    296                     "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + \ 
    297                     "<li>".join(t[0] for t in self.outputs) + "</ul></p>") 
    298         self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) 
    299 #        self.libraryList.append(Script("Hello world", "print 'Hello world'\n")) 
     331        OWGUI.label( 
     332            self.infoBox, self, 
     333            "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ 
     334            "<li>".join(t[0] for t in self.inputs) + \ 
     335            "</ul></p><p>Output variables:<ul><li>" + \ 
     336            "<li>".join(t[0] for t in self.outputs) + \ 
     337            "</ul></p>" 
     338        ) 
     339 
     340        self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | \ 
     341                                       Qt.ItemIsEnabled | Qt.ItemIsEditable) 
     342 
    300343        self.libraryList.wrap(self.libraryListSource) 
    301          
     344 
    302345        self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') 
    303346        self.controlBox.layout().setSpacing(1) 
     347 
    304348        self.libraryView = QListView() 
    305         self.libraryView.setEditTriggers(QListView.DoubleClicked | QListView.EditKeyPressed) 
    306         self.libraryView.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) 
     349        self.libraryView.setEditTriggers(QListView.DoubleClicked | \ 
     350                                         QListView.EditKeyPressed) 
     351        self.libraryView.setSizePolicy(QSizePolicy.Ignored, 
     352                                       QSizePolicy.Preferred) 
    307353        self.libraryView.setItemDelegate(ScriptItemDelegate(self)) 
    308354        self.libraryView.setModel(self.libraryList) 
    309         self.connect(self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onSelectedScriptChanged) 
     355 
     356        self.connect(self.libraryView.selectionModel(), 
     357                     SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), 
     358                     self.onSelectedScriptChanged) 
    310359        self.controlBox.layout().addWidget(self.libraryView) 
     360 
    311361        w = ModelActionsWidget() 
    312          
     362 
    313363        self.addNewScriptAction = action = QAction("+", self) 
    314         action.pyqtConfigure(toolTip="Add a new script to the library") 
     364        action.setToolTip("Add a new script to the library") 
    315365        self.connect(action, SIGNAL("triggered()"), self.onAddScript) 
    316         new_empty = QAction("Add a new empty script", action) 
    317         new_from_file = QAction("Add a new script from a file", action) 
    318         self.connect(new_empty, SIGNAL("triggered()"), self.onAddScript) 
    319         self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) 
    320         menu = QMenu(w) 
    321         menu.addAction(new_empty) 
    322         menu.addAction(new_from_file) 
    323          
    324 #        action.setMenu(menu) 
    325         button = w.addAction(action) 
    326          
     366        w.addAction(action) 
     367 
    327368        self.removeAction = action = QAction("-", self) 
    328         action.pyqtConfigure(toolTip="Remove script from library") 
     369        action.setToolTip("Remove script from library") 
    329370        self.connect(action, SIGNAL("triggered()"), self.onRemoveScript) 
    330371        w.addAction(action) 
    331          
     372 
    332373        action = QAction("Update", self) 
    333         action.pyqtConfigure(toolTip="Save changes in the editor to library") 
     374        action.setToolTip("Save changes in the editor to library") 
    334375        action.setShortcut(QKeySequence(QKeySequence.Save)) 
    335         self.connect(action, SIGNAL("triggered()"), self.commitChangesToLibrary) 
    336         b = w.addAction(action) 
    337 #        b.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) 
    338          
     376        self.connect(action, SIGNAL("triggered()"), 
     377                     self.commitChangesToLibrary) 
     378        w.addAction(action) 
     379 
    339380        action = QAction("More", self) 
    340         action.pyqtConfigure(toolTip="More actions") #, icon=self.style().standardIcon(QStyle.SP_ToolBarHorizontalExtensionButton)) 
    341          
    342         self.openScriptFromFileAction = new_from_file = QAction("Import a script from a file", self) 
    343         self.saveScriptToFile = save_to_file = QAction("Save selected script to a file", self) 
     381        action.pyqtConfigure(toolTip="More actions") 
     382 
     383        new_from_file = QAction("Import a script from a file", self) 
     384        save_to_file = QAction("Save selected script to a file", self) 
    344385        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) 
    345          
    346         self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) 
     386 
     387        self.connect(new_from_file, SIGNAL("triggered()"), 
     388                     self.onAddScriptFromFile) 
    347389        self.connect(save_to_file, SIGNAL("triggered()"), self.saveScript) 
    348          
     390 
    349391        menu = QMenu(w) 
    350392        menu.addAction(new_from_file) 
    351393        menu.addAction(save_to_file) 
    352394        action.setMenu(menu) 
    353         b = w.addAction(action) 
    354         b.setPopupMode(QToolButton.InstantPopup)  
    355         ## TODO: set the space for the indicator 
    356          
     395        button = w.addAction(action) 
     396        button.setPopupMode(QToolButton.InstantPopup) 
     397 
    357398        w.layout().setSpacing(1) 
    358          
     399 
    359400        self.controlBox.layout().addWidget(w) 
    360                      
    361 #        OWGUI.button(self.controlBox, self, "Open...", callback=self.openScript) 
    362 #        OWGUI.button(self.controlBox, self, "Save...", callback=self.saveScript) 
    363          
     401 
    364402        self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') 
    365403        OWGUI.button(self.runBox, self, "Execute", callback=self.execute) 
    366          
     404        OWGUI.checkBox(self.runBox, self, "auto_execute", "Auto execute", 
     405                       tooltip=("Run the script automatically whenever " 
     406                                "the inputs to the widget change.")) 
     407 
    367408        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) 
    368409        self.mainArea.layout().addWidget(self.splitCanvas) 
    369          
    370         self.defaultFont = defaultFont = "Monaco" if sys.platform == "darwin" else "Courier" 
     410 
     411        self.defaultFont = defaultFont = \ 
     412            "Monaco" if sys.platform == "darwin" else "Courier" 
     413 
    371414        self.textBox = OWGUI.widgetBox(self, 'Python script') 
    372415        self.splitCanvas.addWidget(self.textBox) 
    373416        self.text = PythonScriptEditor(self) 
    374417        self.textBox.layout().addWidget(self.text) 
    375          
     418 
    376419        self.textBox.setAlignment(Qt.AlignVCenter) 
    377420        self.text.setTabStopWidth(4) 
    378          
    379         self.connect(self.text, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) 
    380          
     421 
     422        self.connect(self.text, SIGNAL("modificationChanged(bool)"), 
     423                     self.onModificationChanged) 
     424 
    381425        self.saveAction = action = QAction("&Save", self.text) 
    382         action.pyqtConfigure(toolTip="Save script to file") 
     426        action.setToolTip("Save script to file") 
    383427        action.setShortcut(QKeySequence(QKeySequence.Save)) 
    384428        action.setShortcutContext(Qt.WidgetWithChildrenShortcut) 
    385429        self.connect(action, SIGNAL("triggered()"), self.saveScript) 
    386          
     430 
    387431        self.consoleBox = OWGUI.widgetBox(self, 'Console') 
    388432        self.splitCanvas.addWidget(self.consoleBox) 
     
    392436        self.consoleBox.setAlignment(Qt.AlignBottom) 
    393437        self.console.setTabStopWidth(4) 
    394          
     438 
    395439        self.openScript(self.codeFile) 
    396440        try: 
    397             self.libraryView.selectionModel().select(self.libraryList.index(self.currentScriptIndex), QItemSelectionModel.ClearAndSelect) 
     441            self.libraryView.selectionModel().select( 
     442                self.libraryList.index(self.currentScriptIndex), 
     443                QItemSelectionModel.ClearAndSelect 
     444            ) 
    398445        except Exception: 
    399446            pass 
     447 
    400448        self.splitCanvas.setSizes([2, 1]) 
    401449        if self.splitterState is not None: 
    402450            self.splitCanvas.restoreState(QByteArray(self.splitterState)) 
    403          
    404         self.connect(self.splitCanvas, SIGNAL("splitterMoved(int, int)"), lambda pos, ind: setattr(self, "splitterState", str(self.splitCanvas.saveState()))) 
     451 
     452        self.connect(self.splitCanvas, SIGNAL("splitterMoved(int, int)"), 
     453                     self.onSpliterMoved) 
    405454        self.controlArea.layout().addStretch(1) 
    406         self.resize(800,600) 
    407          
     455        self.resize(800, 600) 
     456 
    408457    def setExampleTable(self, et): 
    409458        self.in_data = et 
    410          
     459 
    411460    def setDistanceMatrix(self, dm): 
    412461        self.in_distance = dm 
    413          
    414     def setNetwork(self, net): 
    415         self.in_network = net 
    416          
     462 
    417463    def setLearner(self, learner): 
    418464        self.in_learner = learner 
    419          
     465 
    420466    def setClassifier(self, classifier): 
    421467        self.in_classifier = classifier 
    422          
     468 
     469    def setObject(self, obj): 
     470        self.in_object = obj 
     471 
     472    def handleNewSignals(self): 
     473        if self.auto_execute: 
     474            self.execute() 
     475 
    423476    def selectedScriptIndex(self): 
    424477        rows = self.libraryView.selectionModel().selectedRows() 
     
    427480        else: 
    428481            return None 
    429          
     482 
    430483    def setSelectedScript(self, index): 
    431484        selection = self.libraryView.selectionModel() 
    432         selection.select(self.libraryList.index(index), QItemSelectionModel.ClearAndSelect) 
    433          
     485        selection.select(self.libraryList.index(index), 
     486                         QItemSelectionModel.ClearAndSelect) 
     487 
    434488    def onAddScript(self, *args): 
    435489        self.libraryList.append(Script("New script", "", 0)) 
    436490        self.setSelectedScript(len(self.libraryList) - 1) 
    437          
     491 
    438492    def onAddScriptFromFile(self, *args): 
    439         file = QFileDialog.getOpenFileName(self, 'Open Python Script', self.codeFile, 'Python files (*.py)\nAll files(*.*)') 
    440         file = unicode(file) 
    441         if file: 
    442             name = os.path.basename(file) 
    443             self.libraryList.append(Script(name, open(file, "rb").read(), 0, file)) 
     493        filename = QFileDialog.getOpenFileName( 
     494            self, 'Open Python Script', 
     495            self.codeFile, 
     496            'Python files (*.py)\nAll files(*.*)' 
     497        ) 
     498 
     499        filename = unicode(filename) 
     500        if filename: 
     501            name = os.path.basename(filename) 
     502            self.libraryList.append(Script(name, open(filename, "rb").read(), 
     503                                           0, filename)) 
    444504            self.setSelectedScript(len(self.libraryList) - 1) 
    445      
     505 
    446506    def onRemoveScript(self, *args): 
    447507        index = self.selectedScriptIndex() 
    448508        if index is not None: 
    449509            del self.libraryList[index] 
    450             self.libraryView.selectionModel().select(self.libraryList.index(max(index - 1, 0)), QItemSelectionModel.ClearAndSelect) 
    451      
     510 
     511            self.libraryView.selectionModel().select( 
     512                self.libraryList.index(max(index - 1, 0)), 
     513                QItemSelectionModel.ClearAndSelect 
     514            ) 
     515 
    452516    def onSaveScriptToFile(self, *args): 
    453517        index = self.selectedScriptIndex() 
    454518        if index is not None: 
    455519            self.saveScript() 
    456              
     520 
    457521    def onSelectedScriptChanged(self, selected, deselected): 
    458522        index = [i.row() for i in selected.indexes()] 
    459523        if index: 
    460             current = index[0]  
     524            current = index[0] 
    461525            if current >= len(self.libraryList): 
    462526                self.addNewScriptAction.trigger() 
    463527                return 
     528 
    464529            self.text.setDocument(self.documentForScript(current)) 
    465530            self.currentScriptIndex = current 
    466              
     531 
    467532    def documentForScript(self, script=0): 
    468533        if type(script) != Script: 
    469534            script = self.libraryList[script] 
     535 
    470536        if script not in self._cachedDocuments: 
    471537            doc = QTextDocument(self) 
     
    474540            doc.setDefaultFont(QFont(self.defaultFont)) 
    475541            doc.highlighter = PythonSyntaxHighlighter(doc) 
    476             self.connect(doc, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) 
     542            self.connect(doc, SIGNAL("modificationChanged(bool)"), 
     543                         self.onModificationChanged) 
    477544            doc.setModified(False) 
    478545            self._cachedDocuments[script] = doc 
    479546        return self._cachedDocuments[script] 
    480      
     547 
    481548    def commitChangesToLibrary(self, *args): 
    482549        index = self.selectedScriptIndex() 
     
    485552            self.text.document().setModified(False) 
    486553            self.libraryList.emitDataChanged(index) 
    487              
     554 
    488555    def onModificationChanged(self, modified): 
    489556        index = self.selectedScriptIndex() 
     
    491558            self.libraryList[index].flags = Script.Modified if modified else 0 
    492559            self.libraryList.emitDataChanged(index) 
    493          
     560 
     561    def onSpliterMoved(self, pos, ind): 
     562        self.splitterState = str(self.splitCanvas.saveState()) 
     563 
    494564    def updateSelecetdScriptState(self): 
    495565        index = self.selectedScriptIndex() 
    496566        if index is not None: 
    497567            script = self.libraryList[index] 
    498             self.libraryList[index] = Script(script.name, self.text.toPlainText(), 0) 
    499              
     568            self.libraryList[index] = Script(script.name, 
     569                                             self.text.toPlainText(), 
     570                                             0) 
     571 
    500572    def openScript(self, filename=None): 
    501573        if filename == None: 
    502             filename = unicode(QFileDialog.getOpenFileName(self, 'Open Python Script', 
    503                                self.codeFile, 'Python files (*.py)\nAll files(*.*)')) 
     574            filename = QFileDialog.getOpenFileName( 
     575                self, 'Open Python Script', 
     576                self.codeFile, 
     577                'Python files (*.py)\nAll files(*.*)' 
     578            ) 
     579 
     580            filename = unicode(filename) 
    504581            self.codeFile = filename 
    505582        else: 
    506583            self.codeFile = filename 
    507              
     584 
    508585        if self.codeFile == "": 
    509586            return 
    510              
     587 
    511588        self.error(0) 
    512589        try: 
     
    515592            self.text.setPlainText("") 
    516593            return 
    517          
     594 
    518595        self.text.setPlainText(f.read()) 
    519596        f.close() 
    520      
     597 
    521598    def saveScript(self): 
    522599        index = self.selectedScriptIndex() 
     
    526603        else: 
    527604            filename = self.codeFile 
    528         filename = QFileDialog.getSaveFileName(self, 'Save Python Script', 
    529                             filename, 'Python files (*.py)\nAll files(*.*)')  
     605        filename = QFileDialog.getSaveFileName( 
     606            self, 'Save Python Script', 
     607            filename, 
     608            'Python files (*.py)\nAll files(*.*)' 
     609        ) 
     610 
    530611        self.codeFile = unicode(filename) 
    531          
     612 
    532613        if self.codeFile: 
    533614            fn = "" 
     
    537618            else: 
    538619                fn = self.codeFile 
    539              
     620 
    540621            f = open(fn, 'w') 
    541622            f.write(self.text.toPlainText()) 
    542623            f.close() 
    543              
     624 
    544625    def execute(self): 
    545626        self._script = str(self.text.toPlainText()) 
     
    551632            self.send(signal, getattr(self, signal, None)) 
    552633 
    553 if __name__=="__main__":     
     634 
     635if __name__ == "__main__": 
    554636    appl = QApplication(sys.argv) 
    555637    ow = OWPythonScript() 
Note: See TracChangeset for help on using the changeset viewer.