Example #1
0
    def _build_sms_menu(self, pathlist, treeview):
        selected = self._get_selected_objects(treeview)

        menu = gtk.Menu()

        if len(selected["objs"]) == 1:
            # only show reply or send from storage when only one SMS is sel
            obj = selected["objs"][0]

            item = None

            if obj.where <= STO_INBOX:
                item = gtk.MenuItem(_("_Reply"))
                callback = self._send_sms_to_contact
            elif obj.where == STO_DRAFTS:
                item = gtk.MenuItem(_("_Send"))
                callback = self._send_sms_from_storage
            elif obj.where == STO_SENT:
                # if the SMS is in STO_SENT then only deleting is allowed
                pass

            if item:
                item.connect("activate", callback, treeview)
                item.show()
                menu.append(item)

        item = gtk.ImageMenuItem(_("_Delete"))
        img = gtk.image_new_from_stock(gtk.STOCK_DELETE, gtk.ICON_SIZE_MENU)
        item.set_image(img)
        item.connect("activate", self._delete_rows, pathlist, treeview)
        item.show()
        menu.append(item)

        return menu
Example #2
0
def ask_puk2_dialog(parent):
    logger.debug("Asking for PUK2")
    return generic_puk_dialog(
            _("PUK2 required"),
            _("Please, insert the PUK2 and PIN of your SIM card"),
            parent, puk_regexp=re.compile('^\d{8}$'),
            pin_regexp=re.compile('^\d{4,8}$'))
Example #3
0
    def get_trayicon_menu(self):
        menu = gtk.Menu()

        item = gtk.ImageMenuItem(_("About"))
        img = gtk.image_new_from_stock(gtk.STOCK_ABOUT, gtk.ICON_SIZE_MENU)
        item.set_image(img)
        item.connect("activate", self.on_about_menuitem_activate)
        item.show()
        menu.append(item)

        item = gtk.ImageMenuItem(_("Preferences"))
        item.set_image(gtk.image_new_from_stock(gtk.STOCK_PREFERENCES,
                                                gtk.ICON_SIZE_MENU))
        item.connect("activate", self.on_preferences_menu_item_activate)
        if self.model.device is None:
            item.set_sensitive(False)
        else:
            item.set_sensitive(True)
        item.show()
        menu.append(item)

        item = gtk.ImageMenuItem(_("Quit"))
        img = gtk.image_new_from_stock(gtk.STOCK_QUIT, gtk.ICON_SIZE_MENU)
        item.set_image(img)
        item.connect("activate", self.close_application)
        item.show()
        menu.append(item)

        return menu
Example #4
0
    def on_keyring_password_required(self, opath, callback=None):
        from wader.gtk.profiles import manager
        profile = manager.get_profile_by_object_path(opath)
        password = None

        if profile.secrets.manager.is_new():
            dialog = NewKeyringDialog(self.view.get_top_widget())
            response = dialog.run()
        elif not profile.secrets.manager.is_open():
            dialog = KeyringPasswordDialog(self.view.get_top_widget())
            response = dialog.run()

        if response == gtk.RESPONSE_OK:
            password = dialog.password_entry.get_text()

        dialog.destroy()

        if password is not None:
            try:
                profile.secrets.manager.open(password)
            except KeyringInvalidPassword:
                title = _("Invalid password")
                details = _("The supplied password is incorrect")
                show_error_dialog(title, details)
                # call ourselves again
                self.on_keyring_password_required(opath)
            else:
                if callback is not None:
                    uuid = profile.get_settings()['connection']['uuid']
                    callback(profile.secrets.manager.get_secrets(uuid))
Example #5
0
    def on_save_toolbutton_clicked(self, widget):
        numbers = self.view.get_numbers()
        text = self.view.get_text()

        if not numbers:
            title = _("Invalid number")
            msg = _("You must provide a valid number")
            dialogs.show_error_dialog(title, msg)
            self.view["contacts_entry"].grab_focus()
            return

        if text == "":
            title = _("No text to save")
            msg = _("Are you sure you want to store a blank message?")
            if not dialogs.show_warning_request_cancel_ok(title, msg):
                # user cancelled it
                self.view["text_textview"].grab_focus()
                return

        self.messages = [Message(num, text) for num in numbers]
        for sms in self.messages:
            self.model.device.Save(
                sms.to_dict(),
                dbus_interface=SMS_INTFACE,
                reply_handler=self.on_sms_saved_cb,
                error_handler=self.on_sms_saved_eb,
            )
Example #6
0
    def setup_view(self, view):
        self.view['profile_name_entry'].set_text(self.model.name)
        self.view['username_entry'].set_text(self.model.username)
        self.view.set_network_mode(self.model.network_type)
        self.view.set_band(self.model.band)
        self.view['apn_entry'].set_text(self.model.apn)
        self.view['static_dns_check'].set_active(self.model.static_dns)
        if self.model.primary_dns:
            dns1 = convert_int_to_ip(self.model.primary_dns)
            self.view['primary_dns_entry'].set_text(dns1)
        if self.model.secondary_dns:
            dns2 = convert_int_to_ip(self.model.secondary_dns)
            self.view['secondary_dns_entry'].set_text(dns2)

        if self.model.static_dns:
            self.view.enable_static_dns()

        if not self.model.password:
            try:
                self.model.load_password()
            except KeyringNoMatchError, e:
                logger.error("Error while loading connection password: %s" % e)
                title = _("Error while getting connection password")
                details = _("NoMatchError: No password was retrieved "
                            "from connection, please set one again")
                show_error_dialog(title, details)
                return
Example #7
0
 def property_status_value_change(self, model, old, new):
     self.view.set_status(new)
     if new == _('Initialising'):
         self.view.set_initialising(True)
     elif new == _('No device'):
         self.view.set_disconnected(device_present=False)
     elif new in [_('Registered'), _('Roaming')]:
         self.view.set_initialising(False)
Example #8
0
 def _init_wader_object(self):
     try:
         self.obj = self.bus.get_object(WADER_SERVICE, WADER_OBJPATH)
     except dbus.DBusException, e:
         title = _("Error while starting wader")
         details = _("Check that your installation is correct and your "
                     " OS/distro is supported: %s" % e)
         show_error_dialog(title, details)
         raise SystemExit()
Example #9
0
        def find_by_number_cb(contacts):
            if not contacts:
                title = _("SMS received from %s") % sms['number']
            else:
                assert len(contacts) == 1, "More than one match for a number!"
                title = _("SMS received from %s") % contacts[0][1]

            n = new_notification(self.icon, title, sms['text'],
                                 stock=gtk.STOCK_INFO)
            n.show()
Example #10
0
    def close_application(self, *args):
        if self.model.dial_path:
            show_warning_dialog(_("Can not close application"),
                               _("Can not close while a connection is active"))
            window = self.view.get_top_widget()
            try:
                window.emit_stop_by_name('delete_event')
            except IOError:
                pass

            return True
        else:
            self.view.start_throbber()
            self.model.quit(self._close_application_cb)
Example #11
0
    def _device_removed_cb(self, opath):
        logger.info('Device with opath %s removed' % opath)

        if self.device_opath:
            logger.info('Device path: %s' % self.device_opath)

        if opath == self.device_opath:
            self.device = None
            self.device_opath = None
            self.dial_path = None
            self.operator = _('Unknown')
            self.status = _('No device')
            self.tech = '----'
            self.rssi = 0
Example #12
0
    def _build_contact_menu(self, pathlist, treeview):
        menu = gtk.Menu()
        item = gtk.MenuItem(_("_Send SMS"))
        item.connect("activate", self._send_sms_to_contact, treeview)
        item.show()
        menu.append(item)

        item = gtk.ImageMenuItem(_("_Delete"))
        img = gtk.image_new_from_stock(gtk.STOCK_DELETE, gtk.ICON_SIZE_MENU)
        item.set_image(img)
        item.connect("activate", self._delete_rows, pathlist, treeview)
        item.show()
        menu.append(item)

        return menu
Example #13
0
    def get_categories_model(self):
        if self.categories is None:
            model = CategoriesModel()
            # SMS

            # inbox
            inbox_path = os.path.join(GLADE_DIR, 'inbox.png')
            inbox_pixbuf = gtk.gdk.pixbuf_new_from_file(inbox_path)

            def inbox_visible_func(m, _iter):
                obj = m.get_value(_iter, m.COL_OBJECT)
                return (False if not obj else obj.where == STO_INBOX)

            model.add_category(Category(_("Inbox"), parent=model.sms_iter,
                                        pixbuf=inbox_pixbuf,
                                        visible_func=inbox_visible_func))
            # drafts
            drafts_path = os.path.join(GLADE_DIR, 'folder.png')
            drafts_pixbuf = gtk.gdk.pixbuf_new_from_file(drafts_path)

            def drafts_visible_func(m, _iter):
                obj = m.get_value(_iter, m.COL_OBJECT)
                return (False if not obj else obj.where == STO_DRAFTS)

            model.add_category(Category(_("Drafts"), parent=model.sms_iter,
                                        pixbuf=drafts_pixbuf,
                                        visible_func=drafts_visible_func))
            # sent
            sent_path = os.path.join(GLADE_DIR, 'mail-sent.png')
            sent_pixbuf = gtk.gdk.pixbuf_new_from_file(sent_path)

            def sent_visible_func(m, _iter):
                obj = m.get_value(_iter, m.COL_OBJECT)
                return (False if not obj else obj.where == STO_SENT)

            model.add_category(Category(_("Sent"), parent=model.sms_iter,
                                        pixbuf=sent_pixbuf,
                                        visible_func=sent_visible_func))

            # Contacts
            cts_path = os.path.join(GLADE_DIR, 'contacts.png')
            cts_pixbuf = gtk.gdk.pixbuf_new_from_file(cts_path)
            model.add_category(Category(_("SIM"),
                                        parent=model.cts_iter,
                                        pixbuf=cts_pixbuf))
            self.categories = model

        return self.categories
Example #14
0
    def on_ok_button_clicked(self, widget):
        self.model.name = self.view['profile_name_entry'].get_text()
        self.model.username = self.view['username_entry'].get_text()
        self.model.password = self.view['password_entry'].get_text()

        mode = self.view['connection_combobox'].get_active_text()
        band = self.view['band_combobox'].get_active_text()
        if mode:
            self.model.network_type = MODE_MAP_REV[mode]
        if band:
            self.model.band = BAND_MAP_REV[band]

        self.model.apn = self.view['apn_entry'].get_text()
        self.model.static_dns = self.view['static_dns_check'].get_active()
        if self.view['static_dns_check'].get_active():
            dns1 = self.view['primary_dns_entry'].get_text()
            dns2 = self.view['secondary_dns_entry'].get_text()
            if dns1:
                self.model.primary_dns = convert_ip_to_int(dns1)
            if dns2:
                self.model.secondary_dns = convert_ip_to_int(dns2)

        try:
            self.model.save()
        except RuntimeError, e:
            show_error_dialog(_("Error creating profile"), get_error_msg(e))
Example #15
0
    def on_preferences_menu_item_activate(self, widget):
        from wader.gtk.views.preferences import PreferencesView
        from wader.gtk.controllers.preferences import PreferencesController

        view = PreferencesView()
        controller = PreferencesController(self.model.preferences_model, view,
                                           lambda: self.model.device)

        profiles_model = self.model.preferences_model.profiles_model
        if not profiles_model.has_active_profile():
            show_warning_dialog(
                _("Profile needed"),
                _("You need to create a profile to save preferences"))
            self.ask_for_new_profile()
            return
        view.show()
Example #16
0
    def _get_regstatus(self, first_time=False):
        self.device.GetRegistrationInfo(dbus_interface=NET_INTFACE,
                            reply_handler=self._get_regstatus_cb,
                            error_handler=lambda e:
                                logger.warn("Error getting registration "
                                            "status: %s " % get_error_msg(e)))

        if not first_time and self.status != _("Scanning"):
            return False
Example #17
0
 def on_delete_profile_button_clicked(self, event):
     _iter = self.view.profiles_treeview.get_selection().get_selected()[1]
     profile = self.model.profiles_model.get_value(_iter, 1)
     if profile:
         try:
             self.model.profiles_model.remove_profile(profile)
         except ProfileNotFoundError, e:
             show_error_dialog(_("Error while removing profile"),
                               get_error_msg(e))
Example #18
0
    def setup_treeview(self, model):
        treeview = self["contact_treeview"]
        treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)

        cell = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_("Name"), cell, text=model.COL_NAME)
        column.set_resizable(True)
        column.set_sort_column_id(model.COL_NAME)
        cell.set_property("editable", False)
        treeview.append_column(column)

        cell = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_("Number"), cell, text=model.COL_NUMBER)
        column.set_resizable(True)
        column.set_sort_column_id(model.COL_NUMBER)
        cell.set_property("editable", False)
        treeview.append_column(column)

        treeview.set_model(model)
Example #19
0
    def on_add_button_clicked(self, widget):
        name = self.view["name_entry"].get_text()
        number = self.view["number_entry"].get_text()

        if name == "" or number == "":
            title = _("Name or number not specified")
            msg = _("You must provide a valid name and number")
            dialogs.show_error_dialog(title, msg)

            widget = (name == "") and "name_entry" or "number_entry"
            self.view[widget].grab_focus()
            return

        self.model.device.Add(
            name, number, dbus_interface=CTS_INTFACE, reply_handler=self.on_contact_added_cb, error_handler=logger.error
        )
        # save contact till we receive its index, and then we will add
        # it to the treeview model
        self.contact = Contact(name, number)
Example #20
0
    def on_contacts_list_eb(self, error):
        """
        Errback for org.freedesktop.ModemManager.Gsm.Contacts.List

        Show an error message to the user in case something goes bad
        """
        # end of potentially long operation
        self.view.stop_throbber()

        title = _("Error while reading contacts list")
        dialogs.show_error_dialog(title, get_error_msg(error))
Example #21
0
 def property_operator_value_change(self, model, old, new):
     if new == _('Unknown Network'):
         logger.error("Unknown operator received, using profile name...")
         profiles_model = self.model.preferences_model.profiles_model
         try:
             profile = profiles_model.get_active_profile()
         except RuntimeError:
             self.view.operator_changed(new)
         else:
             self.view.operator_changed(profile.name)
     else:
         self.view.operator_changed(new)
Example #22
0
    def delete(self):
        if self.profile:
            logger.info("Removing profile %s" % self.profile)
            self.manager.remove_profile(self.profile)
            self.profile_path = None
            self.uuid = None
            self.name = ""

            while self.sm:
                sm = self.sm.pop()
                sm.remove()
        else:
            raise RuntimeError(_("Trying to remove an unsaved profile"))
Example #23
0
    def init_ui(self, ctrl):
        icon = gtk.image_new_from_stock(gtk.STOCK_CLEAR, gtk.ICON_SIZE_MENU)
        ctrl.search_entry.set_icon(ICON_ENTRY_SECONDARY, icon)

        alignment = gtk.Alignment(yalign=MAIN_APP_YALIGN)
        alignment.add(ctrl.search_entry)
        self["hbox3"].pack_start(alignment, expand=False)

        window = self.get_top_widget()
        window.set_title(_("Manage SMS and Contacts"))
        window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        window.set_size_request(MAIN_APP_WIDTH, MAIN_APP_HEIGHT)
        window.set_property("resizable", True)
Example #24
0
    def __init__(self, parent):
        flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
        super(_KeyringDialog, self).__init__(_("Insert keyring password"),
                                             parent, flags)
        self.cancel_button = self.add_button(gtk.STOCK_CANCEL,
                                             gtk.RESPONSE_REJECT)
        self.ok_button = self.add_button(gtk.STOCK_OK,
                                         gtk.RESPONSE_OK)
        self.ok_button.set_flags(gtk.CAN_DEFAULT)
        self.ok_button.grab_default()
        self.ok_button.set_sensitive(False)

        self.tree = get_tree(FILE_TO_LOAD)
Example #25
0
    def on_connect_button_toggled(self, widget):
        dialmanager = self.model.get_dialer_manager()

        if widget.get_active():
            # user wants to connect
            if not self.model.device:
                widget.set_active(False)
                show_warning_dialog(
                    _("No device found"),
                    _("No device has been found. Insert one and try again."))
                return


            profiles_model = self.model.preferences_model.profiles_model
            if not profiles_model.has_active_profile():
                widget.set_active(False)
                show_warning_dialog(
                    _("Profile needed"),
                    _("You need to create a profile for connecting."))
                self.ask_for_new_profile()
                return

            active_profile = profiles_model.get_active_profile()

            dialmanager.ActivateConnection(active_profile.profile_path,
                                           self.model.device_opath,
                                           timeout=40,
                                           reply_handler=self._on_connect_cb,
                                           error_handler=self._on_connect_eb)

            self._setup_connection_signals()

            def cancel_cb():
                self.view.set_disconnected()
                self.model.dial_path = None

            def stop_connection_attempt():
                self._ignore_no_reply = True
                dialmanager.StopConnection(self.model.device_opath,
                                           reply_handler=cancel_cb,
                                           error_handler=logger.error)

            self.apb = ActivityProgressBar(_("Connecting"), self)
            self.apb.set_cancel_cb(stop_connection_attempt)
            self.apb.init()
            logger.info("Connecting...")
        else:
            # user wants to disconnect
            if not self.model.dial_path:
                return

            self.apb = ActivityProgressBar(_("Disconnecting"), self,
                                           disable_cancel=True)
            dialmanager.DeactivateConnection(self.model.dial_path,
                                        reply_handler=self._on_disconnect_cb,
                                        error_handler=self._on_disconnect_eb)

            self.apb.init()
            self.model.dial_path = None
Example #26
0
    def on_send_toolbutton_clicked(self, widget):
        numbers = self.view.get_numbers()
        text = self.view.get_text()

        if not numbers:
            title = _("Invalid number")
            msg = _("You must provide a valid number")
            dialogs.show_error_dialog(title, msg)
            self.view["contacts_entry"].grab_focus()
            return

        if text == "":
            title = _("No text to send")
            msg = _("Are you sure you want to send a blank message?")
            if not dialogs.show_warning_request_cancel_ok(title, msg):
                # user cancelled it
                self.view["text_textview"].grab_focus()
                return

        if self.mode == STORAGE and not self.has_changed:
            # sending from storage
            sms = self.selected["objs"][0]
            self.model.device.SendFromStorage(
                sms.index,
                dbus_interface=SMS_INTFACE,
                reply_handler=self.on_sms_sent_cb,
                error_handler=self.on_sms_sent_eb,
            )
        else:
            self.state = SENDING
            for number in numbers:
                self.model.device.Send(
                    dict(number=number, text=text),
                    dbus_interface=SMS_INTFACE,
                    reply_handler=self.on_sms_sent_cb,
                    error_handler=self.on_sms_sent_eb,
                )
            self.state = IDLE
Example #27
0
    def load_contacts_model(self, model, ctrl):
        treeview = self.init_secondary_treeview()

        cell = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_("Name"), cell, text=model.COL_NAME)
        column.set_resizable(True)
        column.set_sort_column_id(model.COL_NAME)
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        column.set_fixed_width(CTS_NAME_WIDTH)
        cell.set_property("editable", True)
        cell.connect("edited", ctrl.on_contact_name_cell_edited)
        treeview.append_column(column)

        cell = gtk.CellRendererText()
        column = gtk.TreeViewColumn(_("Number"), cell, text=model.COL_NUMBER)
        column.set_resizable(True)
        column.set_sort_column_id(model.COL_NUMBER)
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        column.set_fixed_width(CTS_NUMBER_WIDTH)
        cell.set_property("editable", True)
        cell.connect("edited", ctrl.on_contact_number_cell_edited)
        treeview.append_column(column)

        treeview.set_model(model)
Example #28
0
    def _on_connect_eb(self, e):
        logger.error("_on_connect_eb: %s" % e)
        self.view.set_disconnected()
        if self.apb:
            self.apb.close()
            self.apb = None

        if 'NoReply' in get_error_msg(e) and self._ignore_no_reply:
            # do not show NoReply exception as we were expecting it
            self._ignore_no_reply = False
        elif 'TypeError' in get_error_msg(e) and self._ignore_no_reply:
            # do not show TypeError exception as we were expecting it
            # as ActivateConnection returns None instead of an object
            # path.
            self._ignore_no_reply = False
        else:
            title = _('Failed connection attempt')
            show_error_dialog(title, get_error_msg(e))
Example #29
0
        def render_date(cellview, cell, model, _iter, tz):
            if isinstance(model, gtk.TreeModelFilter):
                # we are dealing with the filtered model
                _iter = model.convert_iter_to_child_iter(_iter)
                model = model.get_model()

            sms = model.get_value(_iter, model.COL_OBJECT)
            if sms.datetime is not None:
                try:
                    delta = datetime.datetime.now(tz) - sms.datetime
                    # show date if more than one day has passed
                    # otherwise, show time of recept
                    fmt = "%x" if delta.days >= 1 else "%X"
                except TypeError:
                    # dt might be == None
                    fmt = "%x"

                cell.set_property("text", strftime(fmt, sms.datetime.timetuple()))
            else:
                # no datetime, a SMS_SUBMIT
                cell.set_property("text", _("no timestamp"))
Example #30
0
def show_about_dialog():
    abt = gtk.AboutDialog()
    icon = abt.render_icon(gtk.STOCK_ABOUT, gtk.ICON_SIZE_MENU)
    abt.set_icon(icon)

    gtk.about_dialog_set_url_hook(lambda abt, url: show_uri(url))
    gtk.about_dialog_set_email_hook(lambda d, e: show_uri("mailto:%s" % e))

    icon = gtk.gdk.pixbuf_new_from_file(os.path.join(GLADE_DIR, 'wader.png'))
    abt.set_icon(icon)
    abt.set_program_name(APP_NAME)
    abt.set_version(APP_VERSION)
    abt.set_copyright("Copyright (C) 2008-2009 Wader contributors")
    abt.set_authors(APP_AUTHORS)
    abt.set_documenters(APP_DOCUMENTERS)
    abt.set_artists(APP_ARTISTS)
    abt.set_website(APP_URL)
    abt.set_translator_credits(_('translator-credits'))

    abt.set_website_label(APP_URL)
    _license = """
The Wader project
Copyright (C) 2008-2009  Warp Networks, S.L.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA"""
    abt.set_license(_license)
    return abt