Exemple #1
0
    def save_image_as(self):
        img = self.get_selection().toImage()
        if img.isNull():
            QMessageBox.critical(self, self.tr('Error'), self.tr('No image was selected!'))
            return

        self.hide()

        formats = {
            self.tr('Portable Network Graphics (*.png)'): 'png',
            self.tr('Joint Photographic Experts Group (*.jpg *.jpeg)'): 'jpg',
            self.tr('Graphics Interchange Format (*.gif)'): 'gif',
            self.tr('Bitmap (*.bmp)'): 'bmp',
            self.tr('All Images (*.png *.jpg *.gif *.bmp)'): 'all'
        }

        file_format = None
        destination = QFileDialog.getSaveFileName(self, 'Save image', '', ';;'.join(formats.keys()))
        if isinstance(destination, tuple):
            destination, file_format = destination
            file_format = formats[file_format]
            if file_format == 'all':
                file_format = None

        if not file_format:
            file_format = destination.rsplit('.', 1)[-1]

        if destination:
            if file_format not in formats.values():
                file_format = 'png'
            if not destination.endswith('.' + file_format):
                destination += '.' + file_format
            img.save(destination, file_format, 0 if file_format == 'png' else 90)
        self.reject()
Exemple #2
0
    def onDictyExpressLink(self, link):
        if not self.data:
            return

        selectedIndexes = self.treeWidget.selectedIndexes()
        if not len(selectedIndexes):
            QMessageBox.information(self, "No gene ids selected",
                                    "Please select some genes and try again.")
            return
        model = self.treeWidget.model()
        mapToSource = model.mapToSource
        selectedRows = self.treeWidget.selectedIndexes()
        selectedRows = [mapToSource(index).row() for index in selectedRows]
        model = model.sourceModel()

        selectedGeneids = [self.row2geneinfo[row] for row in selectedRows]
        selectedIds = [self.geneinfo[i][0] for i in selectedGeneids]
        selectedIds = set(selectedIds)

        def fix(ddb):
            if ddb.startswith("DDB"):
                if not ddb.startswith("DDB_G"):
                    ddb = ddb.replace("DDB", "DDB_G")
                return ddb
            return None

        genes = [fix(gene) for gene in selectedIds if fix(gene)]
        url = str(link) % " ".join(genes)
        QDesktopServices.openUrl(QUrl(url))
Exemple #3
0
    def show_report(self):
        """
        Raise the report window.
        """
        self.create_report_html()
        from orangewidget.report.owreport import HAVE_REPORT

        report = self._get_designated_report_view()
        if not HAVE_REPORT and not report.have_report_warning_shown:
            QMessageBox.critical(
                None, "Missing Component",
                "Orange can not display reports, because your installation "
                "contains neither WebEngine nor WebKit.\n\n"
                "If you installed Orange with conda or pip, try using another "
                "PyQt distribution. "
                "If you installed Orange with a standard installer, please "
                "report this bug."
            )
            report.have_report_warning_shown = True

        # Should really have a signal `report_ready` or similar to decouple
        # the implementations.
        report.make_report(self)
        report.show()
        report.raise_()
def track_user_stats():

    reply = get_usage_track_conf()

    if reply=='ask later':

        m = QMessageBox(
            QMessageBox.Question,
            "User tracking",
            "Do you give us permission to track which country you are from and how many times you use this application? " \
            "This will contribute to the support of this software.",
            QMessageBox.Yes | QMessageBox.No | QMessageBox.NoRole
        )
        ask_later_btn = m.addButton("Ask me later", QMessageBox.NoRole)
        m.setEscapeButton(ask_later_btn)
        reply = m.exec_()

        if reply == QMessageBox.No:
            set_usage_track_conf('no-track')

        elif reply == QMessageBox.Yes:
            set_usage_track_conf('track')
            reply = 'track'

        elif reply == QMessageBox.NoButton:
            set_usage_track_conf('ask later')

    if reply=='track':
        register_access()
Exemple #5
0
    def __export(self):
        """Export annotations to a file."""

        try:

            if conf.PYFORMS_DIALOGS_OPTIONS:
                filename, ffilter = QFileDialog.getSaveFileName(
                    parent=self,
                    caption="Export annotations file",
                    directory="untitled.csv",
                    filter="CSV Files (*.csv);;CSV Matrix Files (*.csv)",
                    options=conf.PYFORMS_DIALOGS_OPTIONS)
            else:
                filename, ffilter = QFileDialog.getSaveFileName(
                    parent=self,
                    caption="Export annotations file",
                    directory="untitled.csv",
                    filter="CSV Files (*.csv);;CSV Matrix Files (*.csv)")

            filename = str(filename)
            ffilter = str(ffilter)
            if filename != "":
                with open(filename, 'w') as csvfile:
                    spamwriter = csv.writer(csvfile, dialect='excel')
                    if ffilter == 'CSV Files (*.csv)':
                        self._time.export_events_to_csvwriter(spamwriter)
                    elif ffilter == 'CSV Matrix Files (*.csv)':
                        self._time.exportmatrix_events_to_csvwriter(spamwriter)

        except Exception as e:
            traceback.print_exc()
            m = QMessageBox(QMessageBox.Critical, 'Error', str(e))
            m.exec_()
Exemple #6
0
def message(icon, text, title=None, informative_text=None, details=None,
            buttons=None, default_button=None, exc_info=False, parent=None):
    """Show a message helper function.
    """
    if title is None:
        title = "Message"
    if not text:
        text = "I am neither a postman nor a doctor."

    if buttons is None:
        buttons = QMessageBox.Ok

    if details is None and exc_info:
        details = traceback.format_exc(limit=20)

    mbox = QMessageBox(icon, title, text, buttons, parent)

    if informative_text:
        mbox.setInformativeText(informative_text)

    if details:
        mbox.setDetailedText(details)
        dtextedit = mbox.findChild(QTextEdit)
        if dtextedit is not None:
            dtextedit.setWordWrapMode(QTextOption.NoWrap)

    if default_button is not None:
        mbox.setDefaultButton(default_button)

    return mbox.exec()
Exemple #7
0
def save_plot(data, file_formats, filename=""):
    _LAST_DIR_KEY = "directories/last_graph_directory"
    _LAST_FILTER_KEY = "directories/last_graph_filter"
    settings = QSettings()
    start_dir = settings.value(_LAST_DIR_KEY, filename)
    if not start_dir or \
            (not os.path.exists(start_dir) and
             not os.path.exists(os.path.split(start_dir)[0])):
        start_dir = os.path.expanduser("~")
    last_filter = settings.value(_LAST_FILTER_KEY, "")
    filename, writer, filter = \
        filedialogs.get_file_name(start_dir, last_filter, file_formats)
    if not filename:
        return
    try:
        writer.write(filename, data)
    except Exception as e:
        mb = QMessageBox(
            None,
            windowTitle="Error",
            text='Error occurred while saving file "{}": {}'.format(filename, e),
            detailedText=traceback.format_exc(),
            icon=QMessageBox.Critical)
        mb.exec_()
    else:
        settings.setValue(_LAST_DIR_KEY, os.path.split(filename)[0])
        settings.setValue(_LAST_FILTER_KEY, filter)
Exemple #8
0
 def copy_to_clipboard(self):
     img = self.get_selection()
     if img.isNull():
         QMessageBox.critical(self, self.tr('Error'), self.tr('No image was selected!'))
         return
     QApplication.clipboard().setPixmap(img)
     self.reject()
Exemple #9
0
    def onDictyExpressLink(self, link):
        if not self.data:
            return

        selectedIndexes = self.treeWidget.selectedIndexes()
        if not len(selectedIndexes):
            QMessageBox.information(
                self, "No gene ids selected",
                "Please select some genes and try again."
            )
            return
        model = self.treeWidget.model()
        mapToSource = model.mapToSource
        selectedRows = self.treeWidget.selectedIndexes()
        selectedRows = [mapToSource(index).row() for index in selectedRows]
        model = model.sourceModel()

        selectedGeneids = [self.row2geneinfo[row] for row in selectedRows]
        selectedIds = [self.geneinfo[i][0] for i in selectedGeneids]
        selectedIds = set(selectedIds)

        def fix(ddb):
            if ddb.startswith("DDB"):
                if not ddb.startswith("DDB_G"):
                    ddb = ddb.replace("DDB", "DDB_G")
                return ddb
            return None

        genes = [fix(gene) for gene in selectedIds if fix(gene)]
        url = str(link) % " ".join(genes)
        QDesktopServices.openUrl(QUrl(url))
Exemple #10
0
def save_plot(data, file_formats, filename=""):
    _LAST_DIR_KEY = "directories/last_graph_directory"
    _LAST_FILTER_KEY = "directories/last_graph_filter"
    settings = QSettings()
    start_dir = settings.value(_LAST_DIR_KEY, filename)
    if not start_dir or \
            (not os.path.exists(start_dir) and
             not os.path.exists(os.path.split(start_dir)[0])):
        start_dir = os.path.expanduser("~")
    last_filter = settings.value(_LAST_FILTER_KEY, "")
    filename, writer, filter = \
        filedialogs.open_filename_dialog_save(start_dir, last_filter, file_formats)
    if not filename:
        return
    try:
        writer.write(filename, data)
    except OSError as e:
        mb = QMessageBox(
            None,
            windowTitle="Error",
            text='Error occurred while saving file "{}": {}'.format(filename, e),
            detailedText=traceback.format_exc(),
            icon=QMessageBox.Critical)
        mb.exec_()
    else:
        settings.setValue(_LAST_DIR_KEY, os.path.split(filename)[0])
        settings.setValue(_LAST_FILTER_KEY, filter)
Exemple #11
0
    def reset_widget_settings(self):
        mb = QMessageBox(
            self,
            windowTitle="Clear settings",
            text="Orange needs to be restarted for the changes to take effect.",
            icon=QMessageBox.Information,
            informativeText="Press OK to close Orange now.",
            standardButtons=QMessageBox.Ok | QMessageBox.Cancel,
        )
        res = mb.exec()
        if res == QMessageBox.Ok:
            # Touch a finely crafted file inside the settings directory.
            # The existence of this file is checked by the canvas main
            # function and is deleted there.
            from orangewidget.settings import widget_settings_dir
            dirname = widget_settings_dir()
            try:
                os.makedirs(dirname, exist_ok=True)
            except (FileExistsError, PermissionError):
                return
            with open(os.path.join(dirname, "DELETE_ON_START"), "a"):
                pass

            if not self.close():
                QMessageBox(
                    self,
                    text=
                    "Settings will still be reset at next application start",
                    icon=QMessageBox.Information).exec()
Exemple #12
0
    def question(self, msg, title=None, buttons=['no', 'yes']):
        btns = None
        for btn in buttons:
            if btn.lower() == 'cancel':
                b = QMessageBox.Cancel
            elif btn.lower() == 'no':
                b = QMessageBox.No
            elif btn.lower() == 'yes':
                b = QMessageBox.Yes
            elif btn.lower() == 'no_all':
                b = QMessageBox.NoToAll
            elif btn.lower() == 'yes_all':
                b = QMessageBox.YesToAll

            if btns is None:
                btns = b
            else:
                btns |= b

        m = QMessageBox(QMessageBox.Question, title, msg, btns)
        reply = m.exec_()

        if reply == QMessageBox.Cancel:
            return 'cancel'
        elif reply == QMessageBox.No:
            return 'no'
        elif reply == QMessageBox.Yes:
            return 'yes'
        elif reply == QMessageBox.NoToAll:
            return 'no_all'
        elif reply == QMessageBox.YesToAll:
            return 'yes_all'

        return None
    def browse_files(self, in_demos=False):
        if in_demos:
            start_file = get_sample_datasets_dir()
            if not os.path.exists(start_file):
                QMessageBox.information(
                    None, "File",
                    "Cannot find the directory with documentation data sets")
                return
        else:
            start_file = self.last_path() or os.path.expanduser("~/")

        filenames = QFileDialog.getOpenFileNames(self,
                                                 'Open Multiple Data Files',
                                                 start_file, self.dlg_formats)

        if isinstance(filenames, tuple):  # has a file description
            filenames = filenames[0]

        if not filenames:
            return

        for f in filenames:
            self.add_path(f)
            self.lb.addItem(f)

        self._update_sheet_combo()
        self.load_data()
    def ask_save_report(self):
        """
        Ask whether to save the report or not.
        Returns:
            `QDialog.Rejected` if user cancels, `QDialog.Accepted` otherwise
        """
        workflow = self.current_document().scheme()
        if not isinstance(workflow, WidgetsScheme) or not workflow.has_report():
            return QDialog.Accepted

        report = workflow.report_view()
        if not report.is_changed():
            return QDialog.Accepted

        mBox = QMessageBox(
            self,
            windowTitle="Report window",
            icon=QMessageBox.Question,
            text="The report contains unsaved changes.",
            informativeText="Would you like to save the report?",
            standardButtons=QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel,
        )
        mBox.setDefaultButton(QMessageBox.Save)
        answ = mBox.exec()
        if answ == QMessageBox.Cancel:
            return QDialog.Rejected
        if answ == QMessageBox.Save:
            return report.save_report()
        return QDialog.Accepted
Exemple #15
0
    def browse_file(self, in_demos=False):
        if in_demos:
            start_file = get_sample_datasets_dir()
            if not os.path.exists(start_file):
                QMessageBox.information(
                    None,
                    "File",
                    "Cannot find the directory with documentation datasets",
                )
                return
        else:
            start_file = self.last_path() or os.path.expanduser("~/")

        readers = [
            f for f in FileFormat.formats
            if getattr(f, "read", None) and getattr(f, "EXTENSIONS", None)
        ]
        filename, reader, _ = open_filename_dialog(start_file, None, readers)
        if not filename:
            return
        self.add_path(filename)
        if reader is not None:
            self.recent_paths[0].file_format = reader.qualified_name()

        self.source = self.LOCAL_FILE
        self.load_data()
Exemple #16
0
    def _parse_var_defs(self, js):
        if not isinstance(js, dict) or set(js) != {"categorical", "numeric"}:
            raise InvalidFileFormat
        try:
            renames = {
                var_name: desc["rename"]
                for repo in js.values() for var_name, desc in repo.items()
                if "rename" in desc
            }
        # js is an object coming from json file that can be manipulated by
        # the user, so there are too many things that can go wrong.
        # Catch all exceptions, therefore.
        except Exception as exc:
            raise InvalidFileFormat from exc
        if not all(isinstance(val, str)
                   for val in chain(renames, renames.values())):
            raise InvalidFileFormat
        renamed_vars = {
            renames.get(desc.var.name, desc.var.name)
            for desc in chain(self.disc_descs, self.cont_descs)
        }
        if len(renamed_vars) != len(self.disc_descs) + len(self.cont_descs):
            QMessageBox.warning(
                self,
                "Duplicated variable names",
                "Variables will not be renamed due to duplicated names.")
            for repo in js.values():
                for desc in repo.values():
                    desc.pop("rename", None)

        # First, construct all descriptions; assign later, after we know
        # there won't be exceptions due to invalid file format
        both_descs = []
        warnings = []
        for old_desc, repo, desc_type in (
                (self.disc_descs, "categorical", DiscAttrDesc),
                (self.cont_descs, "numeric", ContAttrDesc)):
            var_by_name = {desc.var.name: desc.var for desc in old_desc}
            new_descs = {}
            for var_name, var_data in js[repo].items():
                var = var_by_name.get(var_name)
                if var is None:
                    continue
                # This can throw InvalidFileFormat
                new_descs[var_name], warn = desc_type.from_dict(var, var_data)
                warnings += warn
            both_descs.append(new_descs)

        self.disc_descs = [both_descs[0].get(desc.var.name, desc)
                           for desc in self.disc_descs]
        self.cont_descs = [both_descs[1].get(desc.var.name, desc)
                           for desc in self.cont_descs]
        if warnings:
            QMessageBox.warning(
                self, "Invalid definitions", "\n".join(warnings))

        self.disc_model.set_data(self.disc_descs)
        self.cont_model.set_data(self.cont_descs)
        self.unconditional_commit()
 def __interpolate_btn_event(self): 
     #store a temporary path for interpolation visualization
     if len(self._sel_pts) >= 2:
         mode = None if self._interpolation_mode.value=='Auto' else self._interpolation_mode.value        #store a temporary path for interpolation visualization
         self.interpolate_range( self._sel_pts[0], self._sel_pts[-1], interpolation_mode=mode)
         self.mainwindow._player.refresh()
     else:
         QMessageBox.about(self, "Error", "You need to select 2 frames.")
	def __derivate_data(self):
		for i in range(1, len(self)):
			a = self[i-1]
			b = self[i]
			if a is not None and b is not None:
				self._values[i-1] = b-a
			else:
				self._values[i-1] = 0
		QMessageBox.about(self, "Info", "Operation complete.")
Exemple #19
0
 def cleanLine(self, track_index=None):
     if track_index is not None or self._selected is not None:
         track_index = track_index if track_index is not None else self._selected.track
         if len(self._tracks) > track_index:
             self._tracks[track_index].clear()
         self._selected = None
         self.repaint()
     else:
         QMessageBox.about(self, "Error", "You must select a timebar first")
         return
    def save_project(self, project_path=None):
        try:
            if project_path is None:
                project_path = QFileDialog.getExistingDirectory(self, "Select the project directory")

            if project_path is not None and str(project_path)!='':
                project_path = str(project_path)
                self.save({}, project_path)
        except Exception as e:
            QMessageBox.critical(self, "Error", str(e))
Exemple #21
0
 def share_clipboard(self):
     mime = QApplication.clipboard().mimeData()
     try:
         wnd = ShareDialog(self, mime=mime)
     except ValueError as e:
         QMessageBox.critical(self, self.tr('Error'), str(e))
         return
     else:
         wnd.show()
         wnd.exec_()
Exemple #22
0
def show_survey():
    # If run for the first time, open a browser tab with a survey
    settings = QSettings()
    show_survey = settings.value("startup/show-survey", True, type=bool)
    if show_survey:
        question = QMessageBox(
            QMessageBox.Question, 'Orange Survey',
            'We would like to know more about how our software is used.\n\n'
            'Would you care to fill our short 1-minute survey?',
            QMessageBox.Yes | QMessageBox.No)
        question.setDefaultButton(QMessageBox.Yes)
        later = question.addButton('Ask again later', QMessageBox.NoRole)
        question.setEscapeButton(later)

        def handle_response(result):
            if result == QMessageBox.Yes:
                success = QDesktopServices.openUrl(
                    QUrl("https://orange.biolab.si/survey/short.html"))
                settings.setValue("startup/show-survey", not success)
            else:
                settings.setValue("startup/show-survey",
                                  result != QMessageBox.No)

        question.finished.connect(handle_response)
        question.show()
        return question
 def __del_path_btn_event(self): #store a temporary path for interpolation visualization
     if len(self._sel_pts) == 2:
         reply = QMessageBox.question(self, 'Confirmation',
                                            "Are you sure you want to delete this path?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
         if reply == QMessageBox.Yes: #store a temporary path for interpolation visualization
             start, end = self._sel_pts[0], self._sel_pts[1]
             self.delete_range(start, end)
             self.calculate_tmp_interpolation()
             self.mainwindow._player.refresh()
     else:
         QMessageBox.about(self, "Error", "You need to select 2 frames.")
    def save_project(self, project_path=None):
        try:
            if project_path is None:
                project_path = QFileDialog.getExistingDirectory(
                    self, "Select the project directory")

            if project_path is not None and str(project_path) != '':
                project_path = str(project_path)
                self.save({}, project_path)
        except Exception as e:
            QMessageBox.critical(self, "Error", str(e))
Exemple #25
0
def message(icon, text, title=None, informative_text=None, details=None,
            buttons=None, default_button=None, exc_info=False, parent=None):
    """Show a message helper function.
    """
    if title is None:
        title = "Message"
    if not text:
        text = "I am neither a postman nor a doctor."

    if buttons is None:
        buttons = QMessageBox.Ok

    if details is None and exc_info:
        details = traceback.format_exc(limit=20)

    mbox = QMessageBox(icon, title, text, buttons, parent)

    if informative_text:
        mbox.setInformativeText(informative_text)

    if details:
        mbox.setDetailedText(details)

    if default_button is not None:
        mbox.setDefaultButton(default_button)

    return mbox.exec_()
Exemple #26
0
    def save_project(self, project_path=None):
        try:
            if project_path is None:
                dialog = QFileDialog()
                dialog.setLabelText(QFileDialog.Accept, 'Save')
                project_path = dialog.getExistingDirectory(
                    self, caption="Select the project directory to save")

            if project_path is not None and str(project_path) != '':
                project_path = str(project_path)
                self.save({}, project_path)
        except Exception as e:
            traceback.print_exc()
            QMessageBox.critical(self, "Error", str(e))
Exemple #27
0
def show_survey():
    # If run for the first time, open a browser tab with a survey
    settings = QSettings()
    show_survey = settings.value("startup/show-survey", True, type=bool)
    if show_survey:
        question = QMessageBox(
            QMessageBox.Question,
            'Orange Survey',
            'We would like to know more about how our software is used.\n\n'
            'Would you care to fill our short 1-minute survey?',
            QMessageBox.Yes | QMessageBox.No)
        question.setDefaultButton(QMessageBox.Yes)
        later = question.addButton('Ask again later', QMessageBox.NoRole)
        question.setEscapeButton(later)

        def handle_response(result):
            if result == QMessageBox.Yes:
                success = QDesktopServices.openUrl(
                    QUrl("https://orange.biolab.si/survey/short.html"))
                settings.setValue("startup/show-survey", not success)
            else:
                settings.setValue("startup/show-survey", result != QMessageBox.No)

        question.finished.connect(handle_response)
        question.show()
        return question
Exemple #28
0
    def __export_2_csv_matrix(self):
        QMessageBox.warning(
            self, "Important!",
            'Please note that this file cannot be imported after.')

        filename, _ = QFileDialog.getSaveFileName(
            parent=self,
            caption="Export matrix file",
            directory="untitled.csv",
            filter="CSV Files (*.csv)",
            options=QFileDialog.DontUseNativeDialog)
        if filename != "":
            with open(filename, 'w') as csvfile:
                spamwriter = csv.writer(csvfile, dialect='excel')
                self._time.exportmatrix_events_to_csvwriter(spamwriter)
Exemple #29
0
        def message_restart(parent):
            icon = QMessageBox.Information
            buttons = QMessageBox.Ok | QMessageBox.Cancel
            title = 'Information'
            text = 'Orange needs to be restarted for the changes to take effect.'

            msg_box = QMessageBox(icon, title, text, buttons, parent)
            msg_box.setDefaultButton(QMessageBox.Ok)
            msg_box.setInformativeText('Press OK to close Orange now.')

            msg_box.button(QMessageBox.Cancel).setText('Close later')
            return msg_box.exec_()
Exemple #30
0
 def acceptChanges(self):
     state = self.getCurrentState()
     oldState = self.colorSchemas[self.selectedSchemaIndex][1]
     if state == oldState:
         QDialog.accept(self)
     else:
         # if we change the default schema, we must save it under a new name
         if self.colorSchemas[self.selectedSchemaIndex][0] == "Default":
             if (QMessageBox.information(
                     self,
                     "Question",
                     "The color schema has changed. Save?",
                     QMessageBox.Yes | QMessageBox.Discard,
             ) == QMessageBox.Discard):
                 QDialog.reject(self)
             else:
                 self.selectedSchemaIndex = self.schemaCombo.count() - 1
                 self.schemaCombo.setCurrentIndex(self.selectedSchemaIndex)
                 self.paletteSelected()
                 QDialog.accept(self)
         # simply save the new users schema
         else:
             self.colorSchemas[self.selectedSchemaIndex] = [
                 self.colorSchemas[self.selectedSchemaIndex][0],
                 state,
             ]
             QDialog.accept(self)
Exemple #31
0
 def __remove_current_track_evt(self):
     reply = QMessageBox.question(
         self, 'Confirm',
         "Are you sure you want to remove the row and its events?",
         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
     if reply == QMessageBox.Yes:
         self._time.remove_selected_track()
 def __cleanLine(self):
     reply = QMessageBox.question(
         self, 'Confirm',
         "Are you sure you want to clean all the events on this track?",
         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
     if reply == QMessageBox.Yes:
         self._time.cleanLine(self._time.current_mouseover_track)
Exemple #33
0
        def get_save_filename(self):  # pragma: no cover
            if sys.platform == "darwin":
                def remove_star(filt):
                    return filt.replace(" (*.", " (.")
            else:
                def remove_star(filt):
                    return filt

            no_ext_filters = {remove_star(f): f for f in self._valid_filters()}
            filename = self._initial_start_dir()
            while True:
                dlg = QFileDialog(
                    None, "Save File", filename, ";;".join(no_ext_filters))
                dlg.setAcceptMode(dlg.AcceptSave)
                dlg.selectNameFilter(remove_star(self._default_valid_filter()))
                dlg.setOption(QFileDialog.DontConfirmOverwrite)
                if dlg.exec() == QFileDialog.Rejected:
                    return "", ""
                filename = dlg.selectedFiles()[0]
                selected_filter = no_ext_filters[dlg.selectedNameFilter()]
                filename = self._replace_extension(
                    filename, self._extension_from_filter(selected_filter))
                if not os.path.exists(filename) or QMessageBox.question(
                        self, "Overwrite file?",
                        f"File {os.path.split(filename)[1]} already exists.\n"
                        "Overwrite?") == QMessageBox.Yes:
                    return filename, selected_filter
Exemple #34
0
        def get_save_filename(self):  # pragma: no cover
            if sys.platform == "darwin":

                def remove_star(filt):
                    return filt.replace(" (*.", " (.")
            else:

                def remove_star(filt):
                    return filt

            no_ext_filters = {remove_star(f): f for f in self.valid_filters()}
            filename = self.initial_start_dir()
            while True:
                dlg = QFileDialog(None, "Save File", filename,
                                  ";;".join(no_ext_filters))
                dlg.setAcceptMode(dlg.AcceptSave)
                dlg.selectNameFilter(remove_star(self.default_valid_filter()))
                dlg.setOption(QFileDialog.DontConfirmOverwrite)
                if dlg.exec() == QFileDialog.Rejected:
                    return "", ""
                filename = dlg.selectedFiles()[0]
                selected_filter = no_ext_filters[dlg.selectedNameFilter()]
                filename = self._replace_extension(
                    filename, self._extension_from_filter(selected_filter))
                if not os.path.exists(filename) or QMessageBox.question(
                        self, "Overwrite file?",
                        f"File {os.path.split(filename)[1]} already exists.\n"
                        "Overwrite?") == QMessageBox.Yes:
                    return filename, selected_filter
def compare_versions(latest):
    current = current_version()
    version = pkg_resources.parse_version
    if version(latest) <= version(current):
        return
    question = QMessageBox(QMessageBox.Information,
                           UPDATE_AVAILABLE_TITLE,
                           UPDATE_AVAILABLE_MESSAGE.format(
                               current_version=current, latest_version=latest),
                           textFormat=Qt.RichText)
    ok = question.addButton('Download Now', question.AcceptRole)
    question.setDefaultButton(ok)
    question.addButton('Remind Later', question.RejectRole)
    question.finished.connect(lambda: question.clickedButton() == ok and
                              QDesktopServices.openUrl(QUrl(DOWNLOAD_URL)))
    question.show()
Exemple #36
0
    def browse_file(self, in_demos=False):
        if in_demos:
            start_file = get_sample_datasets_dir()
            if not os.path.exists(start_file):
                QMessageBox.information(
                    None, "File",
                    "Cannot find the directory with documentation datasets")
                return
        else:
            start_file = self.last_path() or os.path.expanduser("~/")

        filename, _ = QFileDialog.getOpenFileName(
            self, 'Open Distance File', start_file, "(*.dst)")
        if not filename:
            return
        self.add_path(filename)
        self.open_file()
Exemple #37
0
    def load(self):
        fname, _ = QFileDialog.getOpenFileName(
            self, "File name", self._start_dir(),
            "Variable definitions (*.colors)")
        if not fname:
            return

        try:
            with open(fname) as f:
                js = json.load(f)  #: dict
                self._parse_var_defs(js)
        except IOError:
            QMessageBox.critical(self, "File error", "File cannot be opened.")
            return
        except (json.JSONDecodeError, InvalidFileFormat):
            QMessageBox.critical(self, "File error", "Invalid file format.")
            return
Exemple #38
0
    def __open_track_properties_evt(self):
        """
        This controls makes possible the edition of a track in the
        timeline, based on the position of the mouse.

        Updates:
        - Track label
        - Track default color
        """
        current_track = self._time.current_mouseover_track
        parent = self._time

        # Tracks info dict and index
        i = current_track

        # Save current default color to override with selected track color
        timeline_default_color = parent.color
        try:
            parent.color = self._time._tracks[current_track].color
        except Exception as e:
            error_message = ("You tried to edit an empty track.", "\n",
                             "Initialize it by creating an event first.")
            QMessageBox.warning(parent, "Attention!", "".join(error_message))
            return e

        # Create dialog
        dialog = TimelinePopupWindow(parent, i)
        dialog.setModal(True)  # to disable main application window

        # If dialog is accepted, update dict info
        if dialog._ui.exec_() == dialog.Accepted:
            # Update label
            if dialog.behavior is not None:
                self._time._tracks[i].title = dialog.behavior

            # Update color
            if self._time._tracks[i].color != dialog.color:
                for delta in self._time._tracks[i].events:
                    delta.color = dialog.color
                self._time._tracks[i].color = dialog.color
            self._time.repaint()
        else:
            pass

        # Restore timeline default color
        parent.color = timeline_default_color
Exemple #39
0
 def compare_versions(latest):
     if LooseVersion(latest) <= LooseVersion(current):
         return
     question = QMessageBox(
         QMessageBox.Information,
         'Orange Update Available',
         'A newer version of Orange is available.<br><br>'
         '<b>Current version:</b> {}<br>'
         '<b>Latest version:</b> {}'.format(current, latest),
         textFormat=Qt.RichText)
     ok = question.addButton('Download Now', question.AcceptRole)
     question.setDefaultButton(ok)
     question.addButton('Remind Later', question.RejectRole)
     question.finished.connect(
         lambda: question.clickedButton() == ok and QDesktopServices.
         openUrl(QUrl("https://orange.biolab.si/download/")))
     question.show()
    def browse_file(self, in_demos=False):
        if in_demos:
            start_file = get_sample_datasets_dir()
            if not os.path.exists(start_file):
                QMessageBox.information(
                    None, "File",
                    "Cannot find the directory with documentation data sets")
                return
        else:
            start_file = self.last_path() or os.path.expanduser("~/")

        filename, _ = QFileDialog.getOpenFileName(
            self, 'Open Distance File', start_file, "(*.dst)")
        if not filename:
            return
        self.add_path(filename)
        self.open_file()
Exemple #41
0
    def browse_file(self, in_demos=False):
        if in_demos:
            start_file = get_sample_datasets_dir()
            if not os.path.exists(start_file):
                QMessageBox.information(
                    None, "File",
                    "Cannot find the directory with documentation data sets")
                return
        else:
            start_file = self.last_path() or os.path.expanduser("~/")

        filename, _ = QFileDialog.getOpenFileName(
            self, 'Open Orange Data File', start_file, dialog_formats())
        if not filename:
            return
        self.add_path(filename)
        self.source = self.LOCAL_FILE
        self.load_data()
Exemple #42
0
	def value(self, value):
		self.form.setUpdatesEnabled(False)
		if value is None: 
			self.stop()
			self.videoControl.setEnabled(False)
			self.refresh()
		self._video_widget.reset()

		if value == 0:
			self._value = cv2.VideoCapture(0)
		elif isinstance(value, str) and value:

			open_multiplefiles = self._multiple_files

			if open_multiplefiles:
				open_multiplefiles = len(MultipleVideoCapture.search_files(value))>0

			if open_multiplefiles:
				msg = "Multiple files were found with the same name, do you wish to combine then in a single video?\n\n"
				for filepath in MultipleVideoCapture.search_files(value):
					msg += "- {filename}\n".format(filename=os.path.basename(filepath))

				reply = QMessageBox(
					QMessageBox.Question,
					'Open multiple files',
					msg,
					QMessageBox.No | QMessageBox.Yes
				).exec_()

				if reply == QMessageBox.Yes:
					open_multiplefiles = True
				else:
					open_multiplefiles = False

			if open_multiplefiles:
				self._value = MultipleVideoCapture(value)
			else:
				self._value = cv2.VideoCapture(value)
		else:
			self._value = value

		if self._value and value != 0:
			self.videoProgress.setMinimum(0)
			self.videoProgress.setValue(0)
			self.videoProgress.setMaximum(
				self._value.get(7))
			self.videoFrames.setMinimum(0)
			self.videoFrames.setValue(0)
			self.videoFrames.setMaximum(
				self._value.get(7))

		if self._value:
			self.videoControl.setEnabled(True)

		self.refresh()
		self.form.setUpdatesEnabled(True)
Exemple #43
0
 def register_hotkeys(self):
     if self._hotkey is not None:
         self.rebuild_menu()
         self._hotkey.unregister(winid=self.winId())
         hotkey_bindings = {
             settings['hotkey/clipboard']: (self.share_clipboard, self._action_clip),
             settings['hotkey/screenshot']: (self.capture_screen, self._action_screen)
         }
         for hotkey, (callback, action) in hotkey_bindings.items():
             if hotkey:
                 if self._hotkey.register(hotkey, callback, self.winId()):
                     sequence = QKeySequence(hotkey) if hotkey else QKeySequence()
                     action.setShortcut(sequence)
                 else:
                     QMessageBox.critical(self, 'Error', 'Could not bind {} hotkey!\n'
                                                         'Key combination {} is probably already in use.'
                                          .format(const.APP_NAME, hotkey))
     else:
         qDebug('Hotkeys are not supported on this platform')
Exemple #44
0
        def message_restart(parent):
            icon = QMessageBox.Information
            buttons = QMessageBox.Ok | QMessageBox.Cancel
            title = 'Information'
            text = 'Orange needs to be restarted for the changes to take effect.'

            msg_box = QMessageBox(icon, title, text, buttons, parent)
            msg_box.setDefaultButton(QMessageBox.Ok)
            msg_box.setInformativeText('Press OK to close Orange now.')

            msg_box.button(QMessageBox.Cancel).setText('Close later')
            return msg_box.exec_()
Exemple #45
0
    def browse_file(self, in_demos=False):
        if in_demos:
            start_file = get_sample_datasets_dir()
            if not os.path.exists(start_file):
                QMessageBox.information(
                    None, "File",
                    "Cannot find the directory with documentation datasets")
                return
        else:
            start_file = self.last_path() or os.path.expanduser("~/")

        readers = [f for f in FileFormat.formats
                   if getattr(f, 'read', None) and getattr(f, "EXTENSIONS", None)]
        filename, reader, _ = open_filename_dialog(start_file, None, readers)
        if not filename:
            return
        self.add_path(filename)
        if reader is not None:
            self.recent_paths[0].file_format = reader.qualified_name()

        self.source = self.LOCAL_FILE
        self.load_data()
Exemple #46
0
def save_plot(data, file_formats, filename=""):
    _LAST_DIR_KEY = "directories/last_graph_directory"
    _LAST_FILTER_KEY = "directories/last_graph_filter"
    settings = QSettings()
    start_dir = settings.value(_LAST_DIR_KEY, filename)
    if not start_dir or \
            (not os.path.exists(start_dir) and
             not os.path.exists(os.path.split(start_dir)[0])):
        start_dir = os.path.expanduser("~")
    last_filter = settings.value(_LAST_FILTER_KEY, "")
    filename, writer, filter = \
        filedialogs.get_file_name(start_dir, last_filter, file_formats)
    if not filename:
        return
    try:
        writer.write(filename, data)
    except Exception as e:
        QMessageBox.critical(
            None, "Error", 'Error occurred while saving file "{}": {}'.format(filename, e))
    else:
        settings.setValue(_LAST_DIR_KEY, os.path.split(filename)[0])
        settings.setValue(_LAST_FILTER_KEY, filter)
Exemple #47
0
 def compare_versions(latest):
     version = pkg_resources.parse_version
     if version(latest) <= version(current):
         return
     question = QMessageBox(
         QMessageBox.Information,
         'Orange Update Available',
         'A newer version of Orange is available.<br><br>'
         '<b>Current version:</b> {}<br>'
         '<b>Latest version:</b> {}'.format(current, latest),
         textFormat=Qt.RichText)
     ok = question.addButton('Download Now', question.AcceptRole)
     question.setDefaultButton(ok)
     question.addButton('Remind Later', question.RejectRole)
     question.finished.connect(
         lambda:
         question.clickedButton() == ok and
         QDesktopServices.openUrl(QUrl("https://orange.biolab.si/download/")))
     question.show()
def start():

	try:
		pyforms.start_app(
			VideoAnnotator,
			geometry=conf.MAIN_WINDOW_GEOMETRY
		)

	except Exception as e:
		report = traceback.format_exc()

		app = QApplication(sys.argv)
		m = QMessageBox(
			QMessageBox.Question,
			"Send report",
			"<h2>Would you like to send us a report of the bug?</h2>"
			"This will help us improving the software."
			"<p>{bug}</p>".format( bug=str(e) ),
			QMessageBox.Yes | QMessageBox.No
		)
		reply = m.exec_()

		if reply==QMessageBox.Yes:
			try:
				app_id = conf.USERSTATS_APP_ID
				reg_id = get_mac()
				os_name = platform.platform()
				version = pythonvideoannotator.__version__

				data = {'app-id': app_id, 'reg-id': reg_id, 'os-name' : os_name, 'version': version, 'report': report}
				url = "{}/register-bug".format(conf.USERSTATS_URL)
				request = Request(url, urlencode(data).encode())
				urlopen(request).read().decode()
			except Exception as ex:
				print("Could not register new access", ex )

		exit()
		app.exec_()
Exemple #49
0
 def acceptChanges(self):
     state = self.getCurrentState()
     oldState = self.colorSchemas[self.selectedSchemaIndex][1]
     if state == oldState:
         QDialog.accept(self)
     else:
         # if we change the default schema, we must save it under a new name
         if self.colorSchemas[self.selectedSchemaIndex][0] == "Default":
             if QMessageBox.information(
                     self, 'Question',
                     'The color schema has changed. Save?',
                     QMessageBox.Yes | QMessageBox.Discard) == QMessageBox.Discard:
                 QDialog.reject(self)
             else:
                 self.selectedSchemaIndex = self.schemaCombo.count() - 1
                 self.schemaCombo.setCurrentIndex(self.selectedSchemaIndex)
                 self.paletteSelected()
                 QDialog.accept(self)
         # simply save the new users schema
         else:
             self.colorSchemas[self.selectedSchemaIndex] = \
                 [self.colorSchemas[self.selectedSchemaIndex][0], state]
             QDialog.accept(self)
Exemple #50
0
    def __init__(self, parent=None, *, mime=None, image=None):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self._backend = None
        self._backend_controls = {}
        self._label_anonymous = self.tr('Anonymous')
        self._label_select_login = self.tr('Select Login')
        self._available_backends = []

        data = None
        file_name = None
        if image:
            self._share_type = Bi.Image
            data = image
        elif mime:
            if mime.hasImage():
                self._share_type = Bi.Image
                data = mime.imageData()
            elif mime.hasUrls():
                urls = mime.urls()
                if len(urls) == 1:
                    file_path = os.path.realpath(urls[0].toLocalFile())
                    if not os.path.isfile(file_path):
                        raise ValueError(self.tr('Directories can not be shared'))
                    file_size = os.path.getsize(file_path)
                    file_name = os.path.basename(file_path)

                    if file_size > const.BIG_FILE_WARNING_SIZE:
                        file_name = os.path.basename(file_path)
                        nice_size = format_size(file_size)
                        result = QMessageBox.warning(self, self.tr('Warning'),
                                                     self.tr('File "{file_name}" {nice_size}.\n'
                                                             'Are you sure you want to continue?').format(**locals()),
                                                     QMessageBox.Yes | QMessageBox.Abort)
                        if result == QMessageBox.Abort:
                            QTimer.singleShot(0, self.reject)
                            return

                    if file_has_extension(file_path, ('png', 'jpg', 'jpeg', 'bmp', 'gif')):
                        image = QPixmap(file_path)
                    else:
                        image = None
                    if not image or image.isNull():
                        data = read_text_from_file(file_path)
                        if data:
                            self._share_type = Bi.Text
                        else:
                            self._share_type = Bi.File
                            data = file_path
                    else:
                        self._share_type = Bi.Image
                        data = image
                else:
                    raise ValueError(self.tr('Can not share more than one file'))

            elif mime.hasText():
                self._share_type = Bi.Text
                data = mime.text()
        else:
            raise RuntimeError()

        if not data:
            raise ValueError(self.tr('There is no content in your clipboard.\nCopy something in order to share it.'))

        if self._share_type == Bi.Image:
            if not file_name:
                file_name = '{}-{}.png'.format('screenshot' if image else 'image', int(time()))
            if data.width() > self.image_preview.width() or data.height() > self.image_preview.height():
                preview = data.scaled(self.image_preview.size(), Qt.KeepAspectRatio)
            else:
                preview = data
            if isinstance(preview, QImage):
                preview = QPixmap.fromImage(preview)
            self.image_preview.setPixmap(preview)
            self.preview_stack.setCurrentIndex(0)
            buf = QBuffer()
            data.save(buf, 'png', 100)
            data = buf.data().data()
        elif self._share_type == Bi.Text:
            if not file_name:
                file_name = 'file-{}.txt'.format(int(time()))
            self.text_preview.setPlainText(dedent_text_and_truncate(data, 128))
            self.preview_stack.setCurrentIndex(1)
        elif self._share_type == Bi.File:
            if not file_name:
                file_name = 'file-{}.bin'.format(int(time()))
            self.text_preview.setPlainText(self.tr('No preview available'))
            self.preview_stack.setCurrentIndex(1)

        self._file_name = file_name
        self._data = data

        self.populate_backends()

        self.share.pressed.connect(self.share_item)
        self.add_login.pressed.connect(self.on_add_login)
        self.logout.pressed.connect(self.logout_selected)
        self.login_list.currentIndexChanged.connect(self.select_login)

        min_height = self.backend_selector.minimumSizeHint().height()
        if os.name == 'nt':
            # On windows tab widget and font are rather small
            min_height -= 5
            for el in (self.add_login, self.login_list, self.logout, self.share):
                font = el.font()
                font.setPointSize(12)
                el.setFont(font)
            self.login_list.setFixedHeight(self.add_login.height() - 2)
        self.backend_selector.setFixedHeight(min_height)
        self.backend_selector.currentChanged.connect(self.select_backend)
        if self.backend_selector.height() < self.add_login.height():
            # Move tab widget down based on size of controls on the right. Makes widgets below seem to belong to the
            # selected tab.
            self.backend_selector.move(0, self.add_login.height() - self.backend_selector.height())

        self.resize(self.width(), 0)
        self.setWindowState((self.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive)
        self.raise_()
        self.activateWindow()
 def load(self, data, project_path=None):
     try:
         self._project.load(data, project_path)
     except FileNotFoundError as e:
         QMessageBox.critical(self, "Error", str(e))
Exemple #52
0
def main(argv=None):
    if argv is None:
        argv = sys.argv

    usage = "usage: %prog [options] [workflow_file]"
    parser = optparse.OptionParser(usage=usage)

    parser.add_option("--no-discovery",
                      action="store_true",
                      help="Don't run widget discovery "
                           "(use full cache instead)")
    parser.add_option("--force-discovery",
                      action="store_true",
                      help="Force full widget discovery "
                           "(invalidate cache)")
    parser.add_option("--clear-widget-settings",
                      action="store_true",
                      help="Remove stored widget setting")
    parser.add_option("--no-welcome",
                      action="store_true",
                      help="Don't show welcome dialog.")
    parser.add_option("--no-splash",
                      action="store_true",
                      help="Don't show splash screen.")
    parser.add_option("-l", "--log-level",
                      help="Logging level (0, 1, 2, 3, 4)",
                      type="int", default=1)
    parser.add_option("--style",
                      help="QStyle to use",
                      type="str", default=None)
    parser.add_option("--stylesheet",
                      help="Application level CSS style sheet to use",
                      type="str", default="orange.qss")
    parser.add_option("--qt",
                      help="Additional arguments for QApplication",
                      type="str", default=None)

    (options, args) = parser.parse_args(argv[1:])

    levels = [logging.CRITICAL,
              logging.ERROR,
              logging.WARN,
              logging.INFO,
              logging.DEBUG]

    # Fix streams before configuring logging (otherwise it will store
    # and write to the old file descriptors)
    fix_win_pythonw_std_stream()

    # Try to fix fonts on OSX Mavericks
    fix_osx_10_9_private_font()

    # File handler should always be at least INFO level so we need
    # the application root level to be at least at INFO.
    root_level = min(levels[options.log_level], logging.INFO)
    rootlogger = logging.getLogger(canvas.__name__)
    rootlogger.setLevel(root_level)

    # Initialize SQL query and execution time logger (in SqlTable)
    sql_level = min(levels[options.log_level], logging.INFO)
    make_sql_logger(sql_level)

    # Standard output stream handler at the requested level
    stream_hander = logging.StreamHandler()
    stream_hander.setLevel(level=levels[options.log_level])
    rootlogger.addHandler(stream_hander)

    log.info("Starting 'Orange Canvas' application.")

    qt_argv = argv[:1]

    if options.style is not None:
        qt_argv += ["-style", options.style]

    if options.qt is not None:
        qt_argv += shlex.split(options.qt)

    qt_argv += args

    log.debug("Starting CanvasApplicaiton with argv = %r.", qt_argv)
    app = CanvasApplication(qt_argv)

    # NOTE: config.init() must be called after the QApplication constructor
    config.init()

    clear_settings_flag = os.path.join(
        config.widget_settings_dir(), "DELETE_ON_START")

    if options.clear_widget_settings or \
            os.path.isfile(clear_settings_flag):
        log.info("Clearing widget settings")
        shutil.rmtree(
            config.widget_settings_dir(),
            ignore_errors=True)

    file_handler = logging.FileHandler(
        filename=os.path.join(config.log_dir(), "canvas.log"),
        mode="w"
    )

    file_handler.setLevel(root_level)
    rootlogger.addHandler(file_handler)

    # intercept any QFileOpenEvent requests until the main window is
    # fully initialized.
    # NOTE: The QApplication must have the executable ($0) and filename
    # arguments passed in argv otherwise the FileOpen events are
    # triggered for them (this is done by Cocoa, but QApplicaiton filters
    # them out if passed in argv)

    open_requests = []

    def onrequest(url):
        log.info("Received an file open request %s", url)
        open_requests.append(url)

    app.fileOpenRequest.connect(onrequest)

    settings = QSettings()

    stylesheet = options.stylesheet
    stylesheet_string = None

    if stylesheet != "none":
        if os.path.isfile(stylesheet):
            stylesheet_string = open(stylesheet, "rb").read()
        else:
            if not os.path.splitext(stylesheet)[1]:
                # no extension
                stylesheet = os.path.extsep.join([stylesheet, "qss"])

            pkg_name = canvas.__name__
            resource = "styles/" + stylesheet

            if pkg_resources.resource_exists(pkg_name, resource):
                stylesheet_string = \
                    pkg_resources.resource_string(pkg_name, resource).decode()

                base = pkg_resources.resource_filename(pkg_name, "styles")

                pattern = re.compile(
                    r"^\s@([a-zA-Z0-9_]+?)\s*:\s*([a-zA-Z0-9_/]+?);\s*$",
                    flags=re.MULTILINE
                )

                matches = pattern.findall(stylesheet_string)

                for prefix, search_path in matches:
                    QDir.addSearchPath(prefix, os.path.join(base, search_path))
                    log.info("Adding search path %r for prefix, %r",
                             search_path, prefix)

                stylesheet_string = pattern.sub("", stylesheet_string)

            else:
                log.info("%r style sheet not found.", stylesheet)

    # Add the default canvas_icons search path
    dirpath = os.path.abspath(os.path.dirname(canvas.__file__))
    QDir.addSearchPath("canvas_icons", os.path.join(dirpath, "icons"))

    canvas_window = CanvasMainWindow()
    canvas_window.setWindowIcon(config.application_icon())

    if stylesheet_string is not None:
        canvas_window.setStyleSheet(stylesheet_string)

    if not options.force_discovery:
        reg_cache = cache.registry_cache()
    else:
        reg_cache = None

    widget_discovery = qt.QtWidgetDiscovery(cached_descriptions=reg_cache)

    widget_registry = qt.QtWidgetRegistry()

    widget_discovery.found_category.connect(
        widget_registry.register_category
    )
    widget_discovery.found_widget.connect(
        widget_registry.register_widget
    )

    want_splash = \
        settings.value("startup/show-splash-screen", True, type=bool) and \
        not options.no_splash

    if want_splash:
        pm, rect = config.splash_screen()
        splash_screen = SplashScreen(pixmap=pm, textRect=rect)
        splash_screen.setFont(QFont("Helvetica", 12))
        color = QColor("#FFD39F")

        def show_message(message):
            splash_screen.showMessage(message, color=color)

        widget_discovery.discovery_start.connect(splash_screen.show)
        widget_discovery.discovery_process.connect(show_message)
        widget_discovery.discovery_finished.connect(splash_screen.hide)

    log.info("Running widget discovery process.")

    cache_filename = os.path.join(cache_dir(), "widget-registry.pck")
    if options.no_discovery:
        widget_registry = pickle.load(open(cache_filename, "rb"))
        widget_registry = qt.QtWidgetRegistry(widget_registry)
    else:
        widget_discovery.run(config.widgets_entry_points())
        # Store cached descriptions
        cache.save_registry_cache(widget_discovery.cached_descriptions)
        pickle.dump(WidgetRegistry(widget_registry),
                     open(cache_filename, "wb"))
    set_global_registry(widget_registry)
    canvas_window.set_widget_registry(widget_registry)
    canvas_window.show()
    canvas_window.raise_()

    want_welcome = \
        settings.value("startup/show-welcome-screen", True, type=bool) \
        and not options.no_welcome

    # Process events to make sure the canvas_window layout has
    # a chance to activate (the welcome dialog is modal and will
    # block the event queue, plus we need a chance to receive open file
    # signals when running without a splash screen)
    app.processEvents()

    app.fileOpenRequest.connect(canvas_window.open_scheme_file)

    if want_welcome and not args and not open_requests:
        canvas_window.welcome_dialog()

    elif args:
        log.info("Loading a scheme from the command line argument %r",
                 args[0])
        canvas_window.load_scheme(args[0])
    elif open_requests:
        log.info("Loading a scheme from an `QFileOpenEvent` for %r",
                 open_requests[-1])
        canvas_window.load_scheme(open_requests[-1].toLocalFile())

    # If run for the first time, open a browser tab with a survey
    show_survey = settings.value("startup/show-survey", True, type=bool)
    if show_survey:
        question = QMessageBox(
            QMessageBox.Question,
            'Orange Survey',
            'We would like to know more about how our software is used.\n\n'
            'Would you care to fill our short 1-minute survey?',
            QMessageBox.Yes | QMessageBox.No)
        question.setDefaultButton(QMessageBox.Yes)
        later = question.addButton('Ask again later', QMessageBox.NoRole)
        question.setEscapeButton(later)

        def handle_response(result):
            if result == QMessageBox.Yes:
                success = QDesktopServices.openUrl(
                    QUrl("http://orange.biolab.si/survey/short.html"));
                settings.setValue("startup/show-survey", not success)
            else:
                settings.setValue("startup/show-survey", result != QMessageBox.No)

        question.finished.connect(handle_response)
        question.show()

    # Tee stdout and stderr into Output dock
    log_view = canvas_window.log_view()

    stdout = TextStream()
    stdout.stream.connect(log_view.write)
    if sys.stdout:
        stdout.stream.connect(sys.stdout.write)
        stdout.flushed.connect(sys.stdout.flush)

    stderr = TextStream()
    error_writer = log_view.formated(color=Qt.red)
    stderr.stream.connect(error_writer.write)
    if sys.stderr:
        stderr.stream.connect(sys.stderr.write)
        stderr.flushed.connect(sys.stderr.flush)

    log.info("Entering main event loop.")
    try:
        with patch('sys.excepthook',
                   ExceptHook(stream=stderr, canvas=canvas_window,
                              handledException=handle_exception)),\
             patch('sys.stderr', stderr),\
             patch('sys.stdout', stdout):
            status = app.exec_()
    except BaseException:
        log.error("Error in main event loop.", exc_info=True)

    canvas_window.deleteLater()
    app.processEvents()
    app.flush()
    del canvas_window

    # Collect any cycles before deleting the QApplication instance
    gc.collect()

    del app
    return status
Exemple #53
0
def fix_extension(ext, format, suggested_ext, suggested_format):
    dlg = QMessageBox(
        QMessageBox.Warning,
        "Mismatching extension",
        "Extension '{}' does not match the chosen file format, {}.\n\n"
        "Would you like to fix this?".format(ext, format))
    role = QMessageBox.AcceptRole
    change_ext = \
        suggested_ext and \
        dlg.addButton("Change extension to " + suggested_ext, role)
    change_format =\
        suggested_format and \
        dlg.addButton("Save as " + suggested_format, role)
    cancel = dlg.addButton("Back", role)
    dlg.setEscapeButton(cancel)
    dlg.exec()
    if dlg.clickedButton() == cancel:
        return fix_extension.CANCEL
    elif dlg.clickedButton() == change_ext:
        return fix_extension.CHANGE_EXT
    elif dlg.clickedButton() == change_format:
        return fix_extension.CHANGE_FORMAT
Exemple #54
0
 def offerSave(self):
     if (Dirty and QMessageBox.question(self, "%s - Unsaved Changes" % AppName, "Save unsaved changes?", 
                                        QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes):
         self.save()
Exemple #55
0
    def get_table(self):
        curIdx = self.tablecombo.currentIndex()
        if curIdx <= 0:
            if self.database_desc:
                self.database_desc["Table"] = "(None)"
            self.data_desc_table = None
            return

        if self.tablecombo.itemText(curIdx) != "Custom SQL":
            self.table = self.tables[self.tablecombo.currentIndex()]
            self.database_desc["Table"] = self.table
            if "Query" in self.database_desc:
                del self.database_desc["Query"]
            what = self.table
        else:
            what = self.sql = self.sqltext.toPlainText()
            self.table = "Custom SQL"
            if self.materialize:
                import psycopg2
                if not self.materialize_table_name:
                    self.Error.connection(
                        "Specify a table name to materialize the query")
                    return
                try:
                    with self.backend.execute_sql_query("DROP TABLE IF EXISTS " +
                                                        self.materialize_table_name):
                        pass
                    with self.backend.execute_sql_query("CREATE TABLE " +
                                                        self.materialize_table_name +
                                                        " AS " + self.sql):
                        pass
                    with self.backend.execute_sql_query("ANALYZE " + self.materialize_table_name):
                        pass
                except (psycopg2.ProgrammingError, BackendError) as ex:
                    self.Error.connection(str(ex))
                    return

        try:
            table = SqlTable(dict(host=self.host,
                                  port=self.port,
                                  database=self.database,
                                  user=self.username,
                                  password=self.password),
                             what,
                             backend=type(self.backend),
                             inspect_values=False)
        except BackendError as ex:
            self.Error.connection(str(ex))
            return

        self.Error.connection.clear()

        sample = False

        if table.approx_len() > LARGE_TABLE and self.guess_values:
            confirm = QMessageBox(self)
            confirm.setIcon(QMessageBox.Warning)
            confirm.setText("Attribute discovery might take "
                            "a long time on large tables.\n"
                            "Do you want to auto discover attributes?")
            confirm.addButton("Yes", QMessageBox.YesRole)
            no_button = confirm.addButton("No", QMessageBox.NoRole)
            sample_button = confirm.addButton("Yes, on a sample",
                                              QMessageBox.YesRole)
            confirm.exec()
            if confirm.clickedButton() == no_button:
                self.guess_values = False
            elif confirm.clickedButton() == sample_button:
                sample = True

        self.Information.clear()
        if self.guess_values:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            if sample:
                s = table.sample_time(1)
                domain = s.get_domain(inspect_values=True)
                self.Information.data_sampled()
            else:
                domain = table.get_domain(inspect_values=True)
            QApplication.restoreOverrideCursor()
            table.domain = domain

        if self.download:
            if table.approx_len() > MAX_DL_LIMIT:
                QMessageBox.warning(
                    self, 'Warning', "Data is too big to download.\n"
                    "Consider using the Data Sampler widget to download "
                    "a sample instead.")
                self.download = False
            elif table.approx_len() > AUTO_DL_LIMIT:
                confirm = QMessageBox.question(
                    self, 'Question', "Data appears to be big. Do you really "
                                      "want to download it to local memory?",
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if confirm == QMessageBox.No:
                    self.download = False
        if self.download:
            table.download_data(MAX_DL_LIMIT)
            table = Table(table)

        return table