示例#1
0
 def __init__(self, content_box):
     keywords = _("display, screen, monitor, layout, resolution, dual, lcd")
     self.sidePage = SidePage(_("Display"),
                              "cs-display",
                              keywords,
                              content_box,
                              module=self)
示例#2
0
 def __init__(self, content_box):
     keywords = _("panel, height, bottom, top, autohide, size, layout")
     self.sidePage = SidePage(_("Panel"),
                              "cs-panel",
                              keywords,
                              content_box,
                              module=self)
示例#3
0
 def __init__(self, content_box):
     keywords = _("background, picture, slideshow")
     self.sidePage = SidePage(_("Backgrounds"),
                              "cs-backgrounds",
                              keywords,
                              content_box,
                              module=self)
示例#4
0
 def __init__(self, content_box):
     keywords = _("time, date, calendar, format, network, sync")
     self.sidePage = SidePage(_("Date & Time"),
                              "cs-date-time",
                              keywords,
                              content_box,
                              560,
                              module=self)
示例#5
0
 def __init__(self, content_box):
     keywords = _("sound, media, music, speakers, audio")
     self.sidePage = SidePage(_("Sound"),
                              "cs-sound",
                              keywords,
                              content_box,
                              module=self)
     self.sound_settings = Gio.Settings(CINNAMON_DESKTOP_SOUNDS)
示例#6
0
class Module:
    name = "display"
    comment = _("Manage display settings")
    category = "hardware"

    def __init__(self, content_box):
        keywords = _("display, screen, monitor, layout, resolution, dual, lcd")
        self.sidePage = SidePage(_("Display"),
                                 "cs-display",
                                 keywords,
                                 content_box,
                                 module=self)
        self.display_c_widget = None

    def on_module_selected(self):
        if not self.loaded:
            print("Loading Display module")

            self.sidePage.stack = SettingsStack()
            self.sidePage.add_widget(self.sidePage.stack)

            page = SettingsPage()
            self.sidePage.stack.add_titled(page, "layout", _("Layout"))

            try:
                settings = page.add_section(_("Layout"))

                widget = SettingsWidget()
                widget.set_border_width(0)
                widget.set_margin_start(0)
                widget.set_margin_end(0)

                content = self.sidePage.content_box.c_manager.get_c_widget(
                    "display")
                widget.pack_start(content, True, True, 0)

                self.display_c_widget = content
                settings.add_row(widget)

            except Exception as detail:
                print(detail)

            page = SettingsPage()
            self.sidePage.stack.add_titled(page, "settings", _("Settings"))
            settings = page.add_section(_("Settings"))

            switch = GSettingsSwitch(
                _("Disable automatic screen rotation"),
                "org.cinnamon.settings-daemon.peripherals.touchscreen",
                "orientation-lock")
            switch.set_tooltip_text(
                _("Select this option to disable automatic screen rotation on hardware equipped with supported accelerometers."
                  ))
            settings.add_row(switch)

    def on_navigate_out_of_module(self):
        if self.display_c_widget:
            self.display_c_widget.hide()
示例#7
0
 def __init__(self, content_box):
     keywords = _(
         "power, suspend, hibernate, laptop, desktop, brightness, screensaver"
     )
     self.sidePage = SidePage(_("Power Management"),
                              "cs-power",
                              keywords,
                              content_box,
                              -1,
                              module=self)
示例#8
0
class Module:
    name = "display"
    comment = _("Manage display settings")
    category = "hardware"

    def __init__(self, content_box):
        keywords = _("display, screen, monitor, layout, resolution, dual, lcd")
        self.sidePage = SidePage(_("Display"),
                                 "cs-display",
                                 keywords,
                                 content_box,
                                 module=self)

    def on_module_selected(self):
        if not self.loaded:
            print("Loading Display module")

            self.sidePage.stack = SettingsStack()
            self.sidePage.add_widget(self.sidePage.stack)

            page = SettingsPage()
            self.sidePage.stack.add_titled(page, "layout", _("Layout"))

            try:
                settings = page.add_section(_("Layout"))
                widget = SettingsWidget()
                content = self.sidePage.content_box.c_manager.get_c_widget(
                    "display")
                widget.pack_start(content, True, True, 0)
                settings.add_row(widget)

            except Exception as detail:
                print(detail)

            page = SettingsPage()
            self.sidePage.stack.add_titled(page, "settings", _("Settings"))
            settings = page.add_section(_("Settings"))

            ui_scales = [[0, _("Auto")], [1, _("Normal")],
                         [2, _("Double (Hi-DPI)")]]
            combo = GSettingsComboBox(_("User interface scaling:"),
                                      "org.cinnamon.desktop.interface",
                                      "scaling-factor",
                                      ui_scales,
                                      valtype=int)
            settings.add_row(combo)

            switch = GSettingsSwitch(
                _("Disable automatic screen rotation"),
                "org.cinnamon.settings-daemon.peripherals.touchscreen",
                "orientation-lock")
            switch.set_tooltip_text(
                _("Select this option to disable automatic screen rotation on hardware equipped with supported accelerometers."
                  ))
            settings.add_row(switch)
示例#9
0
 def __init__(self, content_box):
     keywords = _("notifications")
     sidePage = SidePage(_("Notifications"),
                         "cs-notifications",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#10
0
 def __init__(self, content_box):
     keywords = _("screensaver, lock, away, message")
     sidePage = SidePage(_("Screensaver"),
                         "cs-screensaver",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#11
0
 def __init__(self, content_box):
     keywords = _("window, tile, flip, tiling, snap, snapping")
     sidePage = SidePage(_("Window Tiling"),
                         "cs-tiling",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#12
0
 def __init__(self, content_box):
     keywords = _("effects, window")
     sidePage = SidePage(_("Effects"),
                         "cs-desktop-effects",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#13
0
文件: cs_startup.py 项目: t6/cinnamon
 def __init__(self, content_box):
     keywords = _("startup, programs, boot, init, session, autostart, apps")
     sidePage = SidePage(_("Startup Applications"),
                         "cs-startup-programs",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#14
0
 def __init__(self, content_box):
     keywords = _("mouse, touchpad, synaptic, double-click")
     sidePage = SidePage(_("Mouse and Touchpad"),
                         "cs-mouse",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#15
0
 def __init__(self, content_box):
     keywords = _("desktop, home, button, trash")
     sidePage = SidePage(_("Desktop"),
                         "cs-desktop",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#16
0
 def __init__(self, content_box):
     keywords = _("logging, click")
     sidePage = SidePage(_("General"),
                         "cs-general",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#17
0
 def __init__(self, content_box):
     keywords = _("keyboard, shortcut, hotkey")
     sidePage = SidePage(_("Keyboard"),
                         "cs-keyboard",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#18
0
 def __init__(self, content_box):
     keywords = _("workspace, osd, expo, monitor")
     sidePage = SidePage(_("Workspaces"),
                         "cs-workspaces",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#19
0
 def __init__(self, content_box):
     keywords = _("magnifier, talk, access, zoom, keys, contrast")
     sidePage = SidePage(_("Accessibility"),
                         "cs-universal-access",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#20
0
 def __init__(self, content_box):
     keywords = _(
         "system, information, details, graphic, sound, kernel, version")
     sidePage = SidePage(_("System Info"),
                         "cs-details",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#21
0
 def __init__(self, content_box):
     keywords = _("user, account, information, details, password")
     sidePage = SidePage(_("Account details"),
                         "cs-user",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
     self.window = None
示例#22
0
 def __init__(self, content_box):
     keywords = _("privacy, recent, gtk, private")
     sidePage = SidePage(_("Privacy"),
                         "cs-privacy",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
     self.settings = Gio.Settings(schema=PRIVACY_SCHEMA)
示例#23
0
 def __init__(self, content_box):
     keywords = _(
         "windows, titlebar, edge, switcher, window list, attention, focus")
     sidePage = SidePage(_("Windows"),
                         "cs-windows",
                         keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#24
0
 def __init__(self, content_box):
     keywords = _("hotcorner, overview, scale, expo")
     sidePage = SidePage(_("Hot Corners"),
                         "cs-overview",
                         keywords,
                         content_box,
                         -1,
                         module=self)
     self.sidePage = sidePage
示例#25
0
 def __init__(self, content_box):
     self.keywords = _("themes, style")
     self.icon = "cs-themes"
     self.window = None
     sidePage = SidePage(_("Themes"),
                         self.icon,
                         self.keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
 def __init__(self, content_box):
     self.keywords = _("layout, cinnamon")
     self.icon = "cinnamon-layout"
     self.window = None
     sidePage = SidePage(_("Desktop Layout"),
                         self.icon,
                         self.keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
示例#27
0
class Module:
    name = "online-accounts"
    comment = _("Connect to your online accounts")
    category = "prefs"

    def __init__(self, content_box):
        keywords = _("google, facebook, twitter, yahoo, web, online, chat, calendar, mail, contact, owncloud, kerberos, imap, smtp, pocket, readitlater, account")
        self.sidePage = SidePage(_("Online Accounts"), "cs-online-accounts", keywords, content_box, 560, module=self)

    def on_module_selected(self):
        if not self.loaded:
            print("Loading Online Account module")

            page = SettingsPage()
            self.sidePage.add_widget(page)

            image = Gtk.Image.new_from_icon_name("help-contents-symbolic", Gtk.IconSize.BUTTON)

            button = Gtk.Button(_("Information about GNOME Online Accounts"))
            button.set_image(image)
            button.set_always_show_image(True)
            button.connect("clicked", self.on_button_clicked)
            page.pack_start(button, False, True, 0)

            try:
                content = self.sidePage.content_box.c_manager.get_c_widget("online-accounts")
                content.set_no_show_all(True)
                page.pack_start(content, True, True, 0)
            except Exception as detail:
                print(detail)

            page.expand = True

    def on_button_clicked(self, button):
        gladefile = "/usr/share/cinnamon/cinnamon-settings/cinnamon-online-accounts-info.ui"
        self.builder = Gtk.Builder()
        self.builder.set_translation_domain('cinnamon')
        self.builder.add_from_file(gladefile)
        self.window = self.builder.get_object("main_window")
        self.window.set_title(_("Online Accounts"))
        self.window.set_icon_name("cs-online-accounts")
        self.window.show()
示例#28
0
 def __init__(self, content_box):
     self.keywords = _("themes, style")
     self.icon = "cs-themes"
     self.window = None
     sidePage = SidePage(_("Themes"),
                         self.icon,
                         self.keywords,
                         content_box,
                         module=self)
     self.sidePage = sidePage
     self.refreshing = False  # flag to ensure we only refresh once at any given moment
示例#29
0
class Module:
    name = "backgrounds"
    category = "appear"
    comment = _("Change your desktop's background")

    def __init__(self, content_box):
        keywords = _("background, picture, slideshow")
        self.sidePage = SidePage(_("Backgrounds"),
                                 "cs-backgrounds",
                                 keywords,
                                 content_box,
                                 module=self)

    def on_module_selected(self):
        if not self.loaded:
            print("Loading Backgrounds module")

            self.sidePage.stack = SettingsStack()
            self.sidePage.add_widget(self.sidePage.stack)

            self.shown_collection = None  # Which collection is displayed in the UI

            self._background_schema = Gio.Settings(
                schema="org.cinnamon.desktop.background")
            self._slideshow_schema = Gio.Settings(
                schema="org.cinnamon.desktop.background.slideshow")
            self._slideshow_schema.connect("changed::slideshow-enabled",
                                           self.on_slideshow_enabled_changed)
            self.add_folder_dialog = Gtk.FileChooserDialog(
                title=_("Add Folder"),
                action=Gtk.FileChooserAction.SELECT_FOLDER,
                buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                         Gtk.STOCK_OPEN, Gtk.ResponseType.OK))

            self.xdg_pictures_directory = os.path.expanduser("~/Pictures")
            xdg_config = os.path.expanduser("~/.config/user-dirs.dirs")
            if os.path.exists(xdg_config) and os.path.exists(
                    "/usr/bin/xdg-user-dir"):
                path = subprocess.check_output(["xdg-user-dir", "PICTURES"
                                                ]).decode("utf-8").rstrip("\n")
                if os.path.exists(path):
                    self.xdg_pictures_directory = path

            self.get_user_backgrounds()

            # Images

            mainbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 2)
            mainbox.expand = True
            mainbox.set_border_width(8)

            self.sidePage.stack.add_titled(mainbox, "images", _("Images"))

            left_vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
            right_vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)

            folder_scroller = Gtk.ScrolledWindow.new(None, None)
            folder_scroller.set_shadow_type(Gtk.ShadowType.IN)
            folder_scroller.set_policy(Gtk.PolicyType.AUTOMATIC,
                                       Gtk.PolicyType.AUTOMATIC)
            folder_scroller.set_property("min-content-width", 150)

            self.folder_tree = Gtk.TreeView.new()
            self.folder_tree.set_headers_visible(False)
            folder_scroller.add(self.folder_tree)

            button_toolbar = Gtk.Toolbar.new()
            button_toolbar.set_icon_size(1)
            Gtk.StyleContext.add_class(
                Gtk.Widget.get_style_context(button_toolbar), "inline-toolbar")
            self.add_folder_button = Gtk.ToolButton.new(None, None)
            self.add_folder_button.set_icon_name("list-add-symbolic")
            self.add_folder_button.set_tooltip_text(_("Add new folder"))
            self.add_folder_button.connect("clicked",
                                           lambda w: self.add_new_folder())
            self.remove_folder_button = Gtk.ToolButton.new(None, None)
            self.remove_folder_button.set_icon_name("list-remove-symbolic")
            self.remove_folder_button.set_tooltip_text(
                _("Remove selected folder"))
            self.remove_folder_button.connect("clicked",
                                              lambda w: self.remove_folder())
            button_toolbar.insert(self.add_folder_button, 0)
            button_toolbar.insert(self.remove_folder_button, 1)

            image_scroller = Gtk.ScrolledWindow.new(None, None)
            image_scroller.set_shadow_type(Gtk.ShadowType.IN)
            image_scroller.set_policy(Gtk.PolicyType.AUTOMATIC,
                                      Gtk.PolicyType.AUTOMATIC)

            self.icon_view = ThreadedIconView()
            image_scroller.add(self.icon_view)
            self.icon_view.connect("selection-changed",
                                   self.on_wallpaper_selection_changed)

            right_vbox.pack_start(image_scroller, True, True, 0)
            left_vbox.pack_start(folder_scroller, True, True, 0)
            left_vbox.pack_start(button_toolbar, False, False, 0)

            mainbox.pack_start(left_vbox, False, False, 2)
            mainbox.pack_start(right_vbox, True, True, 2)

            left_vbox.set_border_width(2)
            right_vbox.set_border_width(2)

            self.collection_store = Gtk.ListStore(
                bool,  # is separator
                str,  # Icon name
                str,  # Display name
                str,  # Path
                str)  # Type of collection
            cell = Gtk.CellRendererText()
            cell.set_alignment(0, 0)
            pb_cell = Gtk.CellRendererPixbuf()
            self.folder_column = Gtk.TreeViewColumn()
            self.folder_column.pack_start(pb_cell, False)
            self.folder_column.pack_start(cell, True)
            self.folder_column.add_attribute(pb_cell, "icon-name", 1)
            self.folder_column.add_attribute(cell, "text", 2)

            self.folder_column.set_alignment(0)

            self.folder_tree.append_column(self.folder_column)
            self.folder_tree.connect("cursor-changed",
                                     self.on_folder_source_changed)

            self.get_system_backgrounds()

            tree_separator = [True, None, None, None, None]
            self.collection_store.append(tree_separator)

            if len(self.user_backgrounds) > 0:
                for item in self.user_backgrounds:
                    self.collection_store.append(item)

            self.folder_tree.set_model(self.collection_store)
            self.folder_tree.set_row_separator_func(self.is_row_separator,
                                                    None)

            self.get_initial_path()

            # Settings

            page = SettingsPage()

            settings = page.add_section(_("Background Settings"))

            size_group = Gtk.SizeGroup.new(Gtk.SizeGroupMode.HORIZONTAL)

            self.sidePage.stack.add_titled(page, "settings", _("Settings"))

            widget = GSettingsSwitch(
                _("Play backgrounds as a slideshow"),
                "org.cinnamon.desktop.background.slideshow",
                "slideshow-enabled")
            settings.add_row(widget)

            widget = GSettingsSpinButton(
                _("Delay"), "org.cinnamon.desktop.background.slideshow",
                "delay", _("minutes"), 1, 1440)
            settings.add_reveal_row(
                widget, "org.cinnamon.desktop.background.slideshow",
                "slideshow-enabled")

            widget = GSettingsSwitch(
                _("Play images in random order"),
                "org.cinnamon.desktop.background.slideshow", "random-order")
            settings.add_reveal_row(
                widget, "org.cinnamon.desktop.background.slideshow",
                "slideshow-enabled")

            widget = GSettingsComboBox(_("Picture aspect"),
                                       "org.cinnamon.desktop.background",
                                       "picture-options",
                                       BACKGROUND_PICTURE_OPTIONS,
                                       size_group=size_group)
            settings.add_row(widget)

            widget = ColorsWidget(size_group)
            settings.add_row(widget)

    def is_row_separator(self, model, iter, data):
        return model.get_value(iter, 0)

    def on_slideshow_enabled_changed(self, settings, key):
        if self._slideshow_schema.get_boolean("slideshow-enabled"):
            self.icon_view.set_sensitive(False)
            self.icon_view.set_selection_mode(Gtk.SelectionMode.NONE)
        else:
            self.icon_view.set_sensitive(True)
            self.icon_view.set_selection_mode(Gtk.SelectionMode.SINGLE)

    def get_system_backgrounds(self):
        picture_list = []
        folder_list = []
        properties_dir = "/usr/share/cinnamon-background-properties"
        backgrounds = []
        if os.path.exists(properties_dir):
            for i in os.listdir(properties_dir):
                if i.endswith(".xml"):
                    xml_path = os.path.join(properties_dir, i)
                    display_name = i.replace(".xml", "").replace(
                        "-", " ").replace("_",
                                          " ").split(" ")[-1].capitalize()
                    icon = "preferences-desktop-wallpaper-symbolic"
                    order = 10
                    # Special case for Linux Mint. We don't want to use 'start-here' here as it wouldn't work depending on the theme.
                    # Also, other distros should get equal treatment. If they define cinnamon-backgrounds and use their own distro name, we should add support for it.
                    if display_name == "Retro":
                        icon = "document-open-recent-symbolic"
                        order = 20  # place retro bgs at the end
                    if display_name == "Linuxmint":
                        display_name = "Linux Mint"
                        icon = "linuxmint-logo-badge-symbolic"
                        order = 0
                    backgrounds.append([[
                        False, icon, display_name, xml_path,
                        BACKGROUND_COLLECTION_TYPE_XML
                    ], display_name, order])

        backgrounds.sort(key=lambda x: (x[2], x[1]))
        for background in backgrounds:
            self.collection_store.append(background[0])

    def get_user_backgrounds(self):
        self.user_backgrounds = []
        path = os.path.expanduser("~/.cinnamon/backgrounds/user-folders.lst")
        if os.path.exists(path):
            with open(path) as f:
                folders = f.readlines()
            for line in folders:
                folder_path = line.strip("\n")
                folder_name = folder_path.split("/")[-1]
                if folder_path == self.xdg_pictures_directory:
                    icon = "folder-pictures-symbolic"
                else:
                    icon = "folder-symbolic"
                self.user_backgrounds.append([
                    False, icon, folder_name, folder_path,
                    BACKGROUND_COLLECTION_TYPE_DIRECTORY
                ])
        else:
            # Add XDG PICTURE DIR
            self.user_backgrounds.append([
                False, "folder-pictures-symbolic",
                self.xdg_pictures_directory.split("/")[-1],
                self.xdg_pictures_directory,
                BACKGROUND_COLLECTION_TYPE_DIRECTORY
            ])
            self.update_folder_list()

    def format_source(self, type, path):
        # returns 'type://path'
        return ("%s://%s" % (type, path))

    def get_initial_path(self):
        try:
            image_source = self._slideshow_schema.get_string("image-source")
            tree_iter = self.collection_store.get_iter_first()
            collection = self.collection_store[tree_iter]
            collection_type = collection[STORE_TYPE]
            collection_path = collection[STORE_PATH]
            collection_source = self.format_source(collection_type,
                                                   collection_path)
            self.remove_folder_button.set_sensitive(True)

            if image_source != "" and "://" in image_source:
                while tree_iter != None:
                    if collection_source == image_source:
                        tree_path = self.collection_store.get_path(tree_iter)
                        self.folder_tree.set_cursor(tree_path)
                        if collection_type == BACKGROUND_COLLECTION_TYPE_XML:
                            self.remove_folder_button.set_sensitive(False)
                        self.update_icon_view(collection_path, collection_type)
                        return
                    tree_iter = self.collection_store.iter_next(tree_iter)
                    collection = self.collection_store[tree_iter]
                    collection_type = collection[STORE_TYPE]
                    collection_path = collection[STORE_PATH]
                    collection_source = self.format_source(
                        collection_type, collection_path)
            else:
                self._slideshow_schema.set_string("image-source",
                                                  collection_source)
                tree_path = self.collection_store.get_path(tree_iter)
                self.folder_tree.get_selection().select_path(tree_path)
                if collection_type == BACKGROUND_COLLECTION_TYPE_XML:
                    self.remove_folder_button.set_sensitive(False)
                self.update_icon_view(collection_path, collection_type)
        except Exception as detail:
            print(detail)

    def on_row_activated(self, tree, path, column):
        self.folder_tree.set_selection(path)

    def on_folder_source_changed(self, tree):
        self.remove_folder_button.set_sensitive(True)
        if tree.get_selection() is not None:
            folder_paths, iter = tree.get_selection().get_selected()
            if iter:
                collection_path = folder_paths[iter][STORE_PATH]
                collection_type = folder_paths[iter][STORE_TYPE]
                collection_source = self.format_source(collection_type,
                                                       collection_path)
                if os.path.exists(collection_path):
                    if collection_source != self._slideshow_schema.get_string(
                            "image-source"):
                        self._slideshow_schema.set_string(
                            "image-source", collection_source)
                    if collection_type == BACKGROUND_COLLECTION_TYPE_XML:
                        self.remove_folder_button.set_sensitive(False)
                    self.update_icon_view(collection_path, collection_type)

    def get_selected_wallpaper(self):
        selected_items = self.icon_view.get_selected_items()
        if len(selected_items) == 1:
            path = selected_items[0]
            iter = self.icon_view.get_model().get_iter(path)
            return self.icon_view.get_model().get(iter, 0)[0]
        return None

    def on_wallpaper_selection_changed(self, iconview):
        wallpaper = self.get_selected_wallpaper()
        if wallpaper:
            for key in wallpaper:
                if key == "filename":
                    self._background_schema.set_string(
                        "picture-uri", "file://" + wallpaper[key])
                elif key == "options":
                    self._background_schema.set_string("picture-options",
                                                       wallpaper[key])

    def add_new_folder(self):
        res = self.add_folder_dialog.run()
        if res == Gtk.ResponseType.OK:
            folder_path = self.add_folder_dialog.get_filename()
            folder_name = folder_path.split("/")[-1]
            # Make sure it's not already added..
            for background in self.user_backgrounds:
                if background[STORE_PATH] == folder_path:
                    self.add_folder_dialog.hide()
                    return
            if folder_path == self.xdg_pictures_directory:
                icon = "folder-pictures-symbolic"
            else:
                icon = "folder-symbolic"
            self.user_backgrounds.append([
                False, icon, folder_name, folder_path,
                BACKGROUND_COLLECTION_TYPE_DIRECTORY
            ])
            self.collection_store.append([
                False, icon, folder_name, folder_path,
                BACKGROUND_COLLECTION_TYPE_DIRECTORY
            ])
            self.update_folder_list()
        self.add_folder_dialog.hide()

    def remove_folder(self):
        if self.folder_tree.get_selection() is not None:
            self.icon_view.clear()
            folder_paths, iter = self.folder_tree.get_selection().get_selected(
            )
            if iter:
                path = folder_paths[iter][STORE_PATH]
                self.collection_store.remove(iter)
                for item in self.user_backgrounds:
                    if item[STORE_PATH] == path:
                        self.user_backgrounds.remove(item)
                        self.update_folder_list()
                        break

    def update_folder_list(self):
        path = os.path.expanduser("~/.cinnamon/backgrounds")
        if not os.path.exists(path):
            os.makedirs(path, mode=0o755, exist_ok=True)
        path = os.path.expanduser("~/.cinnamon/backgrounds/user-folders.lst")
        if len(self.user_backgrounds) == 0:
            file_data = ""
        else:
            first_path = self.user_backgrounds[0][STORE_PATH]
            file_data = first_path + "\n"
            for folder in self.user_backgrounds:
                if folder[STORE_PATH] == first_path:
                    continue
                else:
                    file_data += "%s\n" % folder[STORE_PATH]

        with open(path, "w") as f:
            f.write(file_data)

    def update_icon_view(self, path=None, type=None):
        if path != self.shown_collection:
            self.shown_collection = path
            picture_list = []
            if os.path.exists(path):
                if type == BACKGROUND_COLLECTION_TYPE_DIRECTORY:
                    files = os.listdir(path)
                    files.sort()
                    for i in files:
                        filename = os.path.join(path, i)
                        picture_list.append({"filename": filename})
                elif type == BACKGROUND_COLLECTION_TYPE_XML:
                    picture_list += self.parse_xml_backgrounds_list(path)

            self.icon_view.set_pictures_list(picture_list, path)
            if self._slideshow_schema.get_boolean("slideshow-enabled"):
                self.icon_view.set_sensitive(False)
            else:
                self.icon_view.set_sensitive(True)

    def splitLocaleCode(self, localeCode):
        try:
            loc = localeCode.partition("_")
            loc = (loc[0], loc[2])
        except:
            loc = ("en", "US")
        return loc

    def getLocalWallpaperName(self, names, loc):
        result = ""
        mainLocFound = False
        for wp in names:
            wpLoc = wp[0]
            wpName = wp[1]
            if wpLoc == ("", ""):
                if not mainLocFound:
                    result = wpName
            elif wpLoc[0] == loc[0]:
                if wpLoc[1] == loc[1]:
                    return wpName
                elif wpLoc[1] == "":
                    result = wpName
                    mainLocFound = True
        return result

    def parse_xml_backgrounds_list(self, filename):
        try:
            locAttrName = "{http://www.w3.org/XML/1998/namespace}lang"
            loc = self.splitLocaleCode(locale.getdefaultlocale()[0])
            res = []
            subLocaleFound = False
            f = open(filename)
            rootNode = ElementTree.fromstring(f.read())
            f.close()
            if rootNode.tag == "wallpapers":
                for wallpaperNode in rootNode:
                    if wallpaperNode.tag == "wallpaper" and wallpaperNode.get(
                            "deleted") != "true":
                        wallpaperData = {"metadataFile": filename}
                        names = []
                        for prop in wallpaperNode:
                            if type(prop.tag) == str:
                                if prop.tag != "name":
                                    wallpaperData[prop.tag] = prop.text
                                else:
                                    propAttr = prop.attrib
                                    wpName = prop.text
                                    locName = self.splitLocaleCode(
                                        propAttr.get(locAttrName)
                                    ) if locAttrName in propAttr else ("", "")
                                    names.append((locName, wpName))
                        wallpaperData["name"] = self.getLocalWallpaperName(
                            names, loc)

                        if "filename" in wallpaperData and wallpaperData[
                                "filename"] != "" and os.path.exists(
                                    wallpaperData["filename"]) and os.access(
                                        wallpaperData["filename"], os.R_OK):
                            if wallpaperData["name"] == "":
                                wallpaperData["name"] = os.path.basename(
                                    wallpaperData["filename"])
                            res.append(wallpaperData)
            return res
        except Exception as detail:
            print("Could not parse %s!" % filename)
            print(detail)
            return []
示例#30
0
文件: cs_sound.py 项目: t6/cinnamon
class Module:
    name = "sound"
    category = "hardware"
    comment = _("Manage sound settings")

    def __init__(self, content_box):
        keywords = _(
            "sound, media, music, speakers, audio, microphone, headphone")
        self.sidePage = SidePage(_("Sound"),
                                 "cs-sound",
                                 keywords,
                                 content_box,
                                 module=self)
        self.sound_settings = Gio.Settings(CINNAMON_DESKTOP_SOUNDS)

    def on_module_selected(self):
        if not self.loaded:
            print("Loading Sound module")

            self.outputDeviceList = Gtk.ListStore(
                str,  # name
                str,  # device
                bool,  # active
                int,  # id
                GdkPixbuf.Pixbuf)  # icon

            self.inputDeviceList = Gtk.ListStore(
                str,  # name
                str,  # device
                bool,  # active
                int,  # id
                GdkPixbuf.Pixbuf)  # icon

            self.appList = {}

            self.inializeController()
            self.buildLayout()

        self.checkAppState()
        self.checkInputState()

    def buildLayout(self):
        self.sidePage.stack = SettingsStack()
        self.sidePage.add_widget(self.sidePage.stack)

        ## Output page
        page = SettingsPage()
        self.sidePage.stack.add_titled(page, "output", _("Output"))

        self.outputSelector = self.buildDeviceSelect("output",
                                                     self.outputDeviceList)
        outputSection = page.add_section(_("Device"))
        outputSection.add_row(self.outputSelector)

        devSettings = page.add_section(_("Device settings"))

        # output profiles
        self.profile = ProfileSelector(self.controller)
        devSettings.add_row(self.profile)

        sizeGroup = Gtk.SizeGroup.new(Gtk.SizeGroupMode.HORIZONTAL)

        # ouput volume
        max_volume = self.sound_settings.get_int(MAXIMUM_VOLUME_KEY)
        self.outVolume = VolumeBar(self.controller.get_vol_max_norm(),
                                   max_volume,
                                   sizeGroup=sizeGroup)
        devSettings.add_row(self.outVolume)

        # balance
        self.balance = BalanceBar("balance", sizeGroup=sizeGroup)
        devSettings.add_row(self.balance)
        self.fade = BalanceBar("fade", sizeGroup=sizeGroup)
        devSettings.add_row(self.fade)
        self.woofer = BalanceBar("lfe",
                                 0,
                                 self.controller.get_vol_max_norm(),
                                 sizeGroup=sizeGroup)
        devSettings.add_row(self.woofer)

        ## Input page
        page = SettingsPage()
        self.sidePage.stack.add_titled(page, "input", _("Input"))

        self.inputStack = Gtk.Stack()
        page.pack_start(self.inputStack, True, True, 0)

        inputBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=15)
        self.inputSelector = self.buildDeviceSelect("input",
                                                    self.inputDeviceList)
        deviceSection = SettingsSection("Device")
        inputBox.pack_start(deviceSection, False, False, 0)
        deviceSection.add_row(self.inputSelector)

        devSettings = SettingsSection(_("Device settings"))
        inputBox.pack_start(devSettings, False, False, 0)

        sizeGroup = Gtk.SizeGroup.new(Gtk.SizeGroupMode.HORIZONTAL)

        # input volume
        self.inVolume = VolumeBar(self.controller.get_vol_max_norm(),
                                  max_volume,
                                  sizeGroup=sizeGroup)
        devSettings.add_row(self.inVolume)

        # input level
        self.inLevel = VolumeLevelBar(sizeGroup)
        devSettings.add_row(self.inLevel)
        self.inputStack.add_named(inputBox, "inputBox")

        noInputsMessage = Gtk.Box()
        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
        image = Gtk.Image.new_from_icon_name("action-unavailable-symbolic",
                                             Gtk.IconSize.DIALOG)
        image.set_pixel_size(96)
        box.pack_start(image, False, False, 0)
        box.set_valign(Gtk.Align.CENTER)
        label = Gtk.Label(_("No inputs sources are currently available."))
        box.pack_start(label, False, False, 0)
        noInputsMessage.pack_start(box, True, True, 0)
        self.inputStack.add_named(noInputsMessage, "noInputsMessage")
        self.inputStack.show_all()

        ## Sounds page
        page = SettingsPage()
        self.sidePage.stack.add_titled(page, "sounds", _("Sounds"))

        soundsVolumeSection = page.add_section(_("Sounds Volume"))
        self.soundsVolume = VolumeBar(self.controller.get_vol_max_norm(), 100)
        soundsVolumeSection.add_row(self.soundsVolume)

        soundsSection = SoundBox(_("Sounds"))
        page.pack_start(soundsSection, True, True, 0)
        sizeGroup = Gtk.SizeGroup.new(Gtk.SizeGroupMode.HORIZONTAL)
        for effect in EFFECT_LIST:
            soundsSection.add_row(Effect(effect, sizeGroup))

        ## Applications page
        page = SettingsPage()
        self.sidePage.stack.add_titled(page, "applications", _("Applications"))

        self.appStack = Gtk.Stack()
        page.pack_start(self.appStack, True, True, 0)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.appSettings = SoundBox(_("Applications"))
        box.pack_start(self.appSettings, True, True, 0)
        self.appStack.add_named(box, "appSettings")

        noAppsMessage = Gtk.Box()
        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
        image = Gtk.Image.new_from_icon_name("action-unavailable-symbolic",
                                             Gtk.IconSize.DIALOG)
        image.set_pixel_size(96)
        box.pack_start(image, False, False, 0)
        box.set_valign(Gtk.Align.CENTER)
        label = Gtk.Label(
            _("No application is currently playing or recording audio."))
        box.pack_start(label, False, False, 0)
        noAppsMessage.pack_start(box, True, True, 0)
        self.appStack.add_named(noAppsMessage, "noAppsMessage")

        ## Settings page
        page = SettingsPage()
        self.sidePage.stack.add_titled(page, "settings", _("Settings"))

        amplificationSection = page.add_section(_("Amplification"))
        self.maxVolume = Slider(_("Maximum volume: %d") % max_volume + "%",
                                _("Reduced"),
                                _("Amplified"),
                                1,
                                150,
                                None,
                                step=1,
                                page=10,
                                value=max_volume,
                                gicon=None,
                                iconName=None)
        self.maxVolume.adjustment.connect("value-changed",
                                          self.onMaxVolumeChanged)
        self.maxVolume.setMark(100)
        amplificationSection.add_row(self.maxVolume)

    def onMaxVolumeChanged(self, adjustment):
        newValue = int(round(adjustment.get_value()))
        self.sound_settings.set_int(MAXIMUM_VOLUME_KEY, newValue)
        self.maxVolume.label.set_label(
            _("Maximum volume: %d") % newValue + "%")
        self.outVolume.adjustment.set_upper(newValue)
        self.outVolume.slider.clear_marks()
        if (newValue > 100):
            self.outVolume.setMark(100)

    def inializeController(self):
        self.controller = Cvc.MixerControl(name="cinnamon")
        self.controller.connect("state-changed", self.setChannelMap)
        self.controller.connect("output-added", self.deviceAdded, "output")
        self.controller.connect("input-added", self.deviceAdded, "input")
        self.controller.connect("output-removed", self.deviceRemoved, "output")
        self.controller.connect("input-removed", self.deviceRemoved, "input")
        self.controller.connect("active-output-update",
                                self.activeOutputUpdate)
        self.controller.connect("active-input-update", self.activeInputUpdate)
        self.controller.connect("default-sink-changed",
                                self.defaultSinkChanged)
        self.controller.connect("default-source-changed",
                                self.defaultSourceChanged)
        self.controller.connect("stream-added", self.streamAdded)
        self.controller.connect("stream-removed", self.streamRemoved)
        self.controller.open()

    def buildDeviceSelect(self, type, model):
        select = Gtk.IconView.new_with_model(model)
        select.set_margin(0)
        select.set_pixbuf_column(4)
        select.set_text_column(0)
        select.set_column_spacing(0)

        select.connect("selection-changed", self.setActiveDevice, type)

        return select

    def setActiveDevice(self, view, type):
        selected = view.get_selected_items()
        if len(selected) == 0:
            return

        model = view.get_model()
        newDeviceId = model.get_value(model.get_iter(selected[0]), 3)
        newDevice = getattr(self.controller,
                            "lookup_" + type + "_id")(newDeviceId)
        if newDevice != None and newDeviceId != getattr(self, type + "Id"):
            getattr(self.controller, "change_" + type)(newDevice)
            self.profile.setDevice(newDevice)

    def deviceAdded(self, c, id, type):
        device = getattr(self.controller, "lookup_" + type + "_id")(id)

        iconTheme = Gtk.IconTheme.get_default()
        gicon = device.get_gicon()
        iconName = device.get_icon_name()
        icon = None
        if gicon is not None:
            lookup = iconTheme.lookup_by_gicon(gicon, 32, 0)
            if lookup is not None:
                icon = lookup.load_icon()

        if icon is None:
            if (iconName is not None and "bluetooth" in iconName):
                icon = iconTheme.load_icon("bluetooth", 32, 0)
            else:
                icon = iconTheme.load_icon("audio-card", 32, 0)

        getattr(self, type + "DeviceList").append([
            device.get_description() + "\n" + device.get_origin(), "", False,
            id, icon
        ])

        if type == "input":
            self.checkInputState()

    def deviceRemoved(self, c, id, type):
        store = getattr(self, type + "DeviceList")
        for row in store:
            if row[3] == id:
                store.remove(row.iter)
                if type == "input":
                    self.checkInputState()
                return

    def checkInputState(self):
        if len(self.inputDeviceList) == 0:
            self.inputStack.set_visible_child_name("noInputsMessage")
        else:
            self.inputStack.set_visible_child_name("inputBox")

    def activeOutputUpdate(self, c, id):
        self.outputId = id
        device = self.controller.lookup_output_id(id)

        self.profile.setDevice(device)

        # select current device in device selector
        i = 0
        for row in self.outputDeviceList:
            if row[3] == id:
                self.outputSelector.select_path(
                    Gtk.TreePath.new_from_string(str(i)))
            i = i + 1

        self.setChannelMap()

    def activeInputUpdate(self, c, id):
        self.inputId = id

        # select current device in device selector
        i = 0
        for row in self.inputDeviceList:
            if row[3] == id:
                self.inputSelector.select_path(
                    Gtk.TreePath.new_from_string(str(i)))
            i = i + 1

    def defaultSinkChanged(self, c, id):
        defaultSink = self.controller.get_default_sink()
        if defaultSink == None:
            return
        self.outVolume.setStream(defaultSink)
        self.setChannelMap()

    def defaultSourceChanged(self, c, id):
        defaultSource = self.controller.get_default_source()
        if defaultSource == None:
            return
        self.inVolume.setStream(defaultSource)
        self.inLevel.setStream(defaultSource)

    def setChannelMap(self, a=None, b=None):
        if self.controller.get_state() == Cvc.MixerControlState.READY:
            channelMap = self.controller.get_default_sink().get_channel_map()
            self.balance.setChannelMap(channelMap)
            self.fade.setChannelMap(channelMap)
            self.woofer.setChannelMap(channelMap)

    def streamAdded(self, c, id):
        stream = self.controller.lookup_stream_id(id)

        if stream in self.controller.get_sink_inputs():
            name = stream.props.name

            # FIXME: We use to filter out by PA_PROP_APPLICATION_ID.  But
            # most streams report this as null now... why??
            if name in ("speech-dispatcher", "libcanberra"):
                # speech-dispatcher: orca/speechd/spd-say
                # libcanberra: cinnamon effects, test sounds
                return

            if id in self.appList.keys():
                # Don't add an input more than once
                return

            if name == None:
                name = _("Unknown")

            label = "%s: " % name

            self.appList[id] = VolumeBar(self.controller.get_vol_max_norm(),
                                         100, label, stream.get_gicon())
            self.appList[id].setStream(stream)
            self.appSettings.add_row(self.appList[id])
            self.appSettings.list_box.invalidate_headers()
            self.appSettings.show_all()
        elif stream == self.controller.get_event_sink_input():
            self.soundsVolume.setStream(stream)

        self.checkAppState()

    def streamRemoved(self, c, id):
        if id in self.appList:
            self.appList[id].get_parent().destroy()
            self.appSettings.list_box.invalidate_headers()
            del self.appList[id]
            self.checkAppState()

    def checkAppState(self):
        if len(self.appList) == 0:
            self.appStack.set_visible_child_name("noAppsMessage")
        else:
            self.appStack.set_visible_child_name("appSettings")