Ejemplo n.º 1
0
    def on_about(self):
        saved_state = self.state
        self.pause_game()

        dialog = AboutDialog(self)
        dialog.exec_()

        self.set_game_state(saved_state)
Ejemplo n.º 2
0
 def __init__(self, iface):
     # Save reference to the QGIS interface
     self.iface = iface
     # create our GUI dialog
     self.dlg = MultiEditDialog()
     self.dlga = AboutDialog()
     #initialization for select features
     self.turnedoffLayers = []
     self.selectList = []
     self.cLayer = None
     self.provider = None
     self.saved = False
     self.countchange = 0
     selectall = 0
Ejemplo n.º 3
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        # Set up the user interface from Designer.
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.loadDataDialog = QFileDialog()
        self.loadDataDialog.setFileMode(QFileDialog.DirectoryOnly)
        self.loadDataDialog.setOption(QFileDialog.ShowDirsOnly, True)
        self.loadDataDialog.setAcceptMode(QFileDialog.AcceptOpen)
        self.loadDataDialog.fileSelected.connect(self.directorySelected)

        self.ui.loadDataButton.clicked.connect(self.loadDataDialog.show)
        self.ui.calculateButton.clicked.connect(self.calculateClicked)
        self.ui.actionAbout.triggered.connect(self.actionAboutTriggered)

    @pyqtSlot(str)
    def directorySelected(self, dataDirectory):
        print("Selected data directory: {0}".format(dataDirectory))
        self.loadData(dataDirectory)

    def loadData(self, dataDirectory):
        print("Loading model with data from: {0}".format(dataDirectory))
        self.ui.loadDataButton.setEnabled(False)
        self.ui.statusLabel.setText("Loading model, please wait...")

        try:
            self.model = Model(dataDirectory)
        except Exception as ex:
            print("Model load error: {0}".format(ex))
            self.ui.statusLabel.setText(
                "Error occured during loading the model. Please, try again.")
            self.ui.statusLabel.setStyleSheet("color: red")
            self.ui.loadDataButton.setEnabled(True)
            return

        self.triggerModelLoaded()

        print("Model loaded successfully")

    def triggerModelLoaded(self):
        self.ui.statusLabel.setStyleSheet("color: orange")
        self.ui.statusLabel.setText(
            "Model loaded sucessfully. Now you can start calculations.")
        self.ui.loadDataButton.setEnabled(True)
        self.ui.calculateButton.setEnabled(True)

    @pyqtSlot()
    def calculateClicked(self):
        print("Running model")

        if self.ui.useSweepRadioButton.isChecked():
            algorithmType = Model.AlgorithmType.Sweep
        elif self.ui.useClarkeWrightRadioButton.isChecked():
            algorithmType = Model.AlgorithmType.ClarkeWright
        else:
            assert False, "Either Sweep or ClarkeWright should be checked"

        self.ui.loadDataButton.setEnabled(False)
        self.ui.calculateButton.setEnabled(False)
        self.ui.useSweepRadioButton.setEnabled(False)
        self.ui.useClarkeWrightRadioButton.setEnabled(False)
        self.ui.statusLabel.setText("Running model, please wait...")

        try:
            carsUsage, _ = self.model.run(algorithmType)
        except Exception as ex:
            print("Model run error: {0}".format(ex))
            self.ui.statusLabel.setText(
                "Error occured during running the model. Please, try again.")
            self.ui.statusLabel.setStyleSheet("color: red")
            self.ui.loadDataButton.setEnabled(True)
            self.ui.useSweepRadioButton.setEnabled(True)
            self.ui.useClarkeWrightRadioButton.setEnabled(True)
            raise

        self.ui.statusLabel.setText("Model calculated successfully!")
        self.ui.statusLabel.setStyleSheet("color: green")

        self.openResultsDialog(carsUsage)

    def openResultsDialog(self, modelResults):
        print("Opening results dialog")

        self.ui.inputDataDialog = InputDataDialog(self.model.data, self)

        self.ui.resultsDialog = ResultsDialog(self.model.data, modelResults,
                                              self)
        self.ui.resultsDialog.finished.connect(self.resultsDialogFinished)

        self.ui.inputDataDialog.show()
        self.ui.resultsDialog.show()

        print("Results dialog opened")

    @pyqtSlot()
    def resultsDialogFinished(self):
        self.triggerModelLoaded()
        self.ui.useSweepRadioButton.setEnabled(True)
        self.ui.useClarkeWrightRadioButton.setEnabled(True)

    @pyqtSlot()
    def actionAboutTriggered(self):
        self.aboutDialog = AboutDialog(self)
        self.aboutDialog.show()
Ejemplo n.º 4
0
 def __init__(self, iface):
     # Save reference to the QGIS interface
     self.iface = iface
     self.canvas = self.iface.mapCanvas()
     self.dlg = AboutDialog()
Ejemplo n.º 5
0
class MainWindow:
    def __init__(self):
        self.days = {}
        self.lock_signals = False

        # Determine the last opened file.
        self.xml_file_consumerdb = XML_FILE_CONSUMERDB
        self.gconf_client = gconf.client_get_default()
        val = self.gconf_client.get(GC_KEY_LAST_OPENED_FILE)
        if val:
            last_opened_file = val.get_string()
            if (last_opened_file and os.path.isfile(last_opened_file)):
                self.xml_file_consumerdb = last_opened_file

        # Lookup all widgets.
        gladefile = cfg["APP_SYSNAME"] + ".glade"
        callback = self.on_treeview_selection_changed
        self.xml = util.get_glade_xml(gladefile, "mainwindow")
        self.window = self.xml.get_widget('mainwindow')
        self.treeview = self.xml.get_widget('treeview_caleditor')
        self.treeview_selection = self.treeview.get_selection()
        self.treeview_selection_hd = self.treeview_selection.connect(
            "changed", callback)
        self.calendar = self.xml.get_widget('calendar')
        self.spinbutton_weight = self.xml.get_widget('spinbutton_weight')
        self.combobox_food = self.xml.get_widget('comboboxentry_food')
        self.comboboxentry_food = self.combobox_food.get_child()
        self.spinbutton_quantity = self.xml.get_widget('spinbutton_quantity')
        self.spinbutton_energy = self.xml.get_widget('spinbutton_energy')
        self.spinbutton_hour = self.xml.get_widget('spinbutton_hour')
        self.spinbutton_minute = self.xml.get_widget('spinbutton_minute')
        self.notebook_buttonbox = self.xml.get_widget('notebook_buttonbox')
        self.label_energy_sum = self.xml.get_widget('label_energy_sum')
        self.dialog_about = None
        self.xml.signal_autoconnect(self)

        # Init widgets.
        t = time.localtime(time.time())
        self.spinbutton_hour.set_value(t[3])
        self.spinbutton_minute.set_value(t[4])

        # Init the listview.
        self.model = gtk.ListStore(gobject.TYPE_PYOBJECT, gobject.TYPE_STRING,
                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
                                   gobject.TYPE_STRING, gobject.TYPE_STRING)

        renderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_("Food"), renderer, text=1)
        column.set_sort_column_id(1)
        column.set_resizable(True)
        column.set_expand(True)
        self.treeview.append_column(column)

        renderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_("Calories"), renderer, text=2)
        column.set_sort_column_id(2)
        column.set_resizable(True)
        self.treeview.append_column(column)

        renderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_("Quantity"), renderer, text=3)
        column.set_sort_column_id(3)
        column.set_resizable(True)
        self.treeview.append_column(column)

        renderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_("Time"), renderer, text=4)
        column.set_sort_column_id(5)
        column.set_resizable(True)
        self.treeview.append_column(column)

        self.treeview.set_model(self.model)
        self.treeview.set_headers_clickable(True)
        self.treeview.set_rules_hint(True)
        self.model.set_sort_column_id(5, gtk.SORT_ASCENDING)

        # Finally, load the user data.
        self.load_days()
        self.on_calendar_day_selected(self.calendar)

    ################################################################
    # Data access methods.
    ################################################################
    # Clears the user's consumed food data.
    def clear_days(self):
        self.model.clear()
        self.days = {}
        self.update_title()

    # Loads the user data from the currently opened file.
    def load_days(self):
        if not os.path.isfile(self.xml_file_consumerdb):
            return
        parser = make_parser()
        db = ConsumerDB()
        parser.setFeature(feature_namespaces, 0)
        parser.setContentHandler(db)
        parser.parse(self.xml_file_consumerdb)
        self.clear_days()
        self.days = db.getDays()
        self.gconf_client.set_string(GC_KEY_LAST_OPENED_FILE,
                                     self.xml_file_consumerdb)

        # Trigger a user interface update.
        self.on_calendar_day_selected(self.calendar)

    # Saves the user data to the currently opened file.
    def save_days(self):
        gen = ConsumerDBGenerator()
        gen.generate(self.xml_file_consumerdb, self.days)
        self.update_title()
        self.gconf_client.set_string(GC_KEY_LAST_OPENED_FILE,
                                     self.xml_file_consumerdb)

    ################################################################
    # UI interaction.
    ################################################################
    # Updates a single row in the listview.
    def update_food_in_treeview(self, iter, food):
        self.model.set_value(iter, 0, food)
        self.model.set_value(iter, 1, food.name)
        self.model.set_value(iter, 2, food.energy)
        self.model.set_value(iter, 3, food.quantity)
        self.model.set_value(iter, 4, food.time.strftime("%X"))
        self.model.set_value(iter, 5, food.time.isoformat())

    # Updates the number of calories consumed today.
    def update_energy_sum(self, day):
        sum = 0
        for food in day.get_foods():
            sum = sum + (food.energy * food.quantity)
        text = _("Calories consumed today: %i") % sum
        self.label_energy_sum.set_text(text)

    # Updates the given food in the form. If no food is given,
    # the form is reset to default values.
    def update_food_form(self, food):
        self.lock_signals = True
        if not food:
            food = Food(_("Food"))
            self.comboboxentry_food.set_text("")
        else:
            self.comboboxentry_food.set_text(food.name)
        self.spinbutton_quantity.set_value(food.quantity)
        self.spinbutton_energy.set_value(food.energy)
        self.spinbutton_hour.set_value(food.time.hour)
        self.spinbutton_minute.set_value(food.time.minute)
        self.lock_signals = False

    # Returns a food object that represents the current contents of the form.
    # Returns None if the form has no food name entered.
    def get_food_from_form(self):
        foodname = self.comboboxentry_food.get_text()
        if len(foodname) <= 0:
            return
        hour = int(self.spinbutton_hour.get_value())
        minute = int(self.spinbutton_minute.get_value())
        time = datetime.time(hour, minute, 0, 0, tz.LocalTimezone())
        date = self.get_calendar_date()
        date = date.combine(date, time)
        quantity = round(self.spinbutton_quantity.get_value(), 2)
        food = Food(foodname)
        food.set_quantity(quantity)
        food.set_energy(self.spinbutton_energy.get_value())
        food.set_time(date)
        return food

    # Returns the currently selected date as a datetime object.
    def get_calendar_date(self):
        year, month, day = self.calendar.get_date()
        # This sucks: GtkCalendar returns a zero-based month.
        month = month + 1
        tmz = tz.LocalTimezone()
        date = datetime.datetime(year, month, day, 0, 0, 0, 0, tmz)
        return date

    # Selects the given date in the calendar.
    def set_calendar_date(self, date):
        self.calendar.select_day(1)
        self.calendar.select_month(date.month - 1, date.year)
        self.calendar.select_day(date.day)

    # Returns the currently selected day.
    def get_selected_day(self):
        # Return the day if it already exists.
        today_date = self.get_calendar_date()
        today = self.days.setdefault(today_date.ctime(), Day(today_date))
        if today.get_weight() > 0:
            return today

        # If it was newly instantiated (get_weight == 0) above, inherit the
        # weight from the previous day.
        offset = datetime.timedelta(1)
        yesterday_date = today_date - offset
        yesterday = self.days.get(yesterday_date.ctime())
        if yesterday:
            today.set_weight(yesterday.get_weight())
            return today

        # If the previous day was not yet instantiated, get the default weight
        # from the form.
        weight = round(self.spinbutton_weight.get_value(), 2)
        today.set_weight(weight)
        return today

    # Updates the window title.
    def update_title(self):
        file = os.path.basename(self.xml_file_consumerdb)
        self.window.set_title(file)

    ################################################################
    # Callbacks.
    ################################################################
    def on_delete_event(*args):
        gtk.main_quit()

    def on_button_add_pressed(self, widget):
        food = self.get_food_from_form()
        if not food:
            return

        # Attach the food to the current day and update the GUI.
        self.treeview_selection.handler_block(self.treeview_selection_hd)
        day = self.get_selected_day()
        day.add_food(food)
        iter = self.model.append()
        self.update_food_in_treeview(iter, food)
        self.update_food_form(None)
        self.update_energy_sum(day)
        self.treeview_selection.handler_unblock(self.treeview_selection_hd)

        self.save_days()

    def on_button_delete_pressed(self, widget):
        model, iter = self.treeview_selection.get_selected()
        if not iter:
            return
        food = model.get_value(iter, 0)
        day = self.get_selected_day()
        day.remove_food(food)
        self.update_energy_sum(day)
        self.model.remove(iter)
        self.save_days()
        self.update_food_form(None)
        self.notebook_buttonbox.set_current_page(0)

    def on_button_newform_pressed(self, widget):
        self.update_food_form(None)
        self.notebook_buttonbox.set_current_page(0)
        self.treeview_selection.unselect_all()

    def on_treeview_selection_changed(self, selection):
        model, iter = self.treeview_selection.get_selected()
        if not iter:
            return

        self.treeview_selection.handler_block(self.treeview_selection_hd)
        self.notebook_buttonbox.set_current_page(1)
        food = model.get_value(iter, 0)
        self.update_food_form(food)
        self.treeview_selection.handler_unblock(self.treeview_selection_hd)

    def on_spinbutton_weight_value_changed(self, widget):
        day = self.get_selected_day()
        weight = round(self.spinbutton_weight.get_value(), 2)
        day.set_weight(weight)
        #FIXME: We should implement a timer to do this.
        self.save_days()

    def on_comboboxentry_food_changed(self, widget):
        self.on_entry_changed(widget)

    def on_spinbutton_energy_value_changed(self, widget):
        self.on_entry_changed(widget)

    def on_spinbutton_quantity_value_changed(self, widget):
        self.on_entry_changed(widget)

    def on_spinbutton_hour_value_changed(self, widget):
        self.on_entry_changed(widget)

    def on_spinbutton_minute_value_changed(self, widget):
        self.on_entry_changed(widget)

    def on_entry_changed(self, widget):
        if self.lock_signals:
            return

        # A name is required and a row must be selected.
        foodname = self.comboboxentry_food.get_text()
        model, iter = self.treeview_selection.get_selected()
        if len(foodname) <= 0 or not iter:
            return

        # Re-save the data.
        self.lock_signals = True
        day = self.get_selected_day()
        oldfood = model.get_value(iter, 0)
        food = self.get_food_from_form()
        day.add_food(food)
        day.remove_food(oldfood)
        self.update_food_in_treeview(iter, food)
        self.update_energy_sum(day)
        #FIXME: We should implement a timer to do this.
        self.save_days()
        self.lock_signals = False

    def on_calendar_day_selected(self, widget):
        self.model.clear()
        self.notebook_buttonbox.set_current_page(0)
        today = self.get_selected_day()
        self.spinbutton_weight.set_value(today.get_weight())
        if not today:
            return

        for food in today.get_foods():
            iter = self.model.append()
            self.update_food_in_treeview(iter, food)
        self.update_energy_sum(today)

    ################################################################
    # Menu callbacks.
    ################################################################
    def on_menu_file_new_activate(self, widget):
        fc = filechooser.create_filechooser_save()
        path = os.path.dirname(self.xml_file_consumerdb)
        if path != "":
            fc.set_current_folder(path)
        fc.set_current_name(_("unnamed.shriman"))
        response = fc.run()
        if response == gtk.RESPONSE_OK:
            self.xml_file_consumerdb = fc.get_filename()
            self.clear_days()
        fc.destroy()

    def on_menu_file_open_activate(self, widget):
        fc = filechooser.create_filechooser_open()
        path = os.path.dirname(self.xml_file_consumerdb)
        if path != "":
            fc.set_current_folder(path)
        response = fc.run()
        if response == gtk.RESPONSE_OK:
            self.xml_file_consumerdb = fc.get_filename()
            self.load_days()
        fc.destroy()

    def on_menu_file_save_as_activate(self, widget):
        fc = filechooser.create_filechooser_save()
        path = os.path.dirname(self.xml_file_consumerdb)
        file = os.path.basename(self.xml_file_consumerdb)
        if path != "":
            fc.set_current_folder(path)
        if file != "":
            fc.set_current_name(file)
        response = fc.run()
        if response == gtk.RESPONSE_OK:
            self.xml_file_consumerdb = fc.get_filename()
            self.save_days()
        fc.destroy()

    def on_menu_file_quit_activate(self, widget):
        gtk.main_quit()

    def on_menu_edit_cut_activate(self, widget):
        widget = self.window.get_focus()
        if not hasattr(widget, "cut_clipboard"):
            return
        widget.cut_clipboard()

    def on_menu_edit_copy_activate(self, widget):
        widget = self.window.get_focus()
        if not hasattr(widget, "copy_clipboard"):
            return
        widget.copy_clipboard()

    def on_menu_edit_paste_activate(self, widget):
        widget = self.window.get_focus()
        if not hasattr(widget, "paste_clipboard"):
            return
        widget.paste_clipboard()

    def on_menu_edit_delete_activate(self, widget):
        widget = self.window.get_focus()
        if not hasattr(widget, "delete_selection"):
            return
        widget.delete_selection()

    def on_menu_view_previous_day_activate(self, widget):
        date = self.get_calendar_date()
        offset = datetime.timedelta(1)
        date = date - offset
        self.set_calendar_date(date)

    def on_menu_view_next_day_activate(self, widget):
        date = self.get_calendar_date()
        offset = datetime.timedelta(1)
        date = date + offset
        self.set_calendar_date(date)

    def on_menu_view_today_activate(self, widget):
        date = datetime.datetime.now()
        self.set_calendar_date(date)

    def on_menu_help_about_activate(self, widget):
        if not self.dialog_about:
            self.dialog_about = AboutDialog()
        self.dialog_about.show()

    ################################################################
    # Toolbutton callbacks.
    ################################################################
    def on_toolbutton_new_clicked(self, widget):
        self.on_menu_file_new_activate(widget)

    def on_toolbutton_open_clicked(self, widget):
        self.on_menu_file_open_activate(widget)

    def on_toolbutton_previous_day_clicked(self, widget):
        self.on_menu_view_previous_day_activate(widget)

    def on_toolbutton_next_day_clicked(self, widget):
        self.on_menu_view_next_day_activate(widget)

    def on_toolbutton_today_clicked(self, widget):
        self.on_menu_view_today_activate(widget)
Ejemplo n.º 6
0
 def showAboutDialog(self):
     from aboutdialog import AboutDialog
     if not self.aboutDialog:
         self.aboutDialog = AboutDialog(self._iface.mainWindow())
     self.aboutDialog.setVisible(True)
Ejemplo n.º 7
0
class MainWindow:
    def __init__(self):
        self.days         = {}
        self.lock_signals = False
        
        # Determine the last opened file.
        self.xml_file_consumerdb = XML_FILE_CONSUMERDB
        self.gconf_client        = gconf.client_get_default()
        val = self.gconf_client.get(GC_KEY_LAST_OPENED_FILE)
        if val:
            last_opened_file = val.get_string()
            if (last_opened_file
                and os.path.isfile(last_opened_file)):
                self.xml_file_consumerdb = last_opened_file
        
        # Lookup all widgets.
        gladefile = cfg["APP_SYSNAME"] + ".glade"
        callback  = self.on_treeview_selection_changed
        self.xml                   = util.get_glade_xml(gladefile, "mainwindow")
        self.window                = self.xml.get_widget('mainwindow')
        self.treeview              = self.xml.get_widget('treeview_caleditor')
        self.treeview_selection    = self.treeview.get_selection()
        self.treeview_selection_hd = self.treeview_selection.connect("changed",
                                                                     callback)
        self.calendar              = self.xml.get_widget('calendar')
        self.spinbutton_weight     = self.xml.get_widget('spinbutton_weight')
        self.combobox_food         = self.xml.get_widget('comboboxentry_food')
        self.comboboxentry_food    = self.combobox_food.get_child()
        self.spinbutton_quantity   = self.xml.get_widget('spinbutton_quantity')
        self.spinbutton_energy     = self.xml.get_widget('spinbutton_energy')
        self.spinbutton_hour       = self.xml.get_widget('spinbutton_hour')
        self.spinbutton_minute     = self.xml.get_widget('spinbutton_minute')
        self.notebook_buttonbox    = self.xml.get_widget('notebook_buttonbox')
        self.label_energy_sum      = self.xml.get_widget('label_energy_sum')
        self.dialog_about          = None
        self.xml.signal_autoconnect(self)
        
        # Init widgets.
        t = time.localtime(time.time())
        self.spinbutton_hour.set_value(t[3])
        self.spinbutton_minute.set_value(t[4])
        
        # Init the listview.
        self.model = gtk.ListStore(gobject.TYPE_PYOBJECT,
                                   gobject.TYPE_STRING,
                                   gobject.TYPE_STRING,
                                   gobject.TYPE_STRING,
                                   gobject.TYPE_STRING,
                                   gobject.TYPE_STRING)
        
        renderer = gtk.CellRendererText()
        column   = gtk.TreeViewColumn(_("Food"), renderer, text = 1)
        column.set_sort_column_id(1)
        column.set_resizable(True)
        column.set_expand(True)
        self.treeview.append_column(column)

        renderer = gtk.CellRendererText()
        column   = gtk.TreeViewColumn(_("Calories"), renderer, text = 2)
        column.set_sort_column_id(2)
        column.set_resizable(True)
        self.treeview.append_column(column)

        renderer = gtk.CellRendererText()
        column   = gtk.TreeViewColumn(_("Quantity"), renderer, text = 3)
        column.set_sort_column_id(3)
        column.set_resizable(True)
        self.treeview.append_column(column)

        renderer = gtk.CellRendererText()
        column   = gtk.TreeViewColumn(_("Time"), renderer, text = 4)
        column.set_sort_column_id(5)
        column.set_resizable(True)
        self.treeview.append_column(column)

        self.treeview.set_model(self.model)
        self.treeview.set_headers_clickable(True)
        self.treeview.set_rules_hint(True)
        self.model.set_sort_column_id(5, gtk.SORT_ASCENDING)
        
        # Finally, load the user data.
        self.load_days()
        self.on_calendar_day_selected(self.calendar)
        
    ################################################################
    # Data access methods.
    ################################################################
    # Clears the user's consumed food data.
    def clear_days(self):
        self.model.clear()
        self.days = {}
        self.update_title()
        
    # Loads the user data from the currently opened file.
    def load_days(self):
        if not os.path.isfile(self.xml_file_consumerdb):
            return
        parser = make_parser()
        db     = ConsumerDB()
        parser.setFeature(feature_namespaces, 0)
        parser.setContentHandler(db)
        parser.parse(self.xml_file_consumerdb)
        self.clear_days()
        self.days = db.getDays()
        self.gconf_client.set_string(GC_KEY_LAST_OPENED_FILE,
                                     self.xml_file_consumerdb)

        # Trigger a user interface update.
        self.on_calendar_day_selected(self.calendar)
        
    # Saves the user data to the currently opened file.
    def save_days(self):
        gen = ConsumerDBGenerator()
        gen.generate(self.xml_file_consumerdb, self.days)
        self.update_title()
        self.gconf_client.set_string(GC_KEY_LAST_OPENED_FILE,
                                     self.xml_file_consumerdb)
    
    ################################################################
    # UI interaction.
    ################################################################
    # Updates a single row in the listview.
    def update_food_in_treeview(self, iter, food):
        self.model.set_value(iter, 0, food)
        self.model.set_value(iter, 1, food.name)
        self.model.set_value(iter, 2, food.energy)
        self.model.set_value(iter, 3, food.quantity)
        self.model.set_value(iter, 4, food.time.strftime("%X"))
        self.model.set_value(iter, 5, food.time.isoformat())
    
    # Updates the number of calories consumed today.
    def update_energy_sum(self, day):
        sum = 0
        for food in day.get_foods():
            sum = sum + (food.energy * food.quantity)
        text = _("Calories consumed today: %i") % sum
        self.label_energy_sum.set_text(text)

    # Updates the given food in the form. If no food is given,
    # the form is reset to default values.
    def update_food_form(self, food):
        self.lock_signals = True
        if not food:
            food = Food(_("Food"))
            self.comboboxentry_food.set_text("")
        else:
            self.comboboxentry_food.set_text(food.name)
        self.spinbutton_quantity.set_value(food.quantity)
        self.spinbutton_energy.set_value(food.energy)
        self.spinbutton_hour.set_value(food.time.hour)
        self.spinbutton_minute.set_value(food.time.minute)
        self.lock_signals = False
    
    # Returns a food object that represents the current contents of the form.
    # Returns None if the form has no food name entered.
    def get_food_from_form(self):
        foodname = self.comboboxentry_food.get_text()
        if len(foodname) <= 0:
            return
        hour     = int(self.spinbutton_hour.get_value())
        minute   = int(self.spinbutton_minute.get_value())
        time     = datetime.time(hour, minute, 0, 0, tz.LocalTimezone())
        date     = self.get_calendar_date()
        date     = date.combine(date, time)
        quantity = round(self.spinbutton_quantity.get_value(), 2)
        food = Food(foodname)
        food.set_quantity(quantity)
        food.set_energy(self.spinbutton_energy.get_value())
        food.set_time(date)
        return food
        
    # Returns the currently selected date as a datetime object.
    def get_calendar_date(self):
        year, month, day = self.calendar.get_date()
        # This sucks: GtkCalendar returns a zero-based month.
        month = month + 1
        tmz   = tz.LocalTimezone()
        date  = datetime.datetime(year, month, day, 0, 0, 0, 0, tmz)
        return date
        
    # Selects the given date in the calendar.
    def set_calendar_date(self, date):
        self.calendar.select_day(1)
        self.calendar.select_month(date.month - 1, date.year)
        self.calendar.select_day(date.day)
        
    # Returns the currently selected day.
    def get_selected_day(self):
        # Return the day if it already exists.
        today_date = self.get_calendar_date()
        today      = self.days.setdefault(today_date.ctime(), Day(today_date))
        if today.get_weight() > 0:
            return today

        # If it was newly instantiated (get_weight == 0) above, inherit the
        # weight from the previous day.
        offset         = datetime.timedelta(1)
        yesterday_date = today_date - offset
        yesterday      = self.days.get(yesterday_date.ctime())
        if yesterday:
            today.set_weight(yesterday.get_weight())
            return today

        # If the previous day was not yet instantiated, get the default weight
        # from the form.
        weight = round(self.spinbutton_weight.get_value(), 2)
        today.set_weight(weight)
        return today
        
    # Updates the window title.
    def update_title(self):
        file = os.path.basename(self.xml_file_consumerdb)
        self.window.set_title(file)
        
    ################################################################
    # Callbacks.
    ################################################################
    def on_delete_event(*args):
        gtk.main_quit()
    
    def on_button_add_pressed(self, widget):
        food = self.get_food_from_form()
        if not food:
            return

        # Attach the food to the current day and update the GUI.
        self.treeview_selection.handler_block(self.treeview_selection_hd)
        day = self.get_selected_day()
        day.add_food(food)
        iter = self.model.append()
        self.update_food_in_treeview(iter, food)
        self.update_food_form(None)
        self.update_energy_sum(day)
        self.treeview_selection.handler_unblock(self.treeview_selection_hd)

        self.save_days()
    
    def on_button_delete_pressed(self, widget):
        model, iter = self.treeview_selection.get_selected()
        if not iter:
            return
        food = model.get_value(iter, 0)
        day  = self.get_selected_day()
        day.remove_food(food)
        self.update_energy_sum(day)
        self.model.remove(iter)
        self.save_days()
        self.update_food_form(None)
        self.notebook_buttonbox.set_current_page(0)

    def on_button_newform_pressed(self, widget):
        self.update_food_form(None)
        self.notebook_buttonbox.set_current_page(0)
        self.treeview_selection.unselect_all()

    def on_treeview_selection_changed(self, selection):
        model, iter = self.treeview_selection.get_selected()
        if not iter:
            return

        self.treeview_selection.handler_block(self.treeview_selection_hd)
        self.notebook_buttonbox.set_current_page(1)
        food = model.get_value(iter, 0)
        self.update_food_form(food)
        self.treeview_selection.handler_unblock(self.treeview_selection_hd)
    
    def on_spinbutton_weight_value_changed(self, widget):
        day    = self.get_selected_day()
        weight = round(self.spinbutton_weight.get_value(), 2)
        day.set_weight(weight)
        #FIXME: We should implement a timer to do this.
        self.save_days() 

    def on_comboboxentry_food_changed(self, widget):
        self.on_entry_changed(widget)

    def on_spinbutton_energy_value_changed(self, widget):
        self.on_entry_changed(widget)

    def on_spinbutton_quantity_value_changed(self, widget):
        self.on_entry_changed(widget)

    def on_spinbutton_hour_value_changed(self, widget):
        self.on_entry_changed(widget)

    def on_spinbutton_minute_value_changed(self, widget):
        self.on_entry_changed(widget)

    def on_entry_changed(self, widget):
        if self.lock_signals:
            return

        # A name is required and a row must be selected.
        foodname    = self.comboboxentry_food.get_text()
        model, iter = self.treeview_selection.get_selected()
        if len(foodname) <= 0 or not iter:
            return
        
        # Re-save the data.
        self.lock_signals = True
        day     = self.get_selected_day()
        oldfood = model.get_value(iter, 0)
        food    = self.get_food_from_form()
        day.add_food(food)
        day.remove_food(oldfood)
        self.update_food_in_treeview(iter, food)
        self.update_energy_sum(day)
        #FIXME: We should implement a timer to do this.
        self.save_days()
        self.lock_signals = False
    
    def on_calendar_day_selected(self, widget):
        self.model.clear()
        self.notebook_buttonbox.set_current_page(0)
        today = self.get_selected_day()
        self.spinbutton_weight.set_value(today.get_weight())
        if not today:
            return
        
        for food in today.get_foods():
            iter = self.model.append()
            self.update_food_in_treeview(iter, food)
        self.update_energy_sum(today)
    
    ################################################################
    # Menu callbacks.
    ################################################################
    def on_menu_file_new_activate(self, widget):
        fc   = filechooser.create_filechooser_save()
        path = os.path.dirname(self.xml_file_consumerdb)
        if path != "":
            fc.set_current_folder(path)
        fc.set_current_name(_("unnamed.shriman"))
        response = fc.run()
        if response == gtk.RESPONSE_OK:
            self.xml_file_consumerdb = fc.get_filename()
            self.clear_days()
        fc.destroy()

    def on_menu_file_open_activate(self, widget):
        fc   = filechooser.create_filechooser_open()
        path = os.path.dirname(self.xml_file_consumerdb)
        if path != "":
            fc.set_current_folder(path)
        response = fc.run()
        if response == gtk.RESPONSE_OK:
            self.xml_file_consumerdb = fc.get_filename()
            self.load_days()
        fc.destroy()
    
    def on_menu_file_save_as_activate(self, widget):
        fc   = filechooser.create_filechooser_save()
        path = os.path.dirname(self.xml_file_consumerdb)
        file = os.path.basename(self.xml_file_consumerdb)
        if path != "":
            fc.set_current_folder(path)
        if file != "":
            fc.set_current_name(file)
        response = fc.run()
        if response == gtk.RESPONSE_OK:
            self.xml_file_consumerdb = fc.get_filename()
            self.save_days()
        fc.destroy()
        
    def on_menu_file_quit_activate(self, widget):
        gtk.main_quit()

    def on_menu_edit_cut_activate(self, widget):
        widget = self.window.get_focus()
        if not hasattr(widget, "cut_clipboard"):
            return
        widget.cut_clipboard()

    def on_menu_edit_copy_activate(self, widget):
        widget = self.window.get_focus()
        if not hasattr(widget, "copy_clipboard"):
            return
        widget.copy_clipboard()

    def on_menu_edit_paste_activate(self, widget):
        widget = self.window.get_focus()
        if not hasattr(widget, "paste_clipboard"):
            return
        widget.paste_clipboard()

    def on_menu_edit_delete_activate(self, widget):
        widget = self.window.get_focus()
        if not hasattr(widget, "delete_selection"):
            return
        widget.delete_selection()

    def on_menu_view_previous_day_activate(self, widget):
        date   = self.get_calendar_date()
        offset = datetime.timedelta(1)
        date   = date - offset
        self.set_calendar_date(date)
        
    def on_menu_view_next_day_activate(self, widget):
        date   = self.get_calendar_date()
        offset = datetime.timedelta(1)
        date   = date + offset
        self.set_calendar_date(date)

    def on_menu_view_today_activate(self, widget):
        date = datetime.datetime.now()
        self.set_calendar_date(date)

    def on_menu_help_about_activate(self, widget):
        if not self.dialog_about:
            self.dialog_about = AboutDialog()
        self.dialog_about.show()

    ################################################################
    # Toolbutton callbacks.
    ################################################################
    def on_toolbutton_new_clicked(self, widget):
        self.on_menu_file_new_activate(widget)

    def on_toolbutton_open_clicked(self, widget):
        self.on_menu_file_open_activate(widget)

    def on_toolbutton_previous_day_clicked(self, widget):
        self.on_menu_view_previous_day_activate(widget)

    def on_toolbutton_next_day_clicked(self, widget):
        self.on_menu_view_next_day_activate(widget)

    def on_toolbutton_today_clicked(self, widget):
        self.on_menu_view_today_activate(widget)
Ejemplo n.º 8
0
class BioParkinController(QMainWindow, Ui_MainWindow):
    """
    This is the heart of BioParkin. It sets up the general UI
    (MainWindow, some Views, ...), handles creation and management of
    individual network windows, and instantiates needed services
    (for easy access to data, status bar, ...).

    This class inherits from QMainWindow for its functionality and from
    the (automatically generated) Ui_MainWindow for the design of the UI
    (including the self.setupUi() method).

    @param parent: The standard Qt parent.
    @type parent: QWidget

    @organization: Zuse Insitute Berlin
    """

    __version__ = "1.2.27"
    __author__ = "Moritz Wade & Thomas Dierkes"
    __contact__ = "[email protected] or [email protected]"
    __copyright__ = "Zuse Institute Berlin 2011"

    newNetworkWindowCreated = Signal()
    networkWindowRaised = Signal()
    activeModelChanged = Signal(ModelController)
    modelClosed = Signal(ModelController)

    def __init__(self, args, parent=None):
        """
        This initialization does a lot of stuff. :)

        * State variables are set up
        * Views are created and tied to UI parts (e.g. Docks)
        * Logging is set up
        * Services (StatusBar, Data, ...) are started
        * Necessary slots are connected

        """
        super(BioParkinController, self).__init__(parent)

        # for locale testing
        # locale.setlocale(locale.LC_ALL, 'de_DE')
        #        locale.setlocale(locale.LC_ALL, 'deu_deu')

        self.startTime = time.localtime()

        # set file logger
        self.rotatingFileHandler = logging.handlers.RotatingFileHandler(_LOG_FILENAME, maxBytes=1000000, backupCount=5)
        self.rotatingFileHandler.setFormatter(logging.Formatter("%(asctime)s | %(levelname)s | %(message)s"))
        self.logger = logging.getLogger()  # gets root logger
        self.logger.addHandler(self.rotatingFileHandler)

        # Status bar logger
        self.statusBarLoggingHandler = StatusBarLoggingHandler()
        self.statusBarLoggingHandler.setLevel(logging.INFO)  # only log on info level
        self.logger.addHandler(self.statusBarLoggingHandler)

        # parse command line arguments
        parser = OptionParser()
        parser.add_option(
            "-d",
            "--debug",
            action="store_true",
            dest=OPTION_DEBUG,
            default=False,
            help="Include debugging information in console and file log",
        )
        self.options, args = parser.parse_args()

        self.optionsService = OptionsService()
        self.optionsService.setDebug(self.options.debug)

        # set logging options
        if self.options.debug:
            self.logger.setLevel(logging.DEBUG)
            self.rotatingFileHandler.setLevel(logging.DEBUG)
            logging.info("Debug logging active.")
        else:
            self.logger.setLevel(logging.INFO)
            self.rotatingFileHandler.setLevel(logging.INFO)
            logging.info("Debug logging not active.")

        logging.info("Starting BioPARKIN... %s" % self.startTime)

        ##### LOGGING #####
        logging.info("BioPARKIN started (version %s)" % BioParkinController.__version__)
        logging.info("Command line arguments: %s" % args)
        logging.info("Python version: %s" % sys.version)
        logging.info("PySide version: %s" % PySide.__version__)
        logging.info("PARKINcpp version: %s" % PARKINCPP_DOTTED_VERSION)
        logging.info("libSBML version: %s" % LIBSBML_DOTTED_VERSION)
        logging.info("Matplotlib version: %s" % matplotlib.__version__)
        #        logging.info("NetworkX version: %s" % networkx.__version__)
        logging.info("Python Image Library version: %s" % Image.VERSION)

        self.setupUi(self)
        self._mdiArea.hide()
        self.setWindowTitle("BioPARKIN v%s" % BioParkinController.__version__)

        # restore previous settings
        settings = QSettings()
        try:
            self.recentFiles = settings.value("RecentFiles", [])

            # handles the case if only one file is in the "list" in Linux (it's retrieved as unicode string in this case)
            if type(self.recentFiles) is str or type(self.recentFiles) is unicode:
                self.recentFiles = [self.recentFiles]

            logging.info("Recently opened files: %s" % self.recentFiles)
        except:
            logging.warning("Can't access list of recently opened files. Resetting the list.")
            self.recentFiles = []

        self.updateFileMenu()
        self.aboutDialog = None

        geometry = settings.value("Geometry")
        if geometry:
            self.restoreGeometry(geometry)

        state = settings.value("MainWindow/State")
        if state:
            self.restoreState(state)

        self.ModelControllers = {}
        #        self.SubWindowToModelControllers = {}
        #        self.NetworkWindowCount = 0
        #        self.ActiveNetworkWindow = None
        self.ActiveModelController = None
        #        self.networkSubWindows = {}

        self.integrator = None
        self.odeViewer = None

        self.ModelView = ModelView(self.masterDetailSplitter, self)
        self.ModelTreeView = SBMLEntityWidget(self.masterDetailSplitter)
        self.EntityTableView = EntityTableView(self.masterDetailSplitter)

        self.mainWindowViews = [self.ModelTreeView, self.EntityTableView]  # used to iterate over Views

        # set up Data Service and Data Viewer
        datahandling.parkinController = self
        self.dataService = DataService()

        # debugging#############
        BASE_PATH = reduce(
            lambda l, r: l + os.path.sep + r, os.path.dirname(os.path.realpath(__file__)).split(os.path.sep)[:-1]
        )

        # add ../../templates (relative to the file (!) and not to the CWD)
        dataPath = os.path.join(BASE_PATH, "data")
        #######################

        self.SimulationWorkbenchController = SimulationWorkbenchController(parent=None, parkinController=self)
        self.mainTabWidget.addTab(self.SimulationWorkbenchController, "Workbench")

        # hook up status bar with progress service (that threads can connect to)
        self.statusBarService = StatusBarService(
            self.statusBar()
        )  # first time, service is instantiated => give statusBar reference!
        self.progressBarService = ProgressBarService(self, self.statusBarService)

        self.statusBarLoggingHandler.setStatusBar(self.statusBarService)

        self.warningsService = WarningService.getInstance()
        self.warningsDialog = WarningsDialog(self, self.actionShow_Warnings, self.warningsService)

        # register signals
        self.activeModelChanged.connect(self.on_activeModelChanged)
        self.modelClosed.connect(self.on_modelClosed)
        self.menuFile.aboutToShow.connect(self.updateFileMenu)

        # for debugging
        self.dummyThread = None

        try:  # try to set correct taskbar icon in Windows 7
            myappid = "ZIB.BioPARKIN"  # arbitrary string
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
        except:
            pass

    def updateFileMenu(self):
        """
        Updates the file menu dynamically, so that recent files can be shown.
        """
        self.menuFile.clear()
        #        self.menuFile.addAction(self.actionNew)    # disable for now
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionSave)
        self.menuFile.addAction(self.actionSave_as)
        self.menuFile.addAction(self.actionClose_Model)

        recentFiles = []
        for filename in self.recentFiles:
            if QFile.exists(filename):
                recentFiles.append(filename)

        if len(self.recentFiles) > 0:
            self.menuFile.addSeparator()
            for i, filename in enumerate(recentFiles):
                action = QAction("&%d %s" % (i + 1, QFileInfo(filename).fileName()), self)
                action.setData(filename)
                action.setStatusTip("Opens recent file %s" % QFileInfo(filename).fileName())
                action.setShortcut(QKeySequence(Qt.CTRL | (Qt.Key_1 + i)))
                action.triggered.connect(self.load_model)
                self.menuFile.addAction(action)

        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionQuit)

    def new_model(self):
        """
        Not yet supported.
        """
        pass

    def load_model(self, filename=None):
        """
        Loads a given SBML file, thereby creating a new subwindow
        on the main MDI Area.
        If filename is None, it creates a new model.

        There are a lot of reference variables, so that the system knows the
        currently active subwindow, etc.

        @param filename: The filename of the model. If None, a new model is created.
        @type filename: str
        """
        if not filename:
            action = self.sender()
            if type(action) == QAction:
                filename = action.data()
            else:
                return

        # note: this has been (temporarily added) to allow only one file to be open at the same time
        # We will probably change this behaviour again later, once we have decided how to handle
        # multiple-model results, etc. intelligently
        if len(self.ModelControllers) > 0:

            # show warning dialog
            msgBox = QMessageBox()
            infoText = """<b>Another model is currently loaded.</b><br>
            """
            msgBox.setText(infoText)
            infoTextShort = "Do you want to save the current model (you will be prompted to enter a new filename)?"
            msgBox.setInformativeText(infoTextShort)
            msgBox.setWindowTitle(infoTextShort)
            msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard)
            msgBox.setDefaultButton(QMessageBox.Save)
            msgBox.setIcon(QMessageBox.Warning)
            clickedButton = msgBox.exec_()

            if clickedButton == QMessageBox.Save:
                self.actionSave_as.trigger()

            for (
                modelController
            ) in self.ModelControllers.values():  # close all models (in theory, there should be only one :)
                self.modelClosed.emit(modelController)

        #        self.NetworkWindowCount += 1
        #        self.setStatusTip("Opening file %s..." % filename)
        self.statusBar().showMessage("Opening file %s..." % filename, 2000)
        modelController = ModelController(filename=filename, views=self.mainWindowViews)

        #        # create NetworkViewController
        #        networkViewController = NetworkViewController(modelController=modelController)
        #        networkView = networkViewController.createNetworkView(self) # sets networkController.networkView internally
        #        networkView.setMinimumSize(400, 300)
        #        modelController.setViews(networkViewController=networkViewController)

        #        # Create Subwindow to hold the NetworkView
        #        subWindow = QMdiSubWindow(parent=self._mdiArea)
        #        networkViewController.subWindow = subWindow
        #        subWindow.setAttribute(Qt.WA_DeleteOnClose)
        #        subWindow.setWidget(networkView)
        #        subWindow.setOption(QMdiSubWindow.RubberBandResize, True)
        #        self._mdiArea.addSubWindow(subWindow)
        #        subWindow.activateWindow()
        #        subWindow.show()    # important!
        #        networkView.show()

        # handle references
        filename = modelController.filename
        #        self.SubWindowToModelControllers[subWindow] = modelController
        #        self.networkSubWindows[modelController] = subWindow #networkView
        self.ModelControllers[filename] = modelController
        #        self.ActiveNetworkWindow = networkWindow
        self.ActiveModelController = modelController

        #        self.connectNetworkWindowSignals(networkView, subWindow)

        # emit custom Signal so that e.g. Simulationworkbench are notified of the new subwindow
        #        self.newNetworkWindowCreated.emit()
        self.activeModelChanged.emit(modelController)

        # handle recent files list
        if filename in self.recentFiles:
            self.recentFiles.remove(filename)
        self.recentFiles.insert(0, filename)
        if len(self.recentFiles) > NUM_RECENT_FILES:  # cap list at length of NUM_RECENT_FILES
            self.recentFiles = self.recentFiles[:NUM_RECENT_FILES]

    #    def getMdiArea(self):
    #        return self._mdiArea

    #    @Slot("QWidget")
    #    def connectNetworkWindowSignals(self, networkWindow, subWindow):
    #        """
    #        Connect the signals of network windows (e.g. network is about to be destroyed, etc.)
    #
    #        @param networkWindow: A network view
    #        @type networkWindow: NetworkView
    #
    #        @param subWindow: A Qt QMdiArea sub window
    #        @type subWindow: QMdiSubWindow
    #        """
    #        #self.connect(button3, SIGNAL("clicked()"),    lambda who="Three": self.anyButton(who))
    #
    #        self.connect(networkWindow, SIGNAL("destroyed()"),
    #                     lambda who=networkWindow: self.on_networkwindow_destroyed(who))

    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat("Filename"):
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        """
        Handles the drop event if the user "drops" a file somewhere within BioPARKIN's window.
        """
        # get filename
        uris = event.mimeData().urls()  # support opening several models at once

        # note: uncomment this, to enable drag'n'dropping of multiple models again
        #        for uri in uris:
        #            filename = uri.toLocalFile()
        #            #open file
        #            self.load_model(filename)
        filename = uris[0].toLocalFile()
        self.load_model(filename)
        if len(uris) > 1:
            logging.info(
                "You dragged more than one model to BioPARKIN. Currently, only one model is supported to be opened at the same time. Only the first dragged model was loaded."
            )

    def on_modelClosed(self, modelController):
        """
        Whenever the Signal self.modelClosed is emitted, this
        method is called.
        It removes the modelController of the closed model from
        the management dictionary and updates all local Views.
        """
        if not modelController:
            logging.info("Can't close the model. No model selected.")

            #### abusing this place for testing ####
            #            self.dummyThread = DummyProgressThread()
            #            self.progressBarService.connect_to_thread(self.dummyThread)
            #            self.dummyThread.start()

            #            self.dummyThread = DummyThrobberThread()
            #            self.progressBarService.connect_to_thread(self.dummyThread)
            #            self.dummyThread.start()

            ########################################

            return
        if self.ModelControllers.has_key(
            modelController.filename
        ):  # we do this to remove the model controller from the management dict
            self.ModelControllers.pop(modelController.filename)

        if len(self.ModelControllers) == 0:
            # 26.07.12 td: the next line has been commented out
            self.dataService.remove_all_simulated_data()
            self.ActiveModelController = None
            for view in self.mainWindowViews:
                view.setModel(None)

    #    def on_networkwindow_destroyed(self, networkWindow):
    #        """
    #        This is a slot. It's called to clean things up when a network
    #        window is destroyed. Basically, it just gets the correct ModelController
    #        and passes it on using the modelClosed signal of the BioPARKIN controller.
    #
    #        @param networkWindow: A network view
    #        @type networkWindow: NetworkView
    #        """
    #        logging.debug("Destroying a NetworkWindow: %s" % networkWindow)
    #        modelController = networkWindow.controller.modelController
    #        self.modelClosed.emit(modelController)
    #
    #    def closeNetworkWindow(self, modelController):
    #        if self.networkSubWindows.has_key(modelController): # might have been removed already
    #            self.networkSubWindows.pop(modelController).close() #removes window from dict and closes it

    def on_activeModelChanged(self, activeModelController):
        """
        Whenever the active model changes, the appropriate Signal
        self.activeModelChanged should be emitted. When that is done, this method
        is called.
        """
        logging.info("Active Model: %s" % activeModelController.filename)
        if activeModelController is not None:
            self.ActiveModelController = activeModelController
            for view in self.mainWindowViews:
                view.setModel(self.ActiveModelController.proxyModel, mainModel=self.ActiveModelController.sbmlModel)
                view.setSelectionModel(self.ActiveModelController.selectionModel)

    #    def selectNetworkView(self, modelController):
    #        subwindow = self.networkSubWindows[modelController]
    ##        subwindow.show()
    #        subwindow.raise_()
    #        subwindow.activateWindow()
    ##        subwindow.setFocus()

    #    def on_networkwindow_raised(self, subWindow):
    #        """
    #        This is a slot. It's called when a network window gets focus.
    #        Some references have to be set, and most importantly, all the Views
    #        have to be switched so that they use the data model behind the
    #        newly focused network window.
    #
    #        @param subWindow: A sub window
    #        @type subWindow: QMdiSubWindow
    #        """
    #        if subWindow is None:
    #            return
    #        if not self.SubWindowToModelControllers.has_key(subWindow):
    #            return
    #
    #        activeModelController = self.SubWindowToModelControllers[subWindow]
    ##        self.ActiveNetworkWindow = self.ActiveModelController.getNetworkView()
    #
    ##        self.on_activeModelChanged()
    #        self.activeModelChanged.emit(activeModelController)
    ##        self.networkWindowRaised.emit()
    #
    ##        logging.debug("Leaving on_networkwindow_raised()")

    @Slot("")
    def on_actionNew_triggered(self):
        """
        This is a slot. It's automatically connected to the actionNew
        created in the QtDesigner.
        """
        self.new_model()

    @Slot("")
    def on_actionOpen_triggered(self):
        """
        This is a slot. It's automatically connected to the actionOpen
        created in the QtDesigner.
        """
        homeDir = filehelpers.getHomeDir()

        filenameTuple = QFileDialog.getOpenFileName(
            parent=self, directory=homeDir, filter="SBML files (*.sbml *.xml)", caption="Open SBML file..."
        )

        if (
            filenameTuple and filenameTuple[0]
        ):  # if user presses cancel, the tuple exists but is two empty unicode strings.
            filename = filenameTuple[0]
            self.load_model(filename)
        else:
            logging.info("No file selected. Didn't load anything.")

    @Slot("")
    def on_actionClose_Model_triggered(self):
        #        self.on_modelClosed(self.ActiveModelController)
        self.modelClosed.emit(self.ActiveModelController)

    @Slot("")
    def on_actionSave_triggered(self):
        """
        This is a slot. It's automatically connected to the actionSave
        created in the QtDesigner.
        """
        self.saveActiveNetwork(filename=None)

    @Slot("")
    def on_actionSave_as_triggered(self):
        """
        This is a slot. It's automatically connected to the actionSaveAs
        created in the QtDesigner.
        """
        if not self.ActiveModelController:
            logging.info("Can't save anything. No model loaded.")
            return
        filenameTuple = QFileDialog.getSaveFileName(
            parent=self,
            dir=self.ActiveModelController.filename,
            caption="Save as...",
            filter="SBML file (*.sbml *.xml)",
        )
        if filenameTuple:
            self.saveActiveNetwork(filenameTuple[0])

    def saveActiveNetwork(self, filename=None):
        """
        Tell the currently active network controller to
        save to a file.

        @param filename: Filename of the network.
        @type filename: str
        """
        if self.ActiveModelController is None:
            logging.warning("No model loaded. Can't save anything.")
            return
        self.ActiveModelController.save(filename=filename)

    @Slot("")
    def on_actionShow_Data_Manager_triggered(self):
        """
        This is a slot. It's automatically connected to the actionShowDataManager
        created in the QtDesigner.
        """
        self.DataManagementController.show()

    @Slot("")
    def on_actionODEGenerator_triggered(self):
        """
        Open the ODE Generator information dialog.
        """
        if self.ActiveModelController and self.ActiveModelController.sbmlModel:
            self.odeViewer = ODEViewer(self, self.ActiveModelController.sbmlModel)
            self.odeViewer.show()
        else:
            logging.info("ODEs can't be shown. No model selected.")

    def closeEvent(self, event):
        """
        Override the close event to handle file saving.
        """
        if self.okToContinue():  # files will be saved in self.okToContinue()
            settings = QSettings()
            settings.setValue("Geometry", self.saveGeometry())
            settings.setValue("MainWindow/State", self.saveState())
            settings.setValue("RecentFiles", self.recentFiles)

            event.accept()
        else:
            event.ignore()

    def okToContinue(self):
        """
        Checks if it is ok to close the application.
        The user will be prompted to save files.

        @return: True, if it is ok to continue (e.g. close the app); False, otherwise
        @rtype: bool

        @todo: Make a smart save dialog to allow the user to save only certain files.
        """
        dirtyFilenames = []
        for filename, networkController in self.ModelControllers.items():
            if networkController.Dirty:
                dirtyFilenames.append(
                    networkController.filename
                )  # we don't use the filename key because it might be outdated
        if len(dirtyFilenames) == 0:  # nothing to save
            return True

        reply = QMessageBox.question(
            self,
            "BioParkin - Unsaved Changes",
            "Unsaved changes in these files:\n\n%s\n\nDo you want to save them?" % "\n".join(dirtyFilenames),
            buttons=QMessageBox.SaveAll | QMessageBox.Discard | QMessageBox.Cancel,
        )
        if reply == QMessageBox.Cancel:
            return False
        elif reply == QMessageBox.SaveAll:
            for networkController in self.ModelControllers:
                if networkController.Dirty:
                    networkController.save()
        return True

    ############ SLOTS for SimulationWorkbenchWidget ##############

    @Slot("")
    def on_actionSimulate_triggered(self):
        self.SimulationWorkbenchController.actionSimulate.trigger()

    @Slot("")
    def on_actionComputeSensitivityOverview_triggered(self):
        self.SimulationWorkbenchController.actionComputeSensitivityOverview.trigger()

    @Slot("")
    def on_actionCompute_Detailed_Sensitivities_triggered(self):
        self.SimulationWorkbenchController.actionCompute_Detailed_Sensitivities.trigger()

    @Slot("")
    def on_actionEstimateParameterValues_triggered(self):
        self.SimulationWorkbenchController.actionEstimateParameterValues.trigger()

    @Slot("")
    def on_actionAbout_triggered(self):
        self.aboutDialog = AboutDialog(self)
        self.aboutDialog.show()

    @Slot("")
    def on_actionShow_Results_Window_triggered(self):
        if self.SimulationWorkbenchController and self.SimulationWorkbenchController.resultsWindow:
            self.SimulationWorkbenchController.resultsWindow.show()
        else:
            logging.info("Cannot show Results Window. Nothing has been simulated, yet.")
Ejemplo n.º 9
0
 def about(self):
     AboutDialog(self).exec_()
Ejemplo n.º 10
0
 def about(self):
     about_dialog = AboutDialog(self)
     about_dialog.exec_()
Ejemplo n.º 11
0
class ProcessingManager:
    """ Processing plugin
    """
    def __init__(self, iface):
        self._iface = iface
        self.panel = None
        self.settings = None
        self.aboutDialog = None
        self.workflowBuilder = None

    def initGui(self):
        from PyQt4.QtCore import QObject, SIGNAL
        from PyQt4.QtGui import QMenu
        self.menu = QMenu()
        self.menu.setTitle(self.menu.tr("&Processing", "Processing"))

        # We only generate the panel & populate the menu when needed,
        # to increase our chances that the framework has been loaded.
        QObject.connect(self.menu, SIGNAL("aboutToShow()"), self.populateMenu)

        menuBar = self._iface.mainWindow().menuBar()
        menuBar.insertMenu(menuBar.actions()[-1], self.menu)

    def populateMenu(self):
        from panel import Panel
        from PyQt4.QtCore import QObject, SIGNAL
        from PyQt4.QtGui import QAction

        if not self.panel:
            self.panel = Panel(self._iface)
            self.panel.setVisible(False)
            self.panelAction = self.panel.toggleViewAction()

            self.menu.addAction(self.panelAction)

            self.settingsAction = QAction(
                self.menu.tr("&Settings", "Processing"),
                self._iface.mainWindow())
            self.menu.addAction(self.settingsAction)
            QObject.connect(self.settingsAction, SIGNAL("triggered()"),
                            self.showSettings)

            self.workflowBuilderAction = QAction(
                self.menu.tr("&Workflow builder", "Processing"),
                self._iface.mainWindow())
            self.menu.addAction(self.workflowBuilderAction)
            QObject.connect(self.workflowBuilderAction, SIGNAL("triggered()"),
                            self.showWorkflowBuilder)

            self.aboutAction = QAction(self.menu.tr("&About", "Processing"),
                                       self._iface.mainWindow())
            self.menu.addAction(self.aboutAction)
            QObject.connect(self.aboutAction, SIGNAL("triggered()"),
                            self.showAboutDialog)

    def unload(self):
        if self.panel:
            self.panel.setVisible(False)

    def showSettings(self):
        from settings import Settings
        if not self.settings:
            self.settings = Settings(self._iface.mainWindow())
        self.settings.setVisible(True)

    def showAboutDialog(self):
        from aboutdialog import AboutDialog
        if not self.aboutDialog:
            self.aboutDialog = AboutDialog(self._iface.mainWindow())
        self.aboutDialog.setVisible(True)

    def showWorkflowBuilder(self):
        from workflowBuilder import WorkflowBuilder
        if not self.workflowBuilder:
            self.workflowBuilder = WorkflowBuilder(self._iface)
        self.workflowBuilder.setVisible(True)
Ejemplo n.º 12
0
 def showAboutDialog(self):
     from aboutdialog import AboutDialog
     if not self.aboutDialog:
         self.aboutDialog = AboutDialog(self._iface.mainWindow())
     self.aboutDialog.setVisible(True)
Ejemplo n.º 13
0
    def aboutDialog(self, widget=None):
        from aboutdialog import AboutDialog

        AboutDialog()
Ejemplo n.º 14
0
 def on_menu_help_about_activate(self, widget):
     if not self.dialog_about:
         self.dialog_about = AboutDialog()
     self.dialog_about.show()
Ejemplo n.º 15
0
 def actionAboutTriggered(self):
     self.aboutDialog = AboutDialog(self)
     self.aboutDialog.show()
Ejemplo n.º 16
0
 def on_menuitem_about_activate(self, data=None):
     log.debug("on_menuitem_about_activate")
     from aboutdialog import AboutDialog
     AboutDialog().run()
Ejemplo n.º 17
0
class MultiEdit:

    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # create our GUI dialog
        self.dlg = MultiEditDialog()
        self.dlga = AboutDialog()
        #initialization for select features
        self.turnedoffLayers = []
        self.selectList = []
        self.cLayer = None
        self.provider = None
        self.saved = False
        self.countchange = 0
        selectall = 0
        
    def initGui(self):
        # Create action that will start plugin configuration
        self.action = QAction(QIcon(":/plugins/MultiEdit/multiedit.png"),"MultiEdit", self.iface.mainWindow())
        # connect the action to the run method
        QObject.connect(self.action, SIGNAL("triggered()"), self.run)
        #compatibility with 2.0 menu
        # check if Raster/Vector menu available
        if hasattr(self.iface, "addPluginToVectorMenu"):
            # Raster menu and toolbar available
            self.iface.addPluginToVectorMenu("&Pienocampo", self.action)
            self.iface.addVectorToolBarIcon(self.action)
        else:
            # there is no Raster/Vector menu, place plugin under Plugins menu as usual
            self.iface.addToolBarIcon(self.action)
            self.iface.addPluginToMenu("&Pienocampo", self.action)
                    
                
#Custom functions begin-------------------------------------------------------


 #checks if layer are vector type
    def checkvector(self):
        count = 0
        for name, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if layer.type() == QgsMapLayer.VectorLayer:
                count += 1
        return count

 #choose layer to process
    def chooselayer(self):
        layerlist=[]
        slist=[]
        self.dlg.ui.chosenlayer.clear()
        self.dlg.ui.txtFeedBack.clear()
        #self.dlg.ui.newvalue.clear()
        layers = self.iface.legendInterface().layers()
        for layer in layers:
            layerType = layer.type()
            if layerType == QgsMapLayer.VectorLayer:
                self.dlg.ui.chosenlayer.addItem(layer.name())
        #update other comboboxes
        self.set_select_attributes()
        self.set_unique_value()

 #choose attribute of present layers 
    def set_select_attributes(self):
        #clear comboboxes and linedits
        self.dlg.ui.Column.clear()
        self.dlg.ui.new_field.clear()
        if self.dlg.ui.chosenlayer.currentText() != "":
            layername = self.dlg.ui.chosenlayer.currentText()
            for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
                if selectlayer.name() == layername:
                    for field in selectlayer.dataProvider().fields():
                        self.dlg.ui.Column.addItem(field.name())
                        self.dlg.ui.new_field.addItem(field.name())
                    #once populated combobox with fields 
                    #names populate attributes values
                    self.set_unique_value()

    
    #choose attribute value
    def select_all(self):
        self.selectall = 0
        layername = self.dlg.ui.chosenlayer.currentText()
        #select layer
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.name() == layername:
                selectlayer.setSelectedFeatures([])
                selectlayer.invertSelection()
                self.selectall = 1


    def set_select_value(self):
        self.dlg.ui.oldattribute.clear()
        column = self.dlg.ui.Column.currentText()
        layername = self.dlg.ui.chosenlayer.currentText()
        #output = ""
        #select layer
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.name() == layername:
                provider = selectlayer.dataProvider()
                #select field and fetch values
                for field in provider.fields():
                    if field.name() == column:
                        request = QgsFeatureRequest().setSubsetOfAttributes()
                        for f in selectlayer.getFeatures():
                            attrs = f.attributes()
                            for attr in attrs:
                                if attr != None:
                                    self.dlg.ui.oldattribute.addItem(attr)

 
 #find unique values in layer feature classification 
    def set_unique_value(self):
        #pyqtRemoveInputHook()
        #pdb.set_trace()
        self.dlg.ui.oldattribute.clear()
        uniquelayer = self.dlg.ui.chosenlayer.currentText()
        uniquecolumn = self.dlg.ui.Column.currentText()
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.name() == uniquelayer:
                uniqueprovider = selectlayer.dataProvider()
                list = []
                if (uniqueprovider):
                    fields = uniqueprovider.fields()
                    for field in fields:
                        if field.name() == uniquecolumn:
                            id = fields.indexFromName(field.name())
                            uniquevalue = uniqueprovider.uniqueValues(id)
                            for uv in uniquevalue:
                                self.dlg.ui.oldattribute.addItem(unicode(uv))

    #Select features to process
    def select_features(self):
        #pyqtRemoveInputHook()
        #pdb.set_trace()
        provider = None
        #clear any feature from list...
        self.selectList = []
        #let's begin
        #retrieve comboboxes data
        currlayer = self.dlg.ui.chosenlayer.currentText()
        currcolumn = self.dlg.ui.Column.currentText()
        currfeature = self.dlg.ui.oldattribute.currentText()
        #turn selected layer off to ensure selection of all features in layer
        self.turn_layer_off(currlayer)
        nsel = 0
        #select data provider and layer
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.name() == currlayer:
                cLayer = selectlayer
                provider = cLayer.dataProvider()
                fields = provider.fields()
                index = None
                if cLayer:
                    for field in fields:
                        if field.name() == currcolumn:
                            #navigates through the features and select those whose name
                            #corresponds to the value in combo box
                            for f in cLayer.getFeatures():
                                attrs = f.attributes()
                                for attr in attrs:
                                    if unicode(attr) == currfeature:#check string instead of number
                                        self.selectList.append(f.id())
        # make the actual selection
        if self.selectList:
            cLayer.setSelectedFeatures(self.selectList)
            nsel = cLayer.selectedFeatureCount()
            
        #some info in the text browser to know what's going on
        self.dlg.ui.txtFeedBack.setText(unicode(nsel)+" Feature/s selected"+"\nin Layer--> " + cLayer.name() + "\nin Field--> " + currcolumn + "\nValue to be modified--> " + currfeature)
 
    def change_to_any(self):#change values to any fields at the corresponding row attribute
        self.countchange = 0
        layername = self.dlg.ui.chosenlayer.currentText()
        val = self.get_new_value()
        col_new = self.dlg.ui.new_field.currentText()
        currfeature = self.dlg.ui.oldattribute.currentText()
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.name() == layername:
                layer = selectlayer
        if val == "":
            QMessageBox.warning(None, "Warning","New attribute value is empty or null \n  Please type in one!")
            return
        else:
            #initialize variables and retrieve field id and change attribute value of selected 
            #feature ids  
            nF = 0
            ncol_new = 0
            if(layer):
                layer.startEditing()
                nF = layer.selectedFeatureCount()
                fields = layer.dataProvider().fields()
                for field in fields:
                    if field.name() == col_new:
                        ncol_new = fields.indexFromName(field.name())
                #some information in the textBrowser
                self.dlg.ui.txtFeedBack.setText("Field name: " + col_new + " - Field ID " + unicode(ncol_new) + "\nNumber of Features to modify--> "+ unicode(nF) +"\nValue to be written--> "+ unicode(val))
                if nF >0:
                    fields = layer.dataProvider().fields()
                    for field in fields:
                        if field.name() == col_new:
                            #write the value to all the rows in a field 
                            if self.selectall > 0:
                                idx = fields.indexFromName(field.name())#retrieve field index from name
                                for f in layer.getFeatures():
                                    attrs = f.attributes()
                                    for attr in attrs:
                                        feat = f.id()
                                        layer.changeAttributeValue(feat, idx ,val)
                                        self.countchange+=1
                            else:
                                idx = fields.indexFromName(field.name())#retrieve field index from name
                                for f in layer.getFeatures():
                                    attrs = f.attributes()
                                    for attr in attrs:
                                        #write the value to only matching old attribute value of a field 
                                        if unicode(attr) == currfeature:#convert anything to unicode string to match unique values 0.5
                                            feat = f.id()
                                            layer.changeAttributeValue(feat, idx ,val)
                                            self.countchange+=1
                else:
                    QMessageBox.critical(None,"Error", "Please select at least one feature from current layer")
            else:
                QMessageBox.critical(None,"Error","Please select a layer")
        return self.countchange

    def get_field(self):
        Name = self.dlg.ui.newfield.text()
        return Name
    
    def check_unique_fields(self, fields, newfieldname):
        for i in fields:
            confront = fields[i].name()
            self.dlg.ui.txtFeedBack.append("Searching fields for:  "+unicode(confront))
            if confront == newfieldname:
                unique = 1
            else:
                unique = 0
        return unique

    def create_new_field(self):
        #create new field in layer table
        #pyqtRemoveInputHook()
        #pdb.set_trace()
        layername = self.dlg.ui.chosenlayer.currentText()
        #choose layer
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.name() == layername:
                layer = selectlayer
                provider = layer.dataProvider()
                fields = provider.fields()
                nF = fields.count()
                self.dlg.ui.txtFeedBack.append(unicode(nF)+" fields found in layer.")
                #used to start from 0
                newfieldID=nF-1
                newfieldui = self.dlg.ui.newfield.text()
                if newfieldui == (""):
                    QMessageBox.critical(None,"MutiEdit","Please provide a non null field name")
                    return
                else:
                    newfieldname = self.get_field()
                    unique = 0 
                    for field in fields:
                        confront = field.name()
                        self.dlg.ui.txtFeedBack.append("Searching fields names for:  "+unicode(confront))
                        if confront == newfieldname:
                            unique = 1
                    if unique == 1:
                        QMessageBox.information(None, "MultiEdit","Field name already present in layer, provide another name...")
                        return
                    else:
                        layer.startEditing()
                        newfieldtype = self.dlg.ui.fieldtype.currentText()
                        self.dlg.ui.txtFeedBack.append("Creating new field: "+unicode(newfieldname)+" , Type  "+unicode(newfieldtype))
                        if newfieldtype == "Int":
                            provider.addAttributes ([QgsField(newfieldname,QVariant.Int,"Integer",10,0)])
                        if newfieldtype == "String":
                            provider.addAttributes ([QgsField(newfieldname,QVariant.String,"String",255,0)])
                        if newfieldtype == "Double":
                            provider.addAttributes ([QgsField(newfieldname,QVariant.Double, "Real", 32,2)])
                layer.commitChanges()
                layer.reload()
                #self.dlg.ui.newfield.clear()
        return

 #Clear selected vector features 
    def clearselection(self):
        self.dlg.ui.txtFeedBack.clear()
        clearlist = []
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.type() == QgsMapLayer.VectorLayer:
                selectlayer.setSelectedFeatures(clearlist)

    def show_table(self):
        #shows attribute table of chosen layer 
        table_layer=self.dlg.ui.chosenlayer.currentText()
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.name() == table_layer:
                show_layer_t = selectlayer
                self.iface.showAttributeTable(show_layer_t)
            
    
    def get_new_value(self):
        new_val = self.dlg.ui.newvalue.text()
        return new_val

    def turn_layer_off(self, loadedlayer):
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.name() == loadedlayer:
                theloadedlayer = selectlayer
                legend = self.iface.legendInterface()
                #access legendInteface class to determine if a layer is visible
                #then set it unvisible and add layer to a list
                if (legend.isLayerVisible(theloadedlayer)):
                    legend.setLayerVisible(theloadedlayer, False)
                    self.turnedoffLayers.append(selectlayer)
        
    def turn_layer_on (self, unloadedlayer):
        #access legendInterface class and turn unloadelayer layer on
        legend = self.iface.legendInterface()
        legend.setLayerVisible(unloadedlayer, True)

    def restore_visibility(self):
        #pick turned off layers from a list and set them visible
        if self.turnedoffLayers != []:
            for i in range(len(self.turnedoffLayers)):
                self.turn_layer_on(self.turnedoffLayers[i])
        else:
            return

    def exit(self):
        #pyqtRemoveInputHook()
        #pdb.set_trace()
        self.clearselection()
        #disconnect QT objects 
        QObject.disconnect(self.dlg.ui.chosenlayer, SIGNAL("currentIndexChanged(QString)"), self.clearselection)
        QObject.disconnect(self.dlg.ui.create_new_field, SIGNAL("clicked(bool)"), self.newfield_connect)
        QObject.disconnect(self.dlg.ui.select, SIGNAL("clicked(bool)"), self.select_features)
        QObject.disconnect(self.dlg.ui.all, SIGNAL("clicked(bool)"), self.select_all)
        QObject.disconnect(self.dlg.ui.unselect, SIGNAL("clicked(bool)"), self.clearselection)
        QObject.disconnect(self.dlg.ui.save, SIGNAL("clicked(bool)"), self.save_edits)
        QObject.disconnect(self.dlg.ui.show_t, SIGNAL("clicked(bool)"), self.show_table)
        QObject.disconnect(self.dlg.ui.change_another, SIGNAL("clicked(bool)"), self.change_to_any)
        QObject.disconnect(self.dlg.ui.Exit, SIGNAL("clicked(bool)"), self.exit)
        QObject.disconnect(self.dlg.ui.about, SIGNAL("clicked(bool)"), self.doabout )
        #turn on layers turned off by turn_layer_off
        self.restore_visibility()
        if (self.saved == False and self.countchange > 0):
            self.iface.messageBar().pushMessage("MultiEdit","Remember to review the changes and then save the edits. Thank you", level=QgsMessageBar.INFO)
        return

    def save_edits(self):
        self.saved = False
        #chose layer name to check in iteration
        layername = self.dlg.ui.chosenlayer.currentText()
        #browse layers in project to find matching items, select layer and if started editing
        #commit changes...
        for name, selectlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if selectlayer.name() == layername:
                if (selectlayer.isEditable()):
                    selectlayer.commitChanges()
                    #show result in textBrowser
                    self.dlg.ui.txtFeedBack.setText("Edits saved in Layer--> "+ layername)
                    self.saved = True
                    #check for unsaved layers set to 0...
                    self.countchange = 0
        #update comboboxes
        self.set_unique_value()
                    
        return self.saved
    
    def newfield_connect(self):
        self.create_new_field()
        self.set_select_attributes()
        return

    def doabout(self):
        self.dlga.show()

#Custom function end-------------------------------------------------------------------------------------------------------------------

    def unload(self):#to remove <2.0 compatibility!!!
        #compatibility with 2.0 menu
        # check if Raster/Vector menu is available and remove buttons from appropriate
        # menu and toolbar
        if hasattr(self.iface, "addPluginToVectorMenu"):
            self.iface.removePluginVectorMenu("&Pienocampo",self.action)
            self.iface.removeVectorToolBarIcon(self.action)
        else:
            self.iface.removePluginMenu("&Pienocampo",self.action)
            self.iface.removeToolBarIcon(self.action)
            
            
# run method that performs all the real work----------------------------------------------------------------------

    def run(self):
        #initial check if no vector layer no party...
        self.countchange = 0
        self.turnedoffLayers = []
        self.saved = None
        self.selectall = 0
        check = 0
        check = self.checkvector()
        if check == 0:
            self.iface.messageBar().pushMessage("MultiEdit","No vector layers \n Please load some, then reload plugin", level=QgsMessageBar.CRITICAL, duration=3)
            return
        else:
            boolvar ="YES"
            #Initial comboboxes filling
            self.chooselayer()
            #pyqtRemoveInputHook()
            #pdb.set_trace()
            #Connect to change in layer combobox and column combobox and execute
            #information retrieving procedures
            QObject.connect(self.dlg.ui.chosenlayer, SIGNAL("currentIndexChanged(QString)"), self.set_select_attributes)
            self.set_select_attributes()
            #every change in layer choice clears selection anyway
            QObject.connect(self.dlg.ui.chosenlayer, SIGNAL("currentIndexChanged(QString)"), self.clearselection)
            #populate attribute values combobox
            #2nd version stable with unique values
            self.set_unique_value()
            #Connection for 2nd version
            #QObject.connect(self.dlg.ui.Column, SIGNAL("currentIndexChanged(QString)"), self.set_unique_value)
            QObject.connect(self.dlg.ui.Column, SIGNAL("activated(QString)"), self.set_unique_value)#changed  
            #Connection for 1st version
            #QObject.connect(self.dlg.ui.Column, SIGNAL("currentIndexChanged(QString)"), self.set_select_value)
            #self.set_select_value()
            #Plaintext event
            QObject.connect(self.dlg.ui.newvalue, SIGNAL("textChanged(QString)"), self.get_new_value)
            #Buttons events
            QObject.connect(self.dlg.ui.select, SIGNAL("clicked(bool)"), self.select_features)
            QObject.connect(self.dlg.ui.all, SIGNAL("clicked(bool)"), self.select_all)
            QObject.connect(self.dlg.ui.unselect, SIGNAL("clicked(bool)"), self.clearselection)
            QObject.connect(self.dlg.ui.save, SIGNAL("clicked(bool)"), self.save_edits)
            QObject.connect(self.dlg.ui.show_t, SIGNAL("clicked(bool)"), self.show_table)
            QObject.connect(self.dlg.ui.create_new_field, SIGNAL("clicked(bool)"), self.newfield_connect)
            QObject.connect(self.dlg.ui.change_another, SIGNAL("clicked(bool)"), self.change_to_any)#the real thing 2...
            self.dlg.show()
            self.dlg.ui.txtFeedBack.append("VECTOR LAYER? -->"+ boolvar)
            self.dlg.ui.txtFeedBack.append("Saved layers? -->"+unicode(self.saved))
            self.dlg.ui.txtFeedBack.append("Turned off layer by MultiEdit"+unicode(self.turnedoffLayers))
            QObject.connect(self.dlg.ui.Exit, SIGNAL("clicked(bool)"), self.exit)
            #----About dialog
            QObject.connect(self.dlg.ui.about, SIGNAL("clicked(bool)"), self.doabout )
Ejemplo n.º 18
0
 def on_actionAbout_triggered(self):
     self.aboutDialog = AboutDialog(self)
     self.aboutDialog.show()
Ejemplo n.º 19
0
class BioParkinController(QMainWindow, Ui_MainWindow):
    """
    This is the heart of BioParkin. It sets up the general UI
    (MainWindow, some Views, ...), handles creation and management of
    individual network windows, and instantiates needed services
    (for easy access to data, status bar, ...).

    This class inherits from QMainWindow for its functionality and from
    the (automatically generated) Ui_MainWindow for the design of the UI
    (including the self.setupUi() method).

    @param parent: The standard Qt parent.
    @type parent: QWidget

    @organization: Zuse Insitute Berlin
    """

    __version__ = "1.2.13"
    __author__ = "Moritz Wade & Thomas Dierkes"
    __contact__ = "[email protected] or [email protected]"
    __copyright__ = "Zuse Institute Berlin 2011"

    newNetworkWindowCreated = Signal()
    networkWindowRaised = Signal()
    activeModelChanged = Signal(ModelController)
    modelClosed = Signal(ModelController)


    def __init__(self, args, parent=None):
        """
        This initialization does a lot of stuff. :)

        * State variables are set up
        * Views are created and tied to UI parts (e.g. Docks)
        * Logging is set up
        * Services (StatusBar, Data, ...) are started
        * Necessary slots are connected

        """
        super(BioParkinController, self).__init__(parent)

        #locale.setlocale(locale.LC_ALL, 'de_DE')
        #        locale.setlocale(locale.LC_ALL, 'deu_deu')

        self.startTime = time.localtime()


        # set file logger
        self.rotatingFileHandler = logging.handlers.RotatingFileHandler(_LOG_FILENAME,
                                                       maxBytes=1000000,
                                                       backupCount=5)
        self.rotatingFileHandler.setFormatter(logging.Formatter("%(asctime)s | %(levelname)s | %(message)s"))
        self.logger = logging.getLogger() #gets root logger
        self.logger.addHandler(self.rotatingFileHandler)

        # Status bar logger
        self.statusBarLoggingHandler = StatusBarLoggingHandler()
        self.statusBarLoggingHandler.setLevel(logging.INFO) # only log on info level
        self.logger.addHandler(self.statusBarLoggingHandler)


        # set GUI logger
        #        self.loggingView = QtLoggingView(self)
        #        loggingHandler = QtLoggingHandler(self.loggingView)
        #        loggingHandler.setLevel(logging.INFO)
        #        self.logger.addHandler(loggingHandler)

        # filling log dock area (was set up in QtDesigner)
        #        self._logDockWidget.setWidget(self.loggingView)
        #        self._logDockWidget.hide()


        # parse command line arguments
        parser = OptionParser()
        parser.add_option("-d", "--debug",
                  action="store_true", dest=OPTION_DEBUG, default=False,
                  help="Include debugging information in console and file log")
        self.options, args = parser.parse_args()

        self.optionsService = OptionsService()
        self.optionsService.setDebug(self.options.debug)

        # set logging options
        if self.options.debug:
            self.logger.setLevel(logging.DEBUG)
            self.rotatingFileHandler.setLevel(logging.DEBUG)
            logging.info("Debug logging active.")
        else:
            self.logger.setLevel(logging.INFO)
            self.rotatingFileHandler.setLevel(logging.INFO)
            logging.info("Debug logging not active.")

        logging.debug("Starting BioPARKIN... %s" % self.startTime)

        ##### LOGGING #####
        logging.info("BioPARKIN started (version %s)" % BioParkinController.__version__)
        logging.info("Command line arguments: %s" % args)
        logging.info("Python version: %s" % sys.version)
#        logging.info("SIP version: %s" % sip.SIP_VERSION_STR)
        #logging.info("PyQt version: %s" % PYQT_VERSION_STR)
        logging.info("PySide version: %s" % PySide.__version__)
        logging.info("libSBML version: %s" % LIBSBML_VERSION_STRING)
        logging.info("Matplotlib version: %s" % matplotlib.__version__)
#        logging.info("NetworkX version: %s" % networkx.__version__)
        logging.info("Python Image Library version: %s" % Image.VERSION)






        self.setupUi(self)
        self._mdiArea.hide()
        self.setWindowTitle("BioPARKIN v%s" % BioParkinController.__version__)

        # restore previous settings
        settings = QSettings()
        try:
            self.recentFiles = settings.value("RecentFiles", [])

            # handles the case if only one file is in the "list" in Linux (it's retrieved as unicode string in this case)
            if type(self.recentFiles) is str or type(self.recentFiles) is unicode:
                self.recentFiles = [self.recentFiles]
                
            logging.info("Recently opened files: %s" % self.recentFiles)
        except:
            logging.warning("Can't access list of recently opened files. Resetting the list.")
            self.recentFiles = []

        self.updateFileMenu()
        self.aboutDialog = None

        geometry = settings.value("Geometry")
        if geometry:
            self.restoreGeometry(geometry)

        state = settings.value("MainWindow/State")
        if state:
            self.restoreState(state)


        self.ModelControllers = {}
#        self.SubWindowToModelControllers = {}
#        self.NetworkWindowCount = 0
#        self.ActiveNetworkWindow = None
        self.ActiveModelController = None
#        self.networkSubWindows = {}

        self.integrator = None
        self.odeViewer = None

        self.ModelView = ModelView(self.masterDetailSplitter, self)
        self.ModelTreeView = SBMLEntityWidget(self.masterDetailSplitter)
        self.EntityTableView = EntityTableView(self.masterDetailSplitter)
#        self.masterDetailSplitter.widget(0).destroy()
#        logging.debug("1st Child of Splitter: %s" % self.masterDetailSplitter.widget(0))

        self.mainWindowViews = [self.ModelTreeView, self.EntityTableView]   #used to iterate over Views



        # set up Data Service and Data Viewer
        datahandling.parkinController = self
        self.dataService = DataService()


        # debugging#############
        BASE_PATH = reduce(lambda l, r: l + os.path.sep + r,
                           os.path.dirname(os.path.realpath(__file__)).split(os.path.sep)[:-1])
        #BASE_PATH = os.path.dirname(os.path.realpath(__file__))

        # add ../../templates (relative to the file (!) and not to the CWD)
        dataPath = os.path.join(BASE_PATH, "data")
        #######################

        self.SimulationWorkbenchController = SimulationWorkbenchController(parent=None, parkinController=self)
        self.mainTabWidget.addTab(self.SimulationWorkbenchController, "Workbench")




        # hook up status bar with progress service (that threads can connect to)
        self.statusBarService = StatusBarService(self.statusBar()) # first time, service is instantiated => give statusBar reference!
#        self.statusBarService.setStatusBar(self.statusBar())
        self.progressBarService = ProgressBarService(self, self.statusBarService)

        self.statusBarLoggingHandler.setStatusBar(self.statusBarService)

        self.warningsService = WarningService.getInstance()
        self.warningsDialog = WarningsDialog(self, self.actionShow_Warnings, self.warningsService)


        # register signals

#        self.connect(self._mdiArea, SIGNAL("subWindowActivated(QMdiSubWindow*)"), self.on_networkwindow_raised)
        self.activeModelChanged.connect(self.on_activeModelChanged)
#        self.activeModelChanged.connect(self.selectNetworkView) # put into own method -> easier to put in own class later
        self.modelClosed.connect(self.on_modelClosed)
#        self.modelClosed.connect(self.closeNetworkWindow) # put into own method -> easier to put in own class later
        self.menuFile.aboutToShow.connect(self.updateFileMenu)


        # for debugging
        self.dummyThread = None

        try:    # try to set correct taskbar icon in Windows 7
            myappid = 'ZIB.BioPARKIN' # arbitrary string
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
        except:
            pass


    def updateFileMenu(self):
        """
        Updates the file menu dynamically, so that recent files can be shown.
        """
        self.menuFile.clear()
#        self.menuFile.addAction(self.actionNew)    # disable for now
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionSave)
        self.menuFile.addAction(self.actionSave_as)
        self.menuFile.addAction(self.actionClose_Model)

        recentFiles = []
        for filename in self.recentFiles:
            if QFile.exists(filename):
                recentFiles.append(filename)

        if len(self.recentFiles) > 0:
            self.menuFile.addSeparator()
            for i, filename in enumerate(recentFiles):
                action = QAction("&%d %s" % (i + 1, QFileInfo(filename).fileName()), self)
                action.setData(filename)
                action.setStatusTip("Opens recent file %s" % QFileInfo(filename).fileName())
                action.setShortcut(QKeySequence(Qt.CTRL | (Qt.Key_1+i)))
                action.triggered.connect(self.load_model)
                #self.connect(action, SIGNAL("triggered()"), self.load_model)
                self.menuFile.addAction(action)

        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionQuit)
        #pass

    def new_model(self):
        """
        Just calls load_model without a filename
        to create a new model.
        """
        #self.load_model(filename = None)
        # debugging
        #self.load_model(filename = "/home/bzfwadem/bin/SBMLeditor/data/biomodels-release-20090902/curated/BIOMD0000000231.xml")

        BASE_PATH = reduce(lambda l, r: l + os.path.sep + r,
                           os.path.dirname(os.path.realpath(__file__)).split(os.path.sep)[:-1])
        #BASE_PATH = os.path.dirname(os.path.realpath(__file__))

        # add ../../templates (relative to the file (!) and not to the CWD)
        dataPath = os.path.join(BASE_PATH, "data")


        #self.load_model(filename = "/home/bzfwadem/workspace/BioParkin/data/gyncyc_0.2.sbml")
        #self.load_model(filename=os.path.join(dataPath, "femcyc/pfizer02.xml"))


    def load_model(self, filename=None):
        """
        Loads a given SBML file, thereby creating a new subwindow
        on the main MDI Area.
        If filename is None, it creates a new model.

        There are a lot of reference variables, so that the system knows the
        currently active subwindow, etc.

        @param filename: The filename of the model. If None, a new model is created.
        @type filename: str
        """
        if not filename:
            action = self.sender()
            if type(action) == QAction:
                filename = action.data()
            else:
                return


        # note: this has been (temporarily added) to allow only one file to be open at the same time
        # We will probably change this behaviour again later, once we have decided how to handle
        # multiple-model results, etc. intelligently
        if len(self.ModelControllers) > 0:

            # show warning dialog
            msgBox = QMessageBox()
            infoText =\
            """<b>Another model is currently loaded.</b><br>
            """
            msgBox.setText(infoText)
            infoTextShort = "Do you want to save the current model (you will be prompted to enter a new filename)?"
            msgBox.setInformativeText(infoTextShort)
            msgBox.setWindowTitle(infoTextShort)
            msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard)
            msgBox.setDefaultButton(QMessageBox.Save)
            msgBox.setIcon(QMessageBox.Warning)
            #        msgBox.setWindowIcon(None)
            clickedButton = msgBox.exec_()

            if clickedButton == QMessageBox.Save:
                self.actionSave_as.trigger()


            for modelController in self.ModelControllers.values(): # close all models (in theory, there should be only one :)
                self.modelClosed.emit(modelController)



#        self.NetworkWindowCount += 1
#        self.setStatusTip("Opening file %s..." % filename)
        self.statusBar().showMessage("Opening file %s..." % filename, 2000)
        modelController = ModelController(filename=filename, views=self.mainWindowViews)

#        # create NetworkViewController
#        networkViewController = NetworkViewController(modelController=modelController)
#        networkView = networkViewController.createNetworkView(self) # sets networkController.networkView internally
#        networkView.setMinimumSize(400, 300)
#        modelController.setViews(networkViewController=networkViewController)

#        # Create Subwindow to hold the NetworkView
#        subWindow = QMdiSubWindow(parent=self._mdiArea)
#        networkViewController.subWindow = subWindow
#        subWindow.setAttribute(Qt.WA_DeleteOnClose)
#        subWindow.setWidget(networkView)
#        subWindow.setOption(QMdiSubWindow.RubberBandResize, True)
#        self._mdiArea.addSubWindow(subWindow)
#        subWindow.activateWindow()
#
#        # why do these not work to emit a self._mdiArea.networkWindowActivated Signal?
#        #        self._mdiArea.setActiveSubWindow(subWindow)
#        #        self._mdiArea.activateNextSubWindow()
#        #        self._mdiArea.subWindowActivated()
#
#        subWindow.show()    # important!
#        networkView.show()

        # handle references
        filename = modelController.filename
#        self.SubWindowToModelControllers[subWindow] = modelController
#        self.networkSubWindows[modelController] = subWindow #networkView
        self.ModelControllers[filename] = modelController
#        self.ActiveNetworkWindow = networkWindow
        self.ActiveModelController = modelController

#        self.connectNetworkWindowSignals(networkView, subWindow)

        # emit custom Signal so that e.g. Simulationworkbench are notified of the new subwindow
#        self.newNetworkWindowCreated.emit()
        self.activeModelChanged.emit(modelController)

        # handle recent files list
        if filename in self.recentFiles:
            self.recentFiles.remove(filename)
        self.recentFiles.insert(0, filename)
        if len(self.recentFiles) > NUM_RECENT_FILES:    # cap list at length of NUM_RECENT_FILES
            self.recentFiles = self.recentFiles[:NUM_RECENT_FILES]

#    def getMdiArea(self):
#        return self._mdiArea

#    @Slot("QWidget")
#    def connectNetworkWindowSignals(self, networkWindow, subWindow):
#        """
#        Connect the signals of network windows (e.g. network is about to be destroyed, etc.)
#
#        @param networkWindow: A network view
#        @type networkWindow: NetworkView
#
#        @param subWindow: A Qt QMdiArea sub window
#        @type subWindow: QMdiSubWindow
#        """
#        #self.connect(button3, SIGNAL("clicked()"),    lambda who="Three": self.anyButton(who))
#
#        self.connect(networkWindow, SIGNAL("destroyed()"),
#                     lambda who=networkWindow: self.on_networkwindow_destroyed(who))

    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat('Filename'):
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        # get filename
        uris = event.mimeData().urls()  # support opening several models at once

        # note: uncomment this, to enable drag'n'dropping of multiple models, again
#        for uri in uris:
#            filename = uri.toLocalFile()
#            #open file
#            self.load_model(filename)
        filename = uris[0].toLocalFile()
        self.load_model(filename)
        if len(uris)>1:
            logging.info("You dragged more than one model to BioPARKIN. Currently, only one model is supported to be opened at the same time. Only the first dragged model was loaded.")

    def on_modelClosed(self, modelController):
        """
        Whenever the Signal self.modelClosed is emitted, this
        method is called.
        It removes the modelController of the closed model from
        the managemend dicitionary and updates all local Views.
        """
        if not modelController:
            logging.info("Can't close the model. No model selected.")

            #### abusing this place for testing ####
#            self.dummyThread = DummyProgressThread()
#            self.progressBarService.connect_to_thread(self.dummyThread)
#            self.dummyThread.start()

#            self.dummyThread = DummyThrobberThread()
#            self.progressBarService.connect_to_thread(self.dummyThread)
#            self.dummyThread.start()
            

            ########################################

            return
        if self.ModelControllers.has_key(
            modelController.filename): # we do this to remove the model controller from the management dict
            self.ModelControllers.pop(modelController.filename)

        if len(self.ModelControllers) == 0:
#            self.dataService.remove_all_simulated_data()
            self.ActiveModelController = None
            for view in self.mainWindowViews:
                view.setModel(None)

#    def on_networkwindow_destroyed(self, networkWindow):
#        """
#        This is a slot. It's called to clean things up when a network
#        window is destroyed. Basically, it just gets the correct ModelController
#        and passes it on using the modelClosed signal of the BioPARKIN controller.
#
#        @param networkWindow: A network view
#        @type networkWindow: NetworkView
#        """
#        logging.debug("Destroying a NetworkWindow: %s" % networkWindow)
#        modelController = networkWindow.controller.modelController
#        self.modelClosed.emit(modelController)
#
#    def closeNetworkWindow(self, modelController):
#        if self.networkSubWindows.has_key(modelController): # might have been removed already
#            self.networkSubWindows.pop(modelController).close() #removes window from dict and closes it


    def on_activeModelChanged(self, activeModelController):
        """
        Whenever the active model changes, the appropriate Signal
        self.activeModelChanged should be emitted. When that is done, this method
        is called.
        """
        logging.info("Active Model: %s" % activeModelController.filename)
        if activeModelController is not None:
            self.ActiveModelController = activeModelController
            for view in self.mainWindowViews:
                view.setModel(self.ActiveModelController.proxyModel, mainModel=self.ActiveModelController.sbmlModel)
                view.setSelectionModel(self.ActiveModelController.selectionModel)

#    def selectNetworkView(self, modelController):
#        subwindow = self.networkSubWindows[modelController]
##        subwindow.show()
#        subwindow.raise_()
#        subwindow.activateWindow()
##        subwindow.setFocus()

#    def on_networkwindow_raised(self, subWindow):
#        """
#        This is a slot. It's called when a network window gets focus.
#        Some references have to be set, and most importantly, all the Views
#        have to be switched so that they use the data model behind the
#        newly focused network window.
#
#        @param subWindow: A sub window
#        @type subWindow: QMdiSubWindow
#        """
#        if subWindow is None:
#            return
#        if not self.SubWindowToModelControllers.has_key(subWindow):
#            return
#
#        activeModelController = self.SubWindowToModelControllers[subWindow]
##        self.ActiveNetworkWindow = self.ActiveModelController.getNetworkView()
#
##        self.on_activeModelChanged()
#        self.activeModelChanged.emit(activeModelController)
##        self.networkWindowRaised.emit()
#
##        logging.debug("Leaving on_networkwindow_raised()")


    @Slot("")
    def on_actionNew_triggered(self):
        """
        This is a slot. It's automatically connected to the actionNew
        created in the QtDesigner.
        """

        self.new_model()

    @Slot("")
    def on_actionOpen_triggered(self):
        """
        This is a slot. It's automatically connected to the actionOpen
        created in the QtDesigner.
        """
        homeDir = filehelpers.getHomeDir()

        filenameTuple = QFileDialog.getOpenFileName(parent=self,
                                               directory=homeDir,
                                               filter="SBML files (*.sbml *.xml)",
                                               caption="Open SBML file...")

        if filenameTuple and filenameTuple[0]: # if user presses cancel, the tuple exists but is two empty unicode strings.
            filename = filenameTuple[0]
            self.load_model(filename)
        else:
            logging.info("No file selected. Didn't load anything.")


    @Slot("")
    def on_actionClose_Model_triggered(self):
#        self.on_modelClosed(self.ActiveModelController)
        self.modelClosed.emit(self.ActiveModelController)

    @Slot("")
    def on_actionSave_triggered(self):
        """
        This is a slot. It's automatically connected to the actionSave
        created in the QtDesigner.
        """
        self.saveActiveNetwork(filename=None)

    @Slot("")
    def on_actionSave_as_triggered(self):
        """
        This is a slot. It's automatically connected to the actionSaveAs
        created in the QtDesigner.
        """
        if not self.ActiveModelController:
            logging.info("Can't save anything. No model loaded.")
            return
        filenameTuple = QFileDialog.getSaveFileName(parent=self,
            dir=self.ActiveModelController.filename,
            caption="Save as...",
            filter="SBML file (*.sbml)")
        if filenameTuple:
            self.saveActiveNetwork(filenameTuple[0])


    def saveActiveNetwork(self, filename=None):
        """
        Tell the currently active network controller to
        save to a file.

        @param filename: Filename of the network.
        @type filename: str
        """
        if self.ActiveModelController is None:
            logging.warning("No model loaded. Can't save anything.")
            return
        self.ActiveModelController.save(filename=filename)



    @Slot("")
    def on_actionShow_Data_Manager_triggered(self):
        """
        This is a slot. It's automatically connected to the actionShowDataManager
        created in the QtDesigner.
        """
        self.DataManagementController.show()


    @Slot("")
    def on_actionODEGenerator_triggered(self):
        """
        Open the ODE Generator information dialog.
        """
        if self.ActiveModelController and self.ActiveModelController.sbmlModel:
            self.odeViewer = ODEViewer(self, self.ActiveModelController.sbmlModel)
            self.odeViewer.show()
        else:
            logging.info("ODEs can't be shown. No model selected.")



    def closeEvent(self, event):
        """
        Override the close event to handle file saving.
        """
        if self.okToContinue(): # files will be saved in self.okToContinue()
            settings = QSettings()
            settings.setValue("Geometry", self.saveGeometry())
            settings.setValue("MainWindow/State", self.saveState())
            settings.setValue("RecentFiles", self.recentFiles)

            event.accept()
        else:
            event.ignore()

    def okToContinue(self):
        """
        Checks if it is ok to close the application.
        The user will be prompted to save files.

        @return: True, if it is ok to continue (e.g. close the app); False, otherwise
        @rtype: bool

        @todo: Make a smart save dialog to allow the user to save only certain files.
        """
        dirtyFilenames = []
        for filename, networkController in self.ModelControllers.items():
            if networkController.Dirty:
                dirtyFilenames.append(
                    networkController.filename)   # we don't use the filename key because it might be outdated
        if len(dirtyFilenames) == 0:    #nothing to save
            return True

        reply = QMessageBox.question(self,
                                     "BioParkin - Unsaved Changes",
                                     "Unsaved changes in these files:\n\n%s\n\nDo you want to save them?" % "\n".join(
                                         dirtyFilenames),
                                     buttons=QMessageBox.SaveAll | QMessageBox.Discard | QMessageBox.Cancel)
        if reply == QMessageBox.Cancel:
            return False
        elif reply == QMessageBox.SaveAll:
            for networkController in self.ModelControllers:
                if networkController.Dirty:
                    networkController.save()
        return True



    ############ SLOTS for SimulationWorkbenchWidget ##############


    @Slot("")
    def on_actionSimulate_triggered(self):
        self.SimulationWorkbenchController.actionSimulate.trigger()


    @Slot("")
    def on_actionComputeSensitivityOverview_triggered(self):
        self.SimulationWorkbenchController.actionComputeSensitivityOverview.trigger()

    @Slot("")
    def on_actionCompute_Detailed_Sensitivities_triggered(self):
        self.SimulationWorkbenchController.actionCompute_Detailed_Sensitivities.trigger()

    @Slot("")
    def on_actionEstimateParameterValues_triggered(self):
        self.SimulationWorkbenchController.actionEstimateParameterValues.trigger()


    @Slot("")
    def on_actionAbout_triggered(self):
        self.aboutDialog = AboutDialog(self)
        self.aboutDialog.show()


    @Slot("")
    def on_actionShow_Results_Window_triggered(self):
        if self.SimulationWorkbenchController and self.SimulationWorkbenchController.resultsWindow:
            self.SimulationWorkbenchController.resultsWindow.show()
        else:
            logging.info("Cannot show Results Window. Nothing has been simulated, yet.")
Ejemplo n.º 20
0
 def on_menu_help_about_activate(self, widget):
     if not self.dialog_about:
         self.dialog_about = AboutDialog()
     self.dialog_about.show()
Ejemplo n.º 21
0
 def on_actionAbout_triggered(self):
     self.aboutDialog = AboutDialog(self)
     self.aboutDialog.show()
Ejemplo n.º 22
0
class ProcessingManager:
    """ Processing plugin
    """
    def __init__(self, iface):
        self._iface = iface
        self.panel = None
        self.settings = None
        self.aboutDialog = None
        self.workflowBuilder = None
        
    def initGui(self):
        from PyQt4.QtCore import QObject, SIGNAL
        from PyQt4.QtGui import QMenu
        self.menu = QMenu()
        self.menu.setTitle(self.menu.tr("&Processing", "Processing"))

        # We only generate the panel & populate the menu when needed,
        # to increase our chances that the framework has been loaded.
        QObject.connect(self.menu, SIGNAL("aboutToShow()"),
            self.populateMenu)
        
        menuBar = self._iface.mainWindow().menuBar()   
        menuBar.insertMenu(menuBar.actions()[-1], self.menu)

    def populateMenu(self):
        from panel import Panel
        from PyQt4.QtCore import QObject, SIGNAL
        from PyQt4.QtGui import QAction
        
        if not self.panel:
            self.panel = Panel(self._iface)
            self.panel.setVisible(False)
            self.panelAction = self.panel.toggleViewAction()

            self.menu.addAction(self.panelAction)
            
            self.settingsAction = QAction(
                self.menu.tr("&Settings", "Processing"),
                self._iface.mainWindow())
            self.menu.addAction(self.settingsAction)
            QObject.connect(self.settingsAction,
                SIGNAL("triggered()"), self.showSettings)

            self.workflowBuilderAction= QAction(
                self.menu.tr("&Workflow builder", "Processing"),
                self._iface.mainWindow())
            self.menu.addAction(self.workflowBuilderAction)
            QObject.connect(self.workflowBuilderAction,
                SIGNAL("triggered()"), self.showWorkflowBuilder)

            self.aboutAction = QAction(
                self.menu.tr("&About", "Processing"),
                self._iface.mainWindow())
            self.menu.addAction(self.aboutAction)
            QObject.connect(self.aboutAction,
                SIGNAL("triggered()"), self.showAboutDialog)
    
    def unload(self):
        if self.panel:
            self.panel.setVisible(False)
            
    def showSettings(self):
        from settings import Settings
        if not self.settings:
            self.settings = Settings(self._iface.mainWindow())
        self.settings.setVisible(True)
    
    def showAboutDialog(self):
        from aboutdialog import AboutDialog
        if not self.aboutDialog:
            self.aboutDialog = AboutDialog(self._iface.mainWindow())
        self.aboutDialog.setVisible(True)
        
    def showWorkflowBuilder(self):
        from workflowBuilder import WorkflowBuilder
        if not self.workflowBuilder:
            self.workflowBuilder = WorkflowBuilder(self._iface)
        self.workflowBuilder.setVisible(True)
Ejemplo n.º 23
0
class SelectTools:

    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        self.canvas = self.iface.mapCanvas()
        self.dlg = AboutDialog()

    def initGui(self):
        #toolbar-----------------------------------------------------------------
        # Add toolbar 
        self.toolBar = self.iface.addToolBar("SelectTools")
        self.toolBar.setObjectName("SelectTools")
        
        #Get the tools external module version--
        self.selector = SelectAll(self.iface, self.toolBar)
        self.invselector = SelectInverse (self.iface, self.toolBar)
        #--
        """
        # Get the tools simple version---
        self.act1 = QAction(QIcon(":/plugins/SelectTools/icons/SelectAll.png"),"SelectAll", self.iface.mainWindow())
        self.act2 = QAction(QIcon(":/plugins/SelectTools/icons/SelectInverse.png"),"SelectInverse", self.iface.mainWindow())
        # connect the action to the run method
        QObject.connect(self.act1, SIGNAL("triggered()"), self.selectall)
        QObject.connect(self.act2, SIGNAL("triggered()"), self.selectinverse)
        self.toolBar.addAction(self.act1)
        self.toolBar.addAction(self.act2)
        #----
        """
        #/toolbar------------------------------------------------------------------
        
        #Menu items---------------------------------------------------------------
        self.menu = QMenu()
        self.menu.setTitle( QCoreApplication.translate("SelectTools","SelectTools"))
        #add here help or ther info gettable from menu...
        self.act3 = QAction( QCoreApplication.translate("SelectTools", "SelectAll" ), self.iface.mainWindow() )
        self.act4 = QAction( QCoreApplication.translate("SelectTools", "SelectInverse" ), self.iface.mainWindow() )
        self.about = QAction( QCoreApplication.translate("About", "About" ), self.iface.mainWindow() )
        self.menu.addActions( [self.act3, self.act4, self.about]) 
        menu_bar = self.iface.mainWindow().menuBar()
        actions = menu_bar.actions()
        lastAction = actions[ len( actions ) - 1 ]
        menu_bar.insertMenu(lastAction, self.menu)
        """        
        #internal fx version---
        QObject.connect( self.act3, SIGNAL("triggered()"), self.selectall )
        QObject.connect( self.act4, SIGNAL("triggered()"), self.selectinverse )
        #---
        """
        #external fx version---
        QObject.connect( self.act3, SIGNAL("triggered()"), self.dosel )
        QObject.connect( self.act4, SIGNAL("triggered()"), self.doinv )
        QObject.connect( self.about, SIGNAL("triggered()"), self.doabout )
        #---
        
        #/Menu Items---------------------------------------------------------------

    def dosel(self):
        MenuSelectAll(self.iface)
        
    def doinv(self):
        MenuSelectInverse(self.iface)

    def doabout(self):
        self.dlg.show()
     
         
    def unload(self):
        # Remove the plugin menu item and icon
        del self.toolBar
        del self.menu
        

    def selectall(self):
        #browse layer registry and retrieve vector layers----------------------------------------------------
        layermap = QgsMapLayerRegistry.instance().mapLayers()
        layerlist = []
        for name, layer in layermap.iteritems():
            if layer.type() == QgsMapLayer.VectorLayer:
                layerlist.append(layer)
        #----------------------------------------------------------------------------------------------------
        # if the layer list is not empty retrieve legend Interface layer properties to check if the layer is visible
        if layerlist!= []:
            legend = self.iface.legendInterface()
            layer = self.iface.activeLayer()
            if (legend.isLayerVisible(layer)):
                    # if the active layer is visible check for already selected features
                    n = layer.selectedFeatureCount()
                    if n >0:
                        # if there are selected features deselect them and invert selection
                        layer.setSelectedFeatures([])
                        layer.invertSelection()
                    else:
                        # since there isn't any selected feature simply invert selection
                        layer.invertSelection()    
    # run method that performs all the real work

    def selectinverse(self):
        #browse layer registry and retrieve vector layers----------------------------------------------------
        layermap = QgsMapLayerRegistry.instance().mapLayers()
        layerlist = []
        for name, layer in layermap.iteritems():
            if layer.type() == QgsMapLayer.VectorLayer:
                layerlist.append(layer)
        #----------------------------------------------------------------------------------------------------
        # if the layer list is not empty retrieve legend Interface layer properties to check if the layer is visible
        if layerlist!= []:
            legend = self.iface.legendInterface()
            layer = self.iface.activeLayer()
            if (legend.isLayerVisible(layer)):
                    # if the active layer is visible check for already selected features
                    n = layer.selectedFeatureCount()
                    if n >0:
                        # invert selection
                        #layer.setSelectedFeatures([])
                        layer.invertSelection()
                    else:
                        # since there isn't any selected feature simply invert selection is not useful...
                        QMessageBox.information(None,"SelectInverse","No features selected in active layer!!!")
                        pass
Ejemplo n.º 24
0
 def about(self):
     dlg = AboutDialog()
     dlg.exec_()
Ejemplo n.º 25
0
 def onAbout(self, event):
     dlg = AboutDialog(self)
     dlg.CenterOnScreen()
     dlg.ShowModal()
     dlg.Destroy()