Starts a new completion popup for the current object.
        
        :return     <bool> success

def startCompletion(self, force=False):
        """
        Starts a new completion popup for the current object.
        
        :return     <bool> success
        """
        # add the top level items
        tree = self.completerTree()
        if not force and tree.isVisible():
            return
        
        tree.clear()
        
        # make sure we have a valid object
        obj, remain = self.objectAtCursor()
        
        if obj is None:
            tree.hide()
            return
        
        # determine the cursor position
        rect   = self.cursorRect()
        cursor = self.textCursor()
        point  = QPoint(rect.left(), rect.top() + 18)
        
        # compare the ids since some things might overload the __eq__
        # comparator
        if id(obj) == id(self._scope):
            o_keys = obj.keys()
        elif obj is not None:
            o_keys = dir(obj)
        
        keys = [key for key in sorted(o_keys) if not key.startswith('_')]
        if id(obj) == id(self._scope):
            if not remain:
                return False
            else:
                keys = filter(lambda x: x.startswith(remain[0]), keys)
        
        if not keys:
            return False
        
        for key in keys:
            tree.addTopLevelItem(QTreeWidgetItem([key]))
        
        tree.move(self.mapToGlobal(point))
        tree.show()
        return True