Ejemplo n.º 1
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setLayout(QVBoxLayout())
        
        self.layout().setSpacing(1)
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.view = QListView(self)
        self.view.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)
        self.layout().addWidget(self.view)
        
        self.addScriptAction = QAction("+", self)
        self.addScriptAction.pyqtConfigure(toolTip="Add a new script to library")
        
        self.updateScriptAction = QAction("Update", self)
        self.updateScriptAction.pyqtConfigure(toolTip="Save changes in the editor to library", shortcut=QKeySequence.Save)
        
        self.removeScriptAction = QAction("-", self)
        self.removeScriptAction.pyqtConfigure(toolTip="Remove selected script from file")
        
        self.moreAction = QAction("More", self)
        self.moreAction.pyqtConfigure(toolTip="More actions")#, icon=self.style().standardIcon(QStyle.SP_ToolBarHorizontalExtensionButton))
        
        self.addScriptFromFile = QAction("Add script from file", self)
        self.addScriptFromFile.pyqtConfigure(toolTip="Add a new script to library from a file")
        
        self.saveScriptToFile = QAction("Save script to file", self)
        self.saveScriptToFile.pyqtConfigure(toolTip="Save script to a file", shortcut=QKeySequence.SaveAs)
        
        menu = QMenu(self)
        menu.addActions([self.addScriptFromFile, self.saveScriptToFile])
        self.moreAction.setMenu(menu)
        
        self.actionsWidget = ModelActionsWidget([self.addScriptAction, self.updateScriptAction, 
                                            self.removeScriptAction, self.moreAction], self)
#        self.actionsWidget.buttons[1].setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        self.actionsWidget.layout().setSpacing(1)
        
        self.layout().addWidget(self.actionsWidget)
        
        self.resize(800, 600)
Ejemplo n.º 2
0
    def __init__(self, parent=None, signalManager=None, name="Data Generator"):
        OWWidget.__init__(self, parent, signalManager, name)

        self.outputs = [("Data", ExampleTable)]

        self.addClassAsMeta = False
        self.attributes = []
        self.cov = []
        self.commitOnChange = False

        self.loadSettings()

        self.variablesModel = VariableListModel(
            [Orange.feature.Continuous(name) for name in ["X", "Y"]], self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
        )

        self.classVariable = Orange.feature.Discrete(
            "Class label", values=["Class 1", "Class 2"], baseValue=0
        )

        w = OWGUI.widgetBox(self.controlArea, "Class Label")
        w.layout().setSpacing(1)

        self.classValuesView = listView = QListView(
            selectionMode=QListView.SingleSelection,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored,
                                   QSizePolicy.Maximum)
        )

        self.classValuesModel = EnumVariableModel(
            self.classVariable, self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
        )
        self.classValuesModel.wrap(self.classVariable.values)

        listView.setModel(self.classValuesModel)
        listView.selectionModel().select(self.classValuesModel.index(0),
                                         QItemSelectionModel.ClearAndSelect)
        listView.selectionModel().selectionChanged.connect(
            self.onClassLabelSelection
        )
        w.layout().addWidget(listView)

        self.addClassLabel = QAction(
            "+", self, toolTip="Add class label"
        )
        self.addClassLabel.triggered.connect(self.addNewClassLabel)

        self.removeClassLabel = QAction(
            unicodedata.lookup("MINUS SIGN"), self,
            toolTip="Remove selected class label"
        )
        self.removeClassLabel.triggered.connect(self.removeSelectedClassLabel)

        actionsWidget = ModelActionsWidget(
            [self.addClassLabel, self.removeClassLabel], self
        )
        actionsWidget.layout().addStretch(10)
        actionsWidget.layout().setSpacing(1)

        w.layout().addWidget(actionsWidget)

        toolbox = OWGUI.widgetBox(self.controlArea, "Tools",
                                  orientation=QGridLayout())
        self.toolActions = QActionGroup(self, exclusive=True)

        for i, (name, tooltip, tool, icon) in enumerate(self.TOOLS):
            action = QAction(name, self, toolTip=tooltip, checkable=True)
            if os.path.exists(icon):
                action.setIcon(QIcon(icon))

            action.triggered[()].connect(
                lambda tool=tool: self.onToolAction(tool)
            )

            button = QToolButton(
                iconSize=QSize(24, 24),
                toolButtonStyle=Qt.ToolButtonTextUnderIcon,
                sizePolicy=QSizePolicy(QSizePolicy.MinimumExpanding,
                                       QSizePolicy.Fixed)
            )
            button.setDefaultAction(action)
            toolbox.layout().addWidget(button, i / 3, i % 3)
            self.toolActions.addAction(action)

        # TODO: Columns should have uniform widths
        for column in range(3):
            toolbox.layout().setColumnMinimumWidth(column, 10)
            toolbox.layout().setColumnStretch(column, 1)

        self.optionsLayout = QStackedLayout()
        self.toolsStackCache = {}
        OWGUI.widgetBox(self.controlArea, "Options",
                        orientation=self.optionsLayout)

        ur = OWGUI.widgetBox(self.controlArea, "")
        undo = QAction("Undo", self, toolTip="Undo action",
                       shortcut=QKeySequence.Undo)
        undo.triggered.connect(self.undo)

        redo = QAction("Redo", self, toolTip="Redo action",
                       shortcut=QKeySequence.Redo)
        redo.triggered.connect(self.redo)

        actionsWidget = ModelActionsWidget([undo, redo], self)
        actionsWidget.layout().addStretch(10)
        actionsWidget.layout().setSpacing(1)

        ur.layout().addWidget(actionsWidget)

        OWGUI.rubber(self.controlArea)
        box = OWGUI.widgetBox(self.controlArea, "Commit")

        cb = OWGUI.checkBox(box, self, "commitOnChange", "Commit on change",
                            tooltip="Send the data on any change.",
                            callback=self.commitIf,)
        b = OWGUI.button(box, self, "Commit",
                         callback=self.commit, default=True)
        OWGUI.setStopper(self, b, cb, "dataChangedFlag", callback=self.commit)

        self.graph = PaintDataGraph(self)
        self.graph.setAxisScale(QwtPlot.xBottom, 0.0, 1.0)
        self.graph.setAxisScale(QwtPlot.yLeft, 0.0, 1.0)
        self.graph.setAttribute(Qt.WA_Hover, True)
        self.mainArea.layout().addWidget(self.graph)

        self.currentOptionsWidget = None
        self.data = []
        self.dataChangedFlag = False
        self.domain = None

        self.onDomainChanged()
        self.toolActions.actions()[0].trigger()

        self.dataHistory = [(Orange.data.Table(self.domain),
                             ["Class 1", "Class 2"])]
        self.historyCounter = 0
        self.updateHistoryBool = True

        self.resize(800, 600)
    def __init__(self, parent=None, signalManager=None, name="Data Generator"):
        OWWidget.__init__(self, parent, signalManager, name)
        
        self.outputs = [("Data", ExampleTable)]
        
        self.addClassAsMeta = False
        self.attributes = []
        self.cov = []
        self.commitOnChange = False
        
        self.loadSettings()
        
        self.variablesModel = VariableListModel([orange.FloatVariable(name) for name in ["X", "Y"]], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)

        
        self.classVariable = orange.EnumVariable("Class label", values=["Class 1", "Class 2"], baseValue=0)
        
        w = OWGUI.widgetBox(self.controlArea, "Class Label")
        
        self.classValuesView = listView = QListView()
        listView.setSelectionMode(QListView.SingleSelection)
        
        self.classValuesModel = EnumVariableModel(self.classVariable, self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled| Qt.ItemIsEditable)
        self.classValuesModel.wrap(self.classVariable.values)
        
        listView.setModel(self.classValuesModel)
        listView.selectionModel().select(self.classValuesModel.index(0), QItemSelectionModel.ClearAndSelect)
        self.connect(listView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onClassLabelSelection)
        listView.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Maximum)
        w.layout().addWidget(listView)
        
        self.addClassLabel = addClassLabel = QAction("+", self)
        addClassLabel.pyqtConfigure(toolTip="Add class label")#, icon=QIcon(icon_put))
        self.connect(addClassLabel, SIGNAL("triggered()"), self.addNewClassLabel)
        
        self.removeClassLabel = removeClassLabel = QAction("-", self)
        removeClassLabel.pyqtConfigure(toolTip="Remove class label")#, icon=QIcon(icon_remove))
        self.connect(removeClassLabel, SIGNAL("triggered()"), self.removeSelectedClassLabel)
        
        actionsWidget =  ModelActionsWidget([addClassLabel, removeClassLabel], self)
        actionsWidget.layout().addStretch(10)
        actionsWidget.layout().setSpacing(1)
        
        w.layout().addWidget(actionsWidget)
        
        toolbox = OWGUI.widgetBox(self.controlArea, "Tools", orientation=QGridLayout())
        self.toolActions = QActionGroup(self)
        self.toolActions.setExclusive(True)
        for i, (name, tooltip, tool, icon) in enumerate(self.TOOLS):
            action = QAction(name, self)
            action.setToolTip(tooltip)
            action.setCheckable(True)
            if os.path.exists(icon):
                action.setIcon(QIcon(icon))
            self.connect(action, SIGNAL("triggered()"), lambda tool=tool: self.onToolAction(tool))
            button = QToolButton()
            button.setDefaultAction(action)
            button.setIconSize(QSize(24, 24))
            button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
            button.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
            toolbox.layout().addWidget(button, i / 3, i % 3)
            self.toolActions.addAction(action)
            
        for column in range(3):
            toolbox.layout().setColumnMinimumWidth(column, 10)
            toolbox.layout().setColumnStretch(column, 1)
            
        self.optionsLayout = QStackedLayout()
        self.toolsStackCache = {}
        optionsbox = OWGUI.widgetBox(self.controlArea, "Options", orientation=self.optionsLayout)
        
#        OWGUI.checkBox(self.controlArea, self, "addClassAsMeta", "Add class ids as meta attributes")
        OWGUI.rubber(self.controlArea)
        box = OWGUI.widgetBox(self.controlArea, "Commit")
        
        cb = OWGUI.checkBox(box, self, "commitOnChange", "Commit on change",
                            tooltip="Send the data on any change.",
                            callback=self.commitIf,)
        b = OWGUI.button(box, self, "Commit", 
                         callback=self.commit, default=True)
        OWGUI.setStopper(self, b, cb, "dataChangedFlag", callback=self.commit)
        
        self.graph = PaintDataGraph(self)
        self.graph.setAxisScale(QwtPlot.xBottom, 0.0, 1.0)
        self.graph.setAxisScale(QwtPlot.yLeft, 0.0, 1.0)
        self.graph.setAttribute(Qt.WA_Hover, True)
        self.mainArea.layout().addWidget(self.graph)
        
        self.currentOptionsWidget = None
        self.data = []
        self.dataChangedFlag = False 
        self.domain = None
        
        self.onDomainChanged()
        self.toolActions.actions()[0].trigger()
        
        self.resize(800, 600)
Ejemplo n.º 4
0
    def __init__(self, parent=None, signalManager=None, name="Data Generator"):
        OWWidget.__init__(self, parent, signalManager, name, wantGraph=True)

        self.outputs = [("Data", ExampleTable)]

        self.addClassAsMeta = False
        self.attributes = []
        self.cov = []
        self.commitOnChange = False

        self.loadSettings()

        self.variablesModel = VariableListModel(
            [orange.FloatVariable(name) for name in ["X", "Y"]],
            self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)

        self.classVariable = orange.EnumVariable("Class label",
                                                 values=["Class 1", "Class 2"],
                                                 baseValue=0)

        w = OWGUI.widgetBox(self.controlArea, "Class Label")

        self.classValuesView = listView = QListView()
        listView.setSelectionMode(QListView.SingleSelection)
        listView.setEditTriggers(QListView.SelectedClicked)

        self.classValuesModel = EnumVariableModel(
            self.classVariable,
            self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)
        self.classValuesModel.wrap(self.classVariable.values)

        listView.setModel(self.classValuesModel)
        listView.selectionModel().select(self.classValuesModel.index(0),
                                         QItemSelectionModel.ClearAndSelect)
        self.connect(
            listView.selectionModel(),
            SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
            self.onClassLabelSelection)
        listView.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Maximum)
        w.layout().addWidget(listView)

        self.addClassLabel = addClassLabel = QAction("+", self)
        addClassLabel.pyqtConfigure(
            toolTip="Add class label")  #, icon=QIcon(icon_put))
        self.connect(addClassLabel, SIGNAL("triggered()"),
                     self.addNewClassLabel)

        self.removeClassLabel = removeClassLabel = QAction("-", self)
        removeClassLabel.pyqtConfigure(
            toolTip="Remove class label")  #, icon=QIcon(icon_remove))
        self.connect(removeClassLabel, SIGNAL("triggered()"),
                     self.removeSelectedClassLabel)

        actionsWidget = ModelActionsWidget([addClassLabel, removeClassLabel],
                                           self)
        actionsWidget.layout().addStretch(10)
        actionsWidget.layout().setSpacing(1)

        w.layout().addWidget(actionsWidget)

        toolbox = OWGUI.widgetBox(self.controlArea,
                                  "Tools",
                                  orientation=QGridLayout())
        self.toolActions = QActionGroup(self)
        self.toolActions.setExclusive(True)
        for i, (name, tooltip, tool, icon) in enumerate(self.TOOLS):
            action = QAction(name, self)
            action.setToolTip(tooltip)
            action.setCheckable(True)
            if os.path.exists(icon):
                action.setIcon(QIcon(icon))
            self.connect(action,
                         SIGNAL("triggered()"),
                         lambda tool=tool: self.onToolAction(tool))
            button = QToolButton()
            button.setDefaultAction(action)
            button.setIconSize(QSize(24, 24))
            button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
            button.setSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.Fixed)
            toolbox.layout().addWidget(button, i / 3, i % 3)
            self.toolActions.addAction(action)

        for column in range(3):
            toolbox.layout().setColumnMinimumWidth(column, 10)
            toolbox.layout().setColumnStretch(column, 1)

        self.optionsLayout = QStackedLayout()
        self.toolsStackCache = {}
        optionsbox = OWGUI.widgetBox(self.controlArea,
                                     "Options",
                                     orientation=self.optionsLayout)

        #        OWGUI.checkBox(self.controlArea, self, "addClassAsMeta", "Add class ids as meta attributes")
        OWGUI.rubber(self.controlArea)
        box = OWGUI.widgetBox(self.controlArea, "Commit")

        cb = OWGUI.checkBox(
            box,
            self,
            "commitOnChange",
            "Commit on change",
            tooltip="Send the data on any change.",
            callback=self.commitIf,
        )
        b = OWGUI.button(box,
                         self,
                         "Commit",
                         callback=self.commit,
                         default=True)
        OWGUI.setStopper(self, b, cb, "dataChangedFlag", callback=self.commit)

        self.graph = PaintDataGraph(self)
        self.graph.setAxisScale(QwtPlot.xBottom, 0.0, 1.0)
        self.graph.setAxisScale(QwtPlot.yLeft, 0.0, 1.0)
        self.graph.setAttribute(Qt.WA_Hover, True)
        self.mainArea.layout().addWidget(self.graph)

        self.currentOptionsWidget = None
        self.data = []
        self.dataChangedFlag = False
        self.domain = None

        self.onDomainChanged()
        self.toolActions.actions()[0].trigger()

        self.resize(800, 600)
Ejemplo n.º 5
0
    def __init__(self, parent=None, signalManager=None):
        OWWidget.__init__(self, parent, signalManager, 'Python Script')

        self.inputs = [
            ("in_data", Orange.data.Table, self.setExampleTable, Default),
            ("in_distance", Orange.misc.SymMatrix, self.setDistanceMatrix,
             Default),
            ("in_learner", Orange.core.Learner, self.setLearner, Default),
            ("in_classifier", Orange.core.Classifier, self.setClassifier,
             Default), ("in_object", object, self.setObject)
        ]

        self.outputs = [("out_data", Orange.data.Table),
                        ("out_distance", Orange.misc.SymMatrix),
                        ("out_learner", Orange.core.Learner),
                        ("out_classifier", Orange.core.Classifier, Dynamic),
                        ("out_object", object, Dynamic)]

        self.in_data = None
        self.in_distance = None
        self.in_learner = None
        self.in_classifier = None
        self.in_object = None
        self.auto_execute = False

        self.libraryListSource = [
            Script("Hello world", "print 'Hello world'\n")
        ]
        self.currentScriptIndex = 0
        self.splitterState = None
        self.loadSettings()

        for s in self.libraryListSource:
            s.flags = 0

        self._cachedDocuments = {}

        self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info')
        OWGUI.label(
            self.infoBox, self,
            "<p>Execute python script.</p><p>Input variables:<ul><li> " +
            "<li>".join(t[0] for t in self.inputs) +
            "</ul></p><p>Output variables:<ul><li>" +
            "<li>".join(t[0] for t in self.outputs) + "</ul></p>")

        self.libraryList = PyListModel([],
                                       self,
                                       flags=Qt.ItemIsSelectable
                                       | Qt.ItemIsEnabled | Qt.ItemIsEditable)

        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)

        self.libraryView = QListView(
            editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred))
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)

        self.libraryView.selectionModel().selectionChanged.connect(
            self.onSelectedScriptChanged)
        self.controlBox.layout().addWidget(self.libraryView)

        w = ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.setToolTip("Add a new script to the library")
        action.triggered.connect(self.onAddScript)
        w.addAction(action)

        action = QAction(unicodedata.lookup("MINUS SIGN"), self)
        action.setToolTip("Remove script from library")
        action.triggered.connect(self.onRemoveScript)
        w.addAction(action)

        action = QAction("Update", self)
        action.setToolTip("Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.commitChangesToLibrary)
        w.addAction(action)

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import a script from a file", self)
        save_to_file = QAction("Save selected script to a file", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        new_from_file.triggered.connect(self.onAddScriptFromFile)
        save_to_file.triggered.connect(self.saveScript)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        button = w.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        self.runBox = OWGUI.widgetBox(self.controlArea, 'Run')
        OWGUI.button(self.runBox, self, "Execute", callback=self.execute)
        OWGUI.checkBox(self.runBox,
                       self,
                       "auto_execute",
                       "Auto execute",
                       tooltip=("Run the script automatically whenever "
                                "the inputs to the widget change."))

        self.splitter = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitter)

        self.defaultFont = defaultFont = \
            "Monaco" if sys.platform == "darwin" else "Courier"

        self.textBox = OWGUI.widgetBox(self, 'Python script')
        self.splitter.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)

        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.text.modificationChanged[bool].connect(self.onModificationChanged)

        self.consoleBox = OWGUI.widgetBox(self, 'Console')
        self.splitter.addWidget(self.consoleBox)
        self.console = PythonConsole(self.__dict__, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.console.setTabStopWidth(4)

        select_row(self.libraryView, self.currentScriptIndex)

        self.splitter.setSizes([2, 1])
        if self.splitterState is not None:
            self.splitter.restoreState(QByteArray(self.splitterState))

        self.splitter.splitterMoved[int, int].connect(self.onSpliterMoved)
        self.controlArea.layout().addStretch(1)
        self.resize(800, 600)
Ejemplo n.º 6
0
    def __init__(self, parent=None, signalManager=None):
        OWWidget.__init__(self, parent, signalManager, 'MultiData Python Script')
        
        self.inputs = [("in_data", ExampleTable, self.setExampleTable, Default + Multiple),
                       ("in_distance", orange.SymMatrix, self.setDistanceMatrix),
                       ("in_network", Orange.network.Graph, self.setNetwork),
                       ("in_learners", orange.Learner, self.setLearner, Default + Multiple),
                       ("in_classifiers", orange.Classifier, self.setClassifier, Default + Multiple),
                       ("in_misc", object, self.setMisc, Default + Multiple)]
        self.outputs = [("out_data", ExampleTable), 
                        ("out_distance", orange.SymMatrix), 
                        ("out_network", Orange.network.Graph), 
                        ("out_learner", orange.Learner), 
                        ("out_classifier", orange.Classifier, Dynamic),
                        ("out_test_results", Orange.evaluation.testing.ExperimentResults),
                        ("out_misc", object)]
        
        self.in_data = []
        self.in_data_dict = {}   # TODO: switch to weakref?
        self.in_learners = []
        self.in_learner_dict = {}
        self.in_classifiers = []
        self.in_classifier_dict = {}
        self.in_misc = []
        self.in_misc_dict = {}

        self.in_network = None
        self.in_distance = None
        
        self.codeFile = ''
        self.libraryListSource = [Script("Hello world", "print 'Hello world'\n")]
        self.currentScriptIndex = 0
        self.splitterState = None
        self.loadSettings()
        
        for s in self.libraryListSource:
            s.flags = 0
        
        self._cachedDocuments = {}
        
        self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info')
        label = OWGUI.label(self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \
                    "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + \
                    "<li>".join(t[0] for t in self.outputs) + "</ul></p>")
        self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)
#        self.libraryList.append(Script("Hello world", "print 'Hello world'\n"))
        self.libraryList.wrap(self.libraryListSource)
        
        self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)
        self.libraryView = QListView()
        self.libraryView.setEditTriggers(QListView.DoubleClicked | QListView.EditKeyPressed)
        self.libraryView.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)
        self.connect(self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onSelectedScriptChanged)
        self.controlBox.layout().addWidget(self.libraryView)
        w = ModelActionsWidget()
        
        self.addNewScriptAction = action = QAction("+", self)
        action.pyqtConfigure(toolTip="Add a new script to the library")
        self.connect(action, SIGNAL("triggered()"), self.onAddScript)
        new_empty = QAction("Add a new empty script", action)
        new_from_file = QAction("Add a new script from a file", action)
        self.connect(new_empty, SIGNAL("triggered()"), self.onAddScript)
        self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile)
        menu = QMenu(w)
        menu.addAction(new_empty)
        menu.addAction(new_from_file)
        
#        action.setMenu(menu)
        button = w.addAction(action)
        
        self.removeAction = action = QAction("-", self)
        action.pyqtConfigure(toolTip="Remove script from library")
        self.connect(action, SIGNAL("triggered()"), self.onRemoveScript)
        w.addAction(action)
        
        action = QAction("Update", self)
        action.pyqtConfigure(toolTip="Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        self.connect(action, SIGNAL("triggered()"), self.commitChangesToLibrary)
        b = w.addAction(action)
#        b.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        
        action = QAction("More", self)
        action.pyqtConfigure(toolTip="More actions") #, icon=self.style().standardIcon(QStyle.SP_ToolBarHorizontalExtensionButton))
        
        self.openScriptFromFileAction = new_from_file = QAction("Import a script from a file", self)
        self.saveScriptToFile = save_to_file = QAction("Save selected script to a file", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))
        
        self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile)
        self.connect(save_to_file, SIGNAL("triggered()"), self.saveScript)
        
        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        b = w.addAction(action)
        b.setPopupMode(QToolButton.InstantPopup) 
        ## TODO: set the space for the indicator
        
        w.layout().setSpacing(1)
        
        self.controlBox.layout().addWidget(w)
                    
#        OWGUI.button(self.controlBox, self, "Open...", callback=self.openScript)
#        OWGUI.button(self.controlBox, self, "Save...", callback=self.saveScript)
        
        self.runBox = OWGUI.widgetBox(self.controlArea, 'Run')
        OWGUI.button(self.runBox, self, "Execute", callback=self.execute)
        
        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitCanvas)
        
        self.defaultFont = defaultFont = "Monaco" if sys.platform == "darwin" else "Courier"
        self.textBox = OWGUI.widgetBox(self, 'MultiData Python script')
        self.splitCanvas.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)
        
        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)
        
        self.connect(self.text, SIGNAL("modificationChanged(bool)"), self.onModificationChanged)
        
        self.saveAction = action = QAction("&Save", self.text)
        action.pyqtConfigure(toolTip="Save script to file")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        self.connect(action, SIGNAL("triggered()"), self.saveScript)
        
        self.consoleBox = OWGUI.widgetBox(self, 'Console')
        self.splitCanvas.addWidget(self.consoleBox)
        self.console = PythonConsole(self.__dict__, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.console.setTabStopWidth(4)
        
        self.openScript(self.codeFile)
        try:
            self.libraryView.selectionModel().select(self.libraryList.index(self.currentScriptIndex), QItemSelectionModel.ClearAndSelect)
        except Exception:
            pass
        self.splitCanvas.setSizes([2, 1])
        if self.splitterState is not None:
            self.splitCanvas.restoreState(QByteArray(self.splitterState))
        
        self.connect(self.splitCanvas, SIGNAL("splitterMoved(int, int)"), lambda pos, ind: setattr(self, "splitterState", str(self.splitCanvas.saveState())))
        self.controlArea.layout().addStretch(1)
        self.resize(800,600)
Ejemplo n.º 7
0
class LibraryWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setLayout(QVBoxLayout())
        
        self.layout().setSpacing(1)
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.view = QListView(self)
        self.view.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)
        self.layout().addWidget(self.view)
        
        self.addScriptAction = QAction("+", self)
        self.addScriptAction.pyqtConfigure(toolTip="Add a new script to library")
        
        self.updateScriptAction = QAction("Update", self)
        self.updateScriptAction.pyqtConfigure(toolTip="Save changes in the editor to library", shortcut=QKeySequence.Save)
        
        self.removeScriptAction = QAction("-", self)
        self.removeScriptAction.pyqtConfigure(toolTip="Remove selected script from file")
        
        self.moreAction = QAction("More", self)
        self.moreAction.pyqtConfigure(toolTip="More actions")#, icon=self.style().standardIcon(QStyle.SP_ToolBarHorizontalExtensionButton))
        
        self.addScriptFromFile = QAction("Add script from file", self)
        self.addScriptFromFile.pyqtConfigure(toolTip="Add a new script to library from a file")
        
        self.saveScriptToFile = QAction("Save script to file", self)
        self.saveScriptToFile.pyqtConfigure(toolTip="Save script to a file", shortcut=QKeySequence.SaveAs)
        
        menu = QMenu(self)
        menu.addActions([self.addScriptFromFile, self.saveScriptToFile])
        self.moreAction.setMenu(menu)
        
        self.actionsWidget = ModelActionsWidget([self.addScriptAction, self.updateScriptAction, 
                                            self.removeScriptAction, self.moreAction], self)
#        self.actionsWidget.buttons[1].setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        self.actionsWidget.layout().setSpacing(1)
        
        self.layout().addWidget(self.actionsWidget)
        
        self.resize(800, 600)
        
        
    def setScriptModel(self, model):
        """ Set the script model to show 
        """
        self.model = model
        if self.view is not None:
            self.view.setModel(model)
        
        
    def setView(self, view):
        """ Set the view (QListView or subclass) to use
        """
        if self.view is not None:
            self.layout().removeItemAt(0) 
        self.view = view
        self.layout().insertItem(0, view)
        if self.model is not None:
            self.view.setModel(self.model)
            
            
    def setActionsWidget(self, widget):
        """ Set the widget below the view to widget (removing the previous widget)
        """
        self.layout().removeItemAt(1)
        self.actionsWidget = widget
        self.layout().insertWidget(1, widget)

    def setDocumentEditor(self, editor):
        self.editor = editor
Ejemplo n.º 8
0
    def __init__(self, parent=None, signalManager=None, name="Preprocess"):
        OWWidget.__init__(self, parent, signalManager, name)

        self.inputs = [("Example Table", ExampleTable, self.setData)
                       ]  #, ("Learner", orange.Learner, self.setLearner)]
        self.outputs = [("Preprocess", orngWrap.PreprocessedLearner),
                        ("Preprocessed Example Table", ExampleTable)
                        ]  #, ("Preprocessor", orange.Preprocessor)]

        self.autoCommit = False
        self.changedFlag = False

        #        self.allSchemas = [PreprocessorSchema("Default" , [Preprocessor_discretize(method=orange.EntropyDiscretization()), Preprocessor_dropMissing()])]
        self.allSchemas = [("Default", [
            Preprocessor_discretizeEntropy(
                method=orange.EntropyDiscretization()),
            Preprocessor_dropMissing()
        ], 0)]

        self.lastSelectedSchemaIndex = 0

        self.preprocessorsList = PyListModel([], self)

        box = OWGUI.widgetBox(self.controlArea, "Preprocessors", addSpace=True)
        box.layout().setSpacing(1)

        self.setStyleSheet("QListView::item { margin: 1px;}")
        self.preprocessorsListView = QListView()
        self.preprocessorsListSelectionModel = ListSingleSelectionModel(
            self.preprocessorsList, self)
        self.preprocessorsListView.setItemDelegate(
            PreprocessorItemDelegate(self))
        self.preprocessorsListView.setModel(self.preprocessorsList)

        self.preprocessorsListView.setSelectionModel(
            self.preprocessorsListSelectionModel)
        self.preprocessorsListView.setSelectionMode(QListView.SingleSelection)

        self.connect(self.preprocessorsListSelectionModel,
                     SIGNAL("selectedIndexChanged(QModelIndex)"),
                     self.onPreprocessorSelection)
        self.connect(self.preprocessorsList,
                     SIGNAL("dataChanged(QModelIndex, QModelIndex)"),
                     lambda arg1, arg2: self.commitIf)

        box.layout().addWidget(self.preprocessorsListView)

        self.addPreprocessorAction = QAction("+", self)
        self.addPreprocessorAction.pyqtConfigure(
            toolTip="Add a new preprocessor to the list")
        self.removePreprocessorAction = QAction("-", self)
        self.removePreprocessorAction.pyqtConfigure(
            toolTip="Remove selected preprocessor from the list")
        self.removePreprocessorAction.setEnabled(False)

        self.connect(
            self.preprocessorsListSelectionModel,
            SIGNAL("selectedIndexChanged(QModelIndex)"), lambda index: self.
            removePreprocessorAction.setEnabled(index.isValid()))

        actionsWidget = ModelActionsWidget(
            [self.addPreprocessorAction, self.removePreprocessorAction])
        actionsWidget.layout().setSpacing(1)
        actionsWidget.layout().addStretch(10)

        box.layout().addWidget(actionsWidget)

        self.connect(self.addPreprocessorAction, SIGNAL("triggered()"),
                     self.onAddPreprocessor)
        self.connect(self.removePreprocessorAction, SIGNAL("triggered()"),
                     self.onRemovePreprocessor)

        box = OWGUI.widgetBox(self.controlArea, "Saved Schemas", addSpace=True)

        self.schemaFilterEdit = OWGUIEx.LineEditFilter(self)
        box.layout().addWidget(self.schemaFilterEdit)

        self.schemaList = PyListModel([],
                                      self,
                                      flags=Qt.ItemIsSelectable
                                      | Qt.ItemIsEditable | Qt.ItemIsEnabled)
        self.schemaListProxy = PySortFilterProxyModel(filter_fmt="{0.name}",
                                                      parent=self)
        self.schemaListProxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.schemaListProxy.setSourceModel(self.schemaList)
        self.schemaListView = QListView()
        self.schemaListView.setItemDelegate(PreprocessorSchemaDelegate(self))
        #        self.schemaListView.setModel(self.schemaList)
        self.schemaListView.setModel(self.schemaListProxy)
        self.connect(self.schemaFilterEdit, SIGNAL("textEdited(QString)"),
                     self.schemaListProxy.setFilterRegExp)
        box.layout().addWidget(self.schemaListView)

        self.schemaListSelectionModel = ListSingleSelectionModel(
            self.schemaListProxy, self)
        self.schemaListView.setSelectionMode(QListView.SingleSelection)
        self.schemaListView.setSelectionModel(self.schemaListSelectionModel)

        self.connect(self.schemaListSelectionModel,
                     SIGNAL("selectedIndexChanged(QModelIndex)"),
                     self.onSchemaSelection)

        self.addSchemaAction = QAction("+", self)
        self.addSchemaAction.pyqtConfigure(
            toolTip="Add a new preprocessor schema")
        self.updateSchemaAction = QAction("Update", self)
        self.updateSchemaAction.pyqtConfigure(
            toolTip="Save changes made in the current schema")
        self.removeSchemaAction = QAction("-", self)
        self.removeSchemaAction.pyqtConfigure(toolTip="Remove selected schema")

        self.updateSchemaAction.setEnabled(False)
        self.removeSchemaAction.setEnabled(False)

        actionsWidget = ModelActionsWidget([])
        actionsWidget.addAction(self.addSchemaAction)
        actionsWidget.addAction(self.updateSchemaAction).setSizePolicy(
            QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        actionsWidget.addAction(self.removeSchemaAction)
        actionsWidget.layout().setSpacing(1)

        box.layout().addWidget(actionsWidget)

        self.connect(self.addSchemaAction, SIGNAL("triggered()"),
                     self.onAddSchema)
        self.connect(self.updateSchemaAction, SIGNAL("triggered()"),
                     self.onUpdateSchema)
        self.connect(self.removeSchemaAction, SIGNAL("triggered()"),
                     self.onRemoveSchema)

        self.addPreprocessorsMenuActions = actions = []
        for name, pp, kwargs in self.preprocessors:
            action = QAction(name, self)
            self.connect(action,
                         SIGNAL("triggered()"),
                         lambda pp=pp, kwargs=kwargs: self.addPreprocessor(
                             pp(**kwargs)))
            actions.append(action)

        box = OWGUI.widgetBox(self.controlArea, "Output")
        cb = OWGUI.checkBox(box,
                            self,
                            "autoCommit",
                            "Commit on any change",
                            callback=self.commitIf)
        b = OWGUI.button(box, self, "Commit", callback=self.commit)
        OWGUI.setStopper(self, b, cb, "changedFlag", callback=self.commitIf)

        self.mainAreaStack = QStackedLayout()
        self.stackedEditorsCache = {}

        OWGUI.widgetBox(self.mainArea, orientation=self.mainAreaStack)

        self.data = None
        self.learner = None

        self.loadSettings()
        self.activateLoadedSettings()
Ejemplo n.º 9
0
    def __init__(self, parent=None, signalManager=None):
        OWWidget.__init__(self, parent, signalManager, 'Python Script')

        self.inputs = [("in_data", Orange.data.Table, self.setExampleTable,
                        Default),
                       ("in_distance", Orange.misc.SymMatrix,
                        self.setDistanceMatrix, Default),
                       ("in_learner", Orange.core.Learner, self.setLearner,
                        Default),
                       ("in_classifier", Orange.core.Classifier,
                        self.setClassifier, Default),
                       ("in_object", object, self.setObject)]

        self.outputs = [("out_data", Orange.data.Table),
                        ("out_distance", Orange.misc.SymMatrix),
                        ("out_learner", Orange.core.Learner),
                        ("out_classifier", Orange.core.Classifier, Dynamic),
                        ("out_object", object, Dynamic)]

        self.in_data = None
        self.in_distance = None
        self.in_learner = None
        self.in_classifier = None
        self.in_object = None
        self.auto_execute = False

        self.libraryListSource = [Script("Hello world",
                                         "print 'Hello world'\n")]
        self.currentScriptIndex = 0
        self.splitterState = None
        self.loadSettings()

        for s in self.libraryListSource:
            s.flags = 0

        self._cachedDocuments = {}

        self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info')
        OWGUI.label(
            self.infoBox, self,
            "<p>Execute python script.</p><p>Input variables:<ul><li> " +
            "<li>".join(t[0] for t in self.inputs) +
            "</ul></p><p>Output variables:<ul><li>" +
            "<li>".join(t[0] for t in self.outputs) +
            "</ul></p>"
        )

        self.libraryList = PyListModel(
           [], self,
           flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
        )

        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)

        self.libraryView = QListView(
            editTriggers=QListView.DoubleClicked |
                         QListView.EditKeyPressed,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored,
                                   QSizePolicy.Preferred)
        )
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)

        self.libraryView.selectionModel().selectionChanged.connect(
            self.onSelectedScriptChanged
        )
        self.controlBox.layout().addWidget(self.libraryView)

        w = ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.setToolTip("Add a new script to the library")
        action.triggered.connect(self.onAddScript)
        w.addAction(action)

        action = QAction(unicodedata.lookup("MINUS SIGN"), self)
        action.setToolTip("Remove script from library")
        action.triggered.connect(self.onRemoveScript)
        w.addAction(action)

        action = QAction("Update", self)
        action.setToolTip("Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.commitChangesToLibrary)
        w.addAction(action)

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import a script from a file", self)
        save_to_file = QAction("Save selected script to a file", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        new_from_file.triggered.connect(self.onAddScriptFromFile)
        save_to_file.triggered.connect(self.saveScript)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        button = w.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        self.runBox = OWGUI.widgetBox(self.controlArea, 'Run')
        OWGUI.button(self.runBox, self, "Execute", callback=self.execute)
        OWGUI.checkBox(self.runBox, self, "auto_execute", "Auto execute",
                       tooltip=("Run the script automatically whenever "
                                "the inputs to the widget change."))

        self.splitter = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitter)

        self.defaultFont = defaultFont = \
            "Monaco" if sys.platform == "darwin" else "Courier"

        self.textBox = OWGUI.widgetBox(self, 'Python script')
        self.splitter.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)

        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.text.modificationChanged[bool].connect(self.onModificationChanged)

        self.consoleBox = OWGUI.widgetBox(self, 'Console')
        self.splitter.addWidget(self.consoleBox)
        self.console = PythonConsole(self.__dict__, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.console.setTabStopWidth(4)

        select_row(self.libraryView, self.currentScriptIndex)

        self.splitter.setSizes([2, 1])
        if self.splitterState is not None:
            self.splitter.restoreState(QByteArray(self.splitterState))

        self.splitter.splitterMoved[int, int].connect(self.onSpliterMoved)
        self.controlArea.layout().addStretch(1)
        self.resize(800, 600)
Ejemplo n.º 10
0
    def __init__(self, parent=None, signalManager=None):
        OWWidget.__init__(self, parent, signalManager, 'Python Script')

        self.inputs = [
            ("in_data", ExampleTable, self.setExampleTable),
            ("in_distance", orange.SymMatrix, self.setDistanceMatrix),
            ("in_network", Orange.network.Graph, self.setNetwork),
            ("in_learner", orange.Learner, self.setLearner),
            ("in_classifier", orange.Classifier, self.setClassifier)
        ]
        self.outputs = [("out_data", ExampleTable),
                        ("out_distance", orange.SymMatrix),
                        ("out_network", Orange.network.Graph),
                        ("out_learner", orange.Learner),
                        ("out_classifier", orange.Classifier, Dynamic)]

        self.in_data = None
        self.in_network = None
        self.in_distance = None
        self.in_learner = None
        self.in_classifier = None

        self.codeFile = ''
        self.libraryListSource = [
            Script("Hello world", "print 'Hello world'\n")
        ]
        self.currentScriptIndex = 0
        self.splitterState = None
        self.loadSettings()

        for s in self.libraryListSource:
            s.flags = 0

        self._cachedDocuments = {}

        self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info')
        label = OWGUI.label(self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \
                    "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + \
                    "<li>".join(t[0] for t in self.outputs) + "</ul></p>")
        self.libraryList = PyListModel([],
                                       self,
                                       flags=Qt.ItemIsSelectable
                                       | Qt.ItemIsEnabled | Qt.ItemIsEditable)
        #        self.libraryList.append(Script("Hello world", "print 'Hello world'\n"))
        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)
        self.libraryView = QListView()
        self.libraryView.pyqtConfigure(editTriggers=QListView.DoubleClicked
                                       | QListView.SelectedClicked)
        self.libraryView.setSizePolicy(QSizePolicy.Ignored,
                                       QSizePolicy.Preferred)
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)
        self.connect(
            self.libraryView.selectionModel(),
            SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
            self.onSelectedScriptChanged)
        self.controlBox.layout().addWidget(self.libraryView)
        w = ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.pyqtConfigure(toolTip="Add a new script to the library")
        self.connect(action, SIGNAL("triggered()"), self.onAddScript)
        new_empty = QAction("Add a new empty script", action)
        new_from_file = QAction("Add a new script from a file", action)
        self.connect(new_empty, SIGNAL("triggered()"), self.onAddScript)
        self.connect(new_from_file, SIGNAL("triggered()"),
                     self.onAddScriptFromFile)
        menu = QMenu(w)
        menu.addAction(new_empty)
        menu.addAction(new_from_file)

        #        action.setMenu(menu)
        button = w.addAction(action)

        self.removeAction = action = QAction("-", self)
        action.pyqtConfigure(toolTip="Remove script from library")
        self.connect(action, SIGNAL("triggered()"), self.onRemoveScript)
        w.addAction(action)

        action = QAction("Update", self)
        action.pyqtConfigure(toolTip="Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        self.connect(action, SIGNAL("triggered()"),
                     self.commitChangesToLibrary)
        b = w.addAction(action)
        #        b.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)

        action = QAction("More", self)
        action.pyqtConfigure(
            toolTip="More actions"
        )  #, icon=self.style().standardIcon(QStyle.SP_ToolBarHorizontalExtensionButton))

        self.openScriptFromFileAction = new_from_file = QAction(
            "Import a script from a file", self)
        self.saveScriptToFile = save_to_file = QAction(
            "Save selected script to a file", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        self.connect(new_from_file, SIGNAL("triggered()"),
                     self.onAddScriptFromFile)
        self.connect(save_to_file, SIGNAL("triggered()"), self.saveScript)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        b = w.addAction(action)
        b.setPopupMode(QToolButton.InstantPopup)
        ## TODO: set the space for the indicator

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        #        OWGUI.button(self.controlBox, self, "Open...", callback=self.openScript)
        #        OWGUI.button(self.controlBox, self, "Save...", callback=self.saveScript)

        self.runBox = OWGUI.widgetBox(self.controlArea, 'Run')
        OWGUI.button(self.runBox, self, "Execute", callback=self.execute)

        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitCanvas)

        self.defaultFont = defaultFont = "Monaco" if sys.platform == "darwin" else "Courier"
        self.textBox = OWGUI.widgetBox(self, 'Python script')
        self.splitCanvas.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)

        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.connect(self.text, SIGNAL("modificationChanged(bool)"),
                     self.onModificationChanged)

        self.saveAction = action = QAction("&Save", self.text)
        action.pyqtConfigure(toolTip="Save script to file")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        self.connect(action, SIGNAL("triggered()"), self.saveScript)

        self.consoleBox = OWGUI.widgetBox(self, 'Console')
        self.splitCanvas.addWidget(self.consoleBox)
        self.console = PythonConsole(self.__dict__, self)
        self.consoleBox.layout().addWidget(self.console)
        self.console.document().setDefaultFont(QFont(defaultFont))
        self.consoleBox.setAlignment(Qt.AlignBottom)
        self.console.setTabStopWidth(4)

        self.openScript(self.codeFile)
        try:
            self.libraryView.selectionModel().select(
                self.libraryList.index(self.currentScriptIndex),
                QItemSelectionModel.ClearAndSelect)
        except Exception:
            pass
        self.splitCanvas.setSizes([2, 1])
        if self.splitterState is not None:
            self.splitCanvas.restoreState(QByteArray(self.splitterState))

        self.connect(
            self.splitCanvas, SIGNAL("splitterMoved(int, int)"),
            lambda pos, ind: setattr(self, "splitterState",
                                     str(self.splitCanvas.saveState())))
        self.controlArea.layout().addStretch(1)
        self.resize(800, 600)