Commits

Janez Demšar  committed 60590d0 Merge

Merge

  • Participants
  • Parent commits 27d1ee3, f374aa6

Comments (0)

Files changed (9)

File Orange/OrangeCanvas/application/outputview.py

     QFont, QSizePolicy
 )
 
-from PyQt4.QtCore import Qt, QObject, QEvent, QCoreApplication, QThread, QSize
+from PyQt4.QtCore import (
+    Qt, QObject, QEvent, QCoreApplication, QThread, QSemaphore, QSize
+)
 from PyQt4.QtCore import pyqtSignal as Signal
 
 
         self.outputview.writeWithFormat(string, self.charformat)
 
     def writelines(self, lines):
-        self.outputview.writelines(lines, self.charformat)
+        self.outputview.writelinesWithFormat(lines, self.charformat)
 
     def flush(self):
         self.outputview.flush()
         self.charformat = None
 
 
+# QMetaCallEvent like event
 class QueuedCallEvent(QEvent):
     QueuedCall = QEvent.registerEventType()
 
-    def __init__(self, function, args, kwargs):
+    def __init__(self, function, args, kwargs, semaphore=None):
         QEvent.__init__(self, QueuedCallEvent.QueuedCall)
         self.function = function
         self.args = args
         self.kwargs = kwargs
+        self.semaphore = semaphore
         self._result = None
         self._exc_info = None
         self._state = 0
         try:
             self._result = self.function(*self.args, **self.kwargs)
             self._state = 1
-        except Exception, ex:
+            if self.semaphore is not None:
+                self.semaphore.release()
+        except BaseException, ex:
             self._exc_info = (type(ex), ex.args, None)
+            if self.semaphore is not None:
+                self.semaphore.release()
             raise
 
     def result(self):
             raise self._exc_info[0], self._exc_info[1]
         else:
             # Should this block, add timeout?
-            raise RuntimeError("Result not yet ready")
+            raise RuntimeError("Result of a QueuedCallEvent is not yet ready")
 
     def isready(self):
         return self._state == 1 or self._exc_info
     """
     @wraps(method)
     def delay_method_call(self, *args, **kwargs):
-        event = QueuedCallEvent(method, (self,) + args, kwargs)
+        if self.thread() != QThread.currentThread():
+            semaphore = QSemaphore()
+        else:
+            semaphore = None
+        event = QueuedCallEvent(method, (self,) + args, kwargs, semaphore)
         QCoreApplication.postEvent(self, event)
-        QCoreApplication.sendPostedEvents()
+        if semaphore is None:
+            QCoreApplication.sendPostedEvents()
+        else:
+            # Wait until the other thread's event loop processes the event
+            semaphore.acquire()
         return event.result()
 
     return delay_method_call
         else:
             stream = self.stream
 
-        stream.writelines([separator, header] + text)
+        stream.write("".join([separator, header] + text))
 
         self.handledException.emit()

File Orange/OrangeWidgets/Data/OWPythonScript.py

         self.setTextCursor(cursor)
         self.ensureCursorVisible()
 
+    def writelines(self, lines):
+        for line in lines:
+            self.write(line)
+
     def push(self, line):
         if self.history[0] != line:
             self.history.insert(0, line)

File Orange/OrangeWidgets/OWBaseWidget.py

 
 def _deprecation_warning(name):
     warnings.warn(
-        "{0!r} is deprecated. It will be removed in Orange 2.8",
+        "{0!r} is deprecated. It will be removed in Orange 2.8".format(name),
         DeprecationWarning,
         stacklevel=2
     )
         if changed:
             if self.widgetStateHandler:
                 self.widgetStateHandler()
-            elif text: # and stateType != "Info":
-                self.printEvent(stateType + " - " + text)
-            
+            elif text:
+                _log.info(stateType + " - " + text)
+
             if type(id) == list:
                 for i in id:
                     self.emit(SIGNAL("widgetStateChanged(QString, int, QString)"),

File Orange/OrangeWidgets/Visualize/OWDistributions.py

         self.GeneralTab = self.SettingsTab = self.controlArea
 
         self.graph = OWDistributionGraph(self, self.mainArea)
+        # Set a fixed minimum width. This disables the dynamic minimumSizeHint
+        # from the layout, which can return a uselessly large width for the
+        # x axis when showing a discrete variable with many values.
+        self.graph.setMinimumWidth(250)
+
         self.mainArea.layout().addWidget(self.graph)
         self.graph.setYRlabels(None)
         self.graph.setAxisScale(QwtPlot.yRight, 0.0, 1.0, 0.1)

File Orange/OrangeWidgets/Visualize/OWScatterPlot.py

         self.outputs = [("Selected Data", ExampleTable), ("Other Data", ExampleTable)]
 
         self.graph = OWScatterPlotGraph(self, self.mainArea, "ScatterPlot")
+        self.graph.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+        self.graph.setMinimumSize(250, 200)
+        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+
         self.vizrank = OWVizRank(self, self.signalManager, self.graph, orngVizRank.SCATTERPLOT, "ScatterPlot")
         self.optimizationDlg = self.vizrank
 
     def updateGraph(self, attrList = None, insideColors = None, **args):
         self.graph.zoomStack = []
         if not self.graph.haveData:
+            self.graph.replot()
             return
 
         if attrList and len(attrList) == 2:

File Orange/data/preprocess/scaling.py

     equiN if we don't have a class or class is continuous).
     """
     entro_disc = preprocess.EntropyDiscretization()
-    equi_disc  = preprocess.EquiNDiscretization(number_of_intervals=number_of_intervals)
+    equi_disc = preprocess.EquiNDiscretization(n=number_of_intervals)
     disc_attrs = []
 
     classname = (data and len(data) > 0 and data.domain.class_var and
             warnings.warn("Could not discretize %s attribute. %s" %
                           (attr.name, ex.message))
 
-    if classname: disc_attrs.append(data.domain.class_var)
+    if classname:
+        disc_attrs.append(data.domain.class_var)
     d2 = data.translate(disc_attrs, True)
     return d2
 
 except ImportError:
     orangeqt_setup = None
     build_pyqt_ext = None
+except Exception:
+    # should display a warning about this (configuraiton error ...)
+    orangeqt_setup = None
+    build_pyqt_ext = None
+
 
 class LibStatic(Extension):
     pass
 
+
 class PyXtractExtension(Extension):
     def __init__(self, *args, **kwargs):
         for name, default in [("extra_pyxtract_cmds", []), ("lib_type", "dynamic")]:

File source/orange/lib_kernel.cpp

     if (PyArg_ParseTuple(args, "O&|i", cc_Domain, &domain))
       return WrapOrange(PExampleTable(mlnew TExampleTable(domain, weg)));
 
+    PyErr_Clear();
     PyObject *pargs, *guard = NULL;
     int keepMeta = 0;
     if (args && ((PyTuple_Size(args)==1) || ((PyTuple_Size(args)==2) && PyInt_Check(PyTuple_GET_ITEM(args, 1))))) {

File source/orangeqt/setup.py

 qt_include_dir = None
 qt_lib_dir = None
 qt_framework = False
+qt_framework_dir = None
 
 # use PyQt4 build time config if provided
 if pyqtconfig is not None:
             # This is the standard Qt4 framework layout
             qt_framework = True
             qt_framework_dir = pjoin(qt_dir, "lib")
-        elif glob(pjoin(qt_dir, "Frameworks", "Qt*.framework")):
+        elif glob.glob(pjoin(qt_dir, "Frameworks", "Qt*.framework")):
             # Also worth checking (standard for bundled apps)
             qt_framework = True
             qt_framework_dir = pjoin(qt_dir, "Frameworks")