Gibt es ein "Orte" -Menü für Ubuntu Unity?

11

Ich würde gerne wissen, ob es möglich ist, im oberen Menü von Ubuntu eine Registerkarte "Orte" zu platzieren, z. B. CentOS, Debian usw.

Vielen Dank

Ulises CT
quelle
Leicht, aber was sollte es genau zeigen?
Jacob Vlijm
Hauptordner (Home, Downloads, Dokumente usw.) und solche mit Lesezeichen wie Debian und Centos
Ulises CT
Ich verstehe, werde heute oder morgen einen schreiben, wenn es noch niemand zuvor getan hat :), oder vielleicht existiert bereits einer (du meinst einen Indikator, oder?)
Jacob Vlijm
Suchen Sie in Google Bilder nach "Orte Menü Debian" und Sie werden sehen, was ich meine.
Ulises CT
Nein, das war ein klassisches Menü. Alles, was ich fand, war veraltetes Zeug mit einem Zentimeter Staub darauf. Ich kann ziemlich schnell eine grundlegende schreiben (und werde es tun). Ich möchte es jedoch mit diesem zusammenführen: askubuntu.com/questions/803869/… , was es zu einem interessanten Projekt machen würde. Der erste Schuss heute oder morgen wird daher nicht der letzte sein. Gute Frage.
Jacob Vlijm

Antworten:

12

Ich habe mehrere vorhandene ausprobiert, konnte jedoch keinen Indikator für funktionierende Orte finden . Diejenigen, die ich fand, waren veraltet, ppas wurden nicht mehr gepflegt.

Menü "Modulare Orte"

Also, unten ein frisch geschriebener: Places & Files Indikator für Ubuntu .

Geben Sie hier die Bildbeschreibung ein 2

Die ppa-Version ist modular aufgebaut ; Sie können auswählen, was im Menü angezeigt werden soll:

[ Geben Sie hier die Bildbeschreibung ein]

In der Vollversion:

Geben Sie hier die Bildbeschreibung ein

... oder die kleinste, die nur kürzlich verwendete zeigt:

Geben Sie hier die Bildbeschreibung ein

Installation von ppa

sudo add-apt-repository ppa:vlijm/placesfiles
sudo apt-get update
sudo apt-get install placesfiles

Eine vereinfachte Version zum Anzeigen eines Ortsmenüs, von Lesezeichen und kürzlich verwendeten Dateien

Beschreibung & (Anfangs-) Code

Das Skript

#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread
import os
import subprocess

class Indicator():
    def __init__(self):

        currpath = os.path.dirname(os.path.realpath(__file__))
        self.home = os.environ["HOME"]
        self.bmark_file = os.path.join(self.home, ".config/gtk-3.0/bookmarks")
        self.def_file = os.path.join(self.home, ".config/user-dirs.dirs")
        self.recdata = os.path.join(self.home, ".local/share/recently-used.xbel")
        self.n = 10
        self.app = 'places'
        iconpath = os.path.join(currpath, "dir_icon.png")
        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
        self.indicator.set_label("Places", self.app)
        self.indicator.set_menu(self.create_menu())
        # the thread:
        self.update = Thread(target=self.check_recent)
        self.update.setDaemon(True)
        self.update.start()

    def create_menu(self):
        # creates the (initial) menu
        self.menu = Gtk.Menu()
        # separator
        initial = Gtk.MenuItem("Fetching list...")
        menu_sep = Gtk.SeparatorMenuItem()
        self.menu.append(initial)
        self.menu.append(menu_sep)
        # item_quit.show() 
        self.menu.show_all()
        return self.menu

    def open_directory(self, *args):
        index = self.menu.get_children().index(self.menu.get_active())
        selection = self.menu_items2[index-2]
        self.execute(["xdg-open", selection])

    def open_file(self, *args):
        index = self.submenu.get_children().index(self.submenu.get_active())
        selection = self.submenu2[index] 
        self.execute(["xdg-open", selection])

    def go_special(self, button, target):
        self.execute(["xdg-open", target])

    def connect(self, button):
        self.execute("nautilus-connect-server")

    def set_new(self):
        # update the list, appearing in the menu
        for i in self.menu.get_children():
            self.menu.remove(i)
        home_mention = Gtk.MenuItem("⌂ Home")
        home_mention.connect("activate", self.go_special, self.home)
        self.menu.append(home_mention)
        # separator
        menu_sep1 = Gtk.SeparatorMenuItem()
        self.menu.append(menu_sep1)
        for app in self.menu_items2:
            sub = Gtk.MenuItem("⏍ "+app.split("/")[-1])
            self.menu.append(sub)
            sub.connect('activate', self.open_directory)
        # separator
        menu_sep2 = Gtk.SeparatorMenuItem()
        self.menu.append(menu_sep2)
        # network
        network = "network:///"
        network_mention = Gtk.MenuItem("⇄ Network")
        network_mention.connect("activate", self.go_special, network)
        self.menu.append(network_mention)
        connect_mention = Gtk.MenuItem("⮁ Connect to server")
        connect_mention.connect("activate", self.connect)
        self.menu.append(connect_mention)
        # separator
        menu_sep3 = Gtk.SeparatorMenuItem()
        self.menu.append(menu_sep3)
        # computer
        computer = "computer:///"
        computer_mention = Gtk.MenuItem("⛁ Computer")
        computer_mention.connect("activate", self.go_special, computer)
        self.menu.append(computer_mention)
        recent_mention = Gtk.MenuItem("⁕ Recent files")
        self.menu.append(recent_mention)

        self.submenu = Gtk.Menu()
        for f in self.submenu2:
            recent = Gtk.MenuItem(f)
            recent.connect("activate", self.open_file)
            self.submenu.append(recent)
        recent_mention.set_submenu(self.submenu)
        # separator
        menu_sep6 = Gtk.SeparatorMenuItem()
        self.menu.append(menu_sep6)
        # quit
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        self.menu.append(item_quit)
        self.menu.show_all()

    def run_about(self, *args):
        self.execute("/opt/upfront/code/runabout")

    def check_recent(self):
        self.menu_items1 = []; self.submenu1 = []
        while True:
            time.sleep(4)
            self.menu_items2 = self.get_bookmarks()
            self.submenu2 = self.get_files()

            if any([self.menu_items2 != self.menu_items1,
                self.submenu2 != self.submenu1]):
                GObject.idle_add(
                    self.set_new, 
                    priority=GObject.PRIORITY_DEFAULT
                    )
            self.menu_items1 = self.menu_items2
            self.submenu1 = self.submenu2

    def stop(self, source):
        Gtk.main_quit()

    def get_bookmarks(self):
        loc_bookmarks = [
            l.replace("file://", "") for l in open(self.bmark_file).read().splitlines()\
            if l.startswith("file://")
            ]
        netw_bookmarks = [
            l for l in open(self.bmark_file).read().splitlines()\
            if l.startswith("smb://")
            ]
        defaults = [
            os.path.join(self.home, l.replace('"', "").split("$HOME/")[-1]) for l in \
            open(self.def_file).read().splitlines() if all\
            (["$HOME/" in l, l.startswith("XDG")])
            ]
        return [self.replace_sc(m.split(" ")[0]).rstrip("/") for m in list(
            set(loc_bookmarks+defaults+netw_bookmarks))]

    def replace_sc(self, path):
        for c in [("%23", "#"), ("%5D", "]"), ("%5E", "^"),
                  ("file://", ""), ("%20", " ")]:
            path = path.replace(c[0], c[1])
        return path

    def execute(self, command):
        subprocess.Popen(command)

    def get_files(self):
        # create the list of recently used files
        used = [l for l in open(self.recdata) if all([
                    '<bookmark href="file://' in l, not "/tmp" in l, "." in l])]
        relevant = [l.split('="') for l in set(used)]
        relevant = [[it[1][7:-7], it[-2][:-10]] for it in relevant]
        relevant.sort(key=lambda x: x[1])
        return [item[0].replace("%20", " ") for item in relevant[::-1][:self.n]]


Indicator()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()

Verwendung (falls nicht von ppa installiert)

  1. Kopieren Sie das Skript in eine leere Datei und speichern Sie es unter places_indicator.py
  2. Speichern Sie das Symbol (Rechtsklick> Speichern unter) mit genauem Namen:

    dir_icon.png
    

    Geben Sie hier die Bildbeschreibung ein

    ..in ein und demselben Verzeichnis wie das Skript.

  3. Testen Sie das Skript mit dem folgenden Befehl:

    python3 /path/to/places_indicator.py
    
  4. Wenn alles einwandfrei funktioniert, fügen Sie es zu Startanwendungen hinzu: Dash> Startanwendungen> Hinzufügen. Fügen Sie den Befehl hinzu:

    /bin/bash -c "sleep 10 && python3 /path/to/places_indicator.py
    

Über den Indikator

Der Indikator zeigt:

  1. Das Home-Verzeichnis
  2. Alle Verzeichnisse (lokale Lesezeichen und jdm) in
    • ~/.config/gtk-3.0/bookmarks
    • ~/.config/user-dirs.dirs
  3. Netzwerk
  4. Stellen Sie eine Verbindung zum Netzwerk her
  5. Computer
  6. Kürzlich verwendete Dateien (Lats 10 wie es ist, könnte leicht geändert werden)

Das Ändern / Hinzufügen / Entfernen von Lesezeichen wird dynamisch aktualisiert

Jacob Vlijm
quelle
ziemlich gut, ich habe das auf Unity ausprobiert und funktioniert danke! Aber ich habe mich für Gnome entschieden, weil es schöner aussieht, aber ich werde dieses auch für die aktuelle Filess-Funktion verwenden! danke
Ulises CT
@UlisesCT Ah, danke, dass du Unity anprobiert hast, obwohl du gewechselt hast!
Jacob Vlijm
Ja! Das Problem ist, dass ich von Windows für Desktop-PCs komme und unter Linux nie grafisches Material verwendet habe, sondern nur unter CentOS für Server und dergleichen. Als ich Ubuntu von Ubuntu.es installierte, dachte ich, die Benutzeroberfläche sei genau diese und wusste es nicht Es gibt Gnome und Unity, die Sie auswählen können (ich habe die Registerkarte "Orte" verpasst, da ich unter CentOS versucht habe, es als Desktop zu versuchen, aber es ist irgendwie scheiße). Gut, um weiter zu lernen
Ulises CT
Wow, diese Verpflichtung - ein neues Programm schreiben, um dieses Bedürfnis zu erfüllen! Sehr beeindruckt, gut gemacht @JacobVlijm! Warum ist es Version 0.5.1-1, wenn Sie es gerade erst geschrieben haben?
Ads20000
@ Ads20000 Danke! Ein paar Verbesserungen; (neu) verschobene oder umbenannte Dateien werden jetzt markiert, eine Benachrichtigung wird angezeigt, wenn Sie (versuchen), sie zu öffnen, anderes aktuelles Symbol, funktioniert jetzt auch am 14.04, geringfügige Optimierung des Codes (Herausfiltern von Sonderzeichen in Dateinamen) usw.
Jacob Vlijm
8

Update 24.02.2017 : Der Indikator bietet jetzt die Möglichkeit, Weblinks zu fixieren

Einführung

HINWEIS: Die vorherige Version dieser Antwort befindet sich im Bearbeitungsverlauf, obwohl sie nicht mehr relevant ist.

Der unten dargestellte Indikator war für eine andere Frage gedacht, aber da sich die Gelegenheit bot, habe ich beschlossen, ihn hier zu veröffentlichen. Die Dateianzeige ist eine einfache Anzeige für den Zugriff auf Benutzerdateien und -ordner. Es ermöglicht das Überprüfen kürzlich verwendeter Dateien, das Setzen von Lesezeichen für Dateien und Verzeichnisse. Insbesondere das Menü Orte ist für diese Frage besonders relevant.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Wie Sie auf dem Screenshot sehen können, unterstützt der Indikator auch andere Gebietsschemas als Englisch. Wenn Ihr System also etwas anderes als Englisch verwendet, funktioniert es.

Update : Der Indikator unterstützt jetzt auch das Starten von .desktop-Dateien, die angeheftet wurden. Wenn Sie beispielsweise Firefox.desktop angeheftet haben, wird Firefox gestartet. Somit kann der Indikator als Schnellstarter für Programme verwendet werden. Die Funktion befindet sich zum Zeitpunkt des Schreibens (19. November, 19:53 Uhr GMT, die Verarbeitung sollte ungefähr 24 Stunden dauern) auf dem Weg in PPA, ist jedoch bereits auf Github sowie hier im aktualisierten Quellcode verfügbar.

Geben Sie hier die Bildbeschreibung ein

Den Indikator erhalten

Der Indikator ist sowohl bei meinem persönlichen PPA als auch bei GitHub erhältlich . Führen Sie die folgenden Schritte aus, um es zu erhalten:

sudo add-apt-repository ppa:1047481448-2/sergkolo
sudo apt-get update
sudo apt-get install files-indicator

Quellcode

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#
# Author: Serg Kolo , contact: [email protected]
# Date: November 19 , 2016
# Purpose: appindicator for accessing files and folders
# Tested on: Ubuntu 16.04 LTS
#
#
# Licensed under The MIT License (MIT).
# See included LICENSE file or the notice below.
#
# Copyright © 2016 Sergiy Kolodyazhnyy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import gi
gi.require_version('AppIndicator3', '0.1')
gi.require_version('Notify', '0.7')
from gi.repository import GLib as glib
from gi.repository import AppIndicator3 as appindicator
from gi.repository import Gtk as gtk
from gi.repository import Gio
from gi.repository import Notify
from collections import OrderedDict
# from collections import OrderedDict
import urllib.parse
import subprocess
import copy
import shutil
import dbus
import math
import json
import os

class FilesIndicator(object):

    def __init__(self):
        self.app = appindicator.Indicator.new(
            'files-indicator', "document-open-recent",
            appindicator.IndicatorCategory.HARDWARE
        )
        self.user_home = os.path.expanduser('~')
        filename = '.pinned_files.json'
        self.pinned_list = os.path.join(self.user_home,filename)

        self.config = os.path.join(self.user_home,'.files_indicator.json')
        self.max_items = 15
        self.name_length = 20
        self.read_config()

        self.app.set_status(appindicator.IndicatorStatus.ACTIVE)

        self.cached_files = self.get_recent_files()
        self.make_menu()
        self.update()

    def read_config(self,*args):
        config = {}
        try:
            with open(self.config) as f:
                 config = json.load(f)

        except FileNotFoundError:
            print('>>> ',self.config,' not found.Creating one')
            f = open(self.config,'w')
            config = {'max_items':self.max_items,
                      'name_length':self.name_length
            }
            json.dump(config,f,indent=4)
            f.close()
        except json.JSONDecodeError:
            print(">>> Can't read ",self.pinned_list,',may be corrupt')
            return None
        else:
            self.max_items = config['max_items']
            self.name_length = config['name_length']

    def add_menu_item(self, menu_obj, item_type, image, label, action, args):
        """ dynamic function that can add menu items depending on
            the item type and other arguments"""
        menu_item, icon = None, None
        if item_type is gtk.ImageMenuItem and label:
            menu_item = gtk.ImageMenuItem.new_with_label(label)
            menu_item.set_always_show_image(True)
            if '/' in image:
                icon = gtk.Image.new_from_file(image)
            else:
                icon = gtk.Image.new_from_icon_name(image, 48)
            menu_item.set_image(icon)
        elif item_type is gtk.ImageMenuItem and not label:
            menu_item = gtk.ImageMenuItem()
            menu_item.set_always_show_image(True)
            if '/' in image:
                icon = gtk.Image.new_from_file(image)
            else:
                icon = gtk.Image.new_from_icon_name(image, 16)
            menu_item.set_image(icon)
        elif item_type is gtk.MenuItem:
            menu_item = gtk.MenuItem(label)
        elif item_type is gtk.SeparatorMenuItem:
            menu_item = gtk.SeparatorMenuItem()
        if action:
            menu_item.connect('activate', action, *args)

        menu_obj.append(menu_item)
        menu_item.show()

    def get_user_dirs(self,*args):
        user_dirs = []
        for index,val in glib.UserDirectory.__enum_values__.items():
            if index == 8: continue
            dir = glib.get_user_special_dir(index)
            if dir: user_dirs.append(dir)
        return user_dirs

    def get_file_icon(self,*args):
        if args[-1].endswith('.desktop'):
            desk_file = Gio.DesktopAppInfo.new_from_filename(args[-1])
            icon = desk_file.get_icon()
            if type(icon) == Gio.ThemedIcon:
                themed_name = icon.get_names()[0]
                theme = gtk.IconTheme.get_default()
                name = theme.lookup_icon(themed_name, 48, 0).get_filename()
            if type(icon) == Gio.FileIcon:
                name = icon.get_file().get_uri()

            icon_url= urllib.parse.unquote(name).replace('file://','') 
            return icon_url

        file = Gio.File.new_for_path(args[-1])
        file_info = file.query_info("standard::*",0)
        icon_string = file_info.get_icon().to_string()
        if 'folder-' in icon_string:
            return icon_string.split()[-2]
        return icon_string.split()[-1]

    def get_recent_files(self,*args):
        manager = gtk.RecentManager.get_default()
        try:
            files = OrderedDict()
            for index,item in enumerate(manager.get_items(),1):
                    uri = item.get_uri()
                    uri_decoded = urllib.parse.unquote(uri)
                    filepath = uri_decoded.replace('file://','')
                    if not os.path.exists(filepath): continue
                    basename = os.path.basename(uri_decoded)
                    files[basename] = filepath
                    if index == self.max_items:
                        break
        except Exception as e:
            print(e)
            return None
        finally:  return files

    def callback(self,*args):
        self.update()

    def update(self,*args):
        current_files = self.get_recent_files()
        if current_files != self.cached_files:
             self.make_menu()
             self.cached_files = current_files
        glib.timeout_add_seconds(3,self.callback)

    def add_submenu(self,top_menu,label):
        menuitem = gtk.MenuItem(label)
        submenu = gtk.Menu()
        menuitem.set_submenu(submenu)
        top_menu.append(menuitem)
        menuitem.show()
        return submenu

    def make_menu(self):
        if hasattr(self, 'app_menu'):
            for item in self.app_menu.get_children():
                    self.app_menu.remove(item)
        else:
            self.app_menu = gtk.Menu()
        recent = self.add_submenu(self.app_menu,'Recent Files')
        recent_dict = self.get_recent_files()

        content = [recent,gtk.ImageMenuItem,'gtk-add',
                   'Add to Recent Files',self.add_recent,[None]
        ]      
        self.add_menu_item(*content) 

        content = [recent,gtk.ImageMenuItem,'user-trash',
                   'Clear recent files list',self.clear_recent,[None]
        ]      
        self.add_menu_item(*content)

        content = [recent,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)
        self.add_menu_item(*content) 
        if not recent_dict:
            content = [recent,gtk.MenuItem,None,
                       'No items',None,None
            ]
            self.add_menu_item(*content)
            last = None
            for i in recent.get_children():
                last = i
            last.set_sensitive(False)
        else:
            for name,data in recent_dict.items():
                icon = self.get_file_icon(data)
                content = [recent, gtk.ImageMenuItem,
                           icon, name[:self.name_length],
                           self.open_item, [data]
                ]
                self.add_menu_item(*content)

        # Pinned files
        bookmarks = self.add_submenu(self.app_menu,'Pinned Files')
        content = [bookmarks,gtk.ImageMenuItem,
                   'bookmark_add','Pin a file',
                   self.pin_file,[bookmarks,None]
        ]
        self.add_menu_item(*content)

        content = [bookmarks,gtk.ImageMenuItem,
                   'remove','Remove item',
                   self.remove_pinned,['files']
        ]
        self.add_menu_item(*content)

        content = [bookmarks,gtk.ImageMenuItem,
                   'user-trash','Remove All',
                   self.remove_all_pinned,[None]
        ]
        self.add_menu_item(*content)
        content = [bookmarks,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)
        self.add_menu_item(*content) 

        pinned_files = self.get_pinned()

        if (pinned_files and 
            'files' in pinned_files.keys() and
            pinned_files['files']):
            for filepath in pinned_files['files']:
                icon = self.get_file_icon(filepath) 
                content = [bookmarks,gtk.ImageMenuItem,
                           icon,os.path.basename(filepath),
                           self.open_item,[filepath]
                ]
                self.add_menu_item(*content)
        else:
            content = [bookmarks,gtk.MenuItem,None,
                       'No items',None,None
            ]
            self.add_menu_item(*content)
            last = None
            for i in bookmarks.get_children():
                last = i
            last.set_sensitive(False)

        places = self.add_submenu(self.app_menu,'Places')
        content = [places,gtk.ImageMenuItem,'add',
                   'Pin Directory',self.pin_dir,[None]
        ]

        self.add_menu_item(*content)

        content = [places,gtk.ImageMenuItem,
                   'remove','Remove Pinned',
                   self.remove_pinned,['dirs']
        ]
        self.add_menu_item(*content)

        content = [places,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)

        content = [places,gtk.MenuItem,None,
                   'Standard Dirs',None,None
        ]
        self.add_menu_item(*content)
        last = None
        for i in places.get_children():
            last = i
        last.set_sensitive(False)
        for dir in self.get_user_dirs():
            icon = self.get_file_icon(dir)
            content = [places,gtk.ImageMenuItem,icon,
                       os.path.basename(dir),self.open_item,[dir]

            ]
            self.add_menu_item(*content)

        content = [places,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)

        content = [places,gtk.MenuItem,None,
                   'Pinned Dirs',None,None
        ]
        self.add_menu_item(*content)
        last = None
        for i in places.get_children():
            last = i
        last.set_sensitive(False)

        if (pinned_files and 
           'dirs' in pinned_files.keys() and
           pinned_files['dirs']):
            for dir in pinned_files['dirs']:
                icon = self.get_file_icon(dir)
                print(icon)
                content = [places,gtk.ImageMenuItem,icon,
                           os.path.basename(dir),self.open_item,[dir]

                ]
                self.add_menu_item(*content)
        else:
            content = [places,gtk.MenuItem,None,
                       'No items',None,None
            ]
            self.add_menu_item(*content)
            last = None
            for i in places.get_children():
                last = i
            last.set_sensitive(False)

        content = [self.app_menu,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)
        content = [self.app_menu,gtk.ImageMenuItem,'exit',
                   'quit',self.quit,[None]
        ]
        self.add_menu_item(*content)
        self.app.set_menu(self.app_menu)

    def check_directory(self,*args):
        current_set = set(os.listdir(args[-1]))
        return current_set - self.cached_set


    def get_pinned(self,*args):
        try:
            with open(self.pinned_list) as f:
                 return json.load(f,object_pairs_hook=OrderedDict)

        except FileNotFoundError:
            print('>>> ',self.pinned_list,' not found')
            return None
        except json.JSONDecodeError:
            print(">>> Can't read ",self.pinned_list,',may be corrupt')
            return None

    def pin_dir(self,*args):
        # TODO
        current_list = self.get_pinned()
        if not current_list:
                current_list = OrderedDict()
                current_list['dirs'] = []
                f = open(self.pinned_list,'w')
                f.write("")
                f.close()

        if not args[-1]:
                cmd = "zenity --file-selection --directory --separator || --multiple"
                dirs = self.run_cmd(cmd.split())
        else:
                dirs = args[-1]

        dir_list = []
        if not dirs: return None
        dir_list = dirs.decode().strip().split("||")
        if not 'dirs' in current_list.keys():
             current_list['dirs'] = []
        for f in dir_list:
                #icon = self.get_file_icon(f)
                current_list['dirs'].append(f)

        with open(self.pinned_list,'w') as f:
                json.dump(current_list,f,indent=4)
        self.make_menu()

    def pin_file(self,*args):
        current_list = self.get_pinned()
        if not current_list:
                current_list = OrderedDict()
                current_list['files'] = []
                f = open(self.pinned_list,'w')
                f.write("")
                f.close()
        if not args[-1]:
                cmd = "zenity --file-selection --separator || --multiple "
                files = self.run_cmd(cmd.split())
        else:
                files = args[-1]

        file_list = []
        if not files: return None
        file_list = files.decode().strip().split("||")
        if not 'files' in current_list.keys():
            current_list['files'] = []
        for f in file_list:
                #icon = self.get_file_icon(f)
                current_list['files'].append(f)

        with open(self.pinned_list,'w') as f:
                json.dump(current_list,f,indent=4)
        self.make_menu()

    def remove_all_pinned(self,*args):
        try:
            #os.unlink(self.pinned_list)

            with open(self.pinned_list) as f:
                pinned = json.load(f)
            pinned.pop('files')       
            with open(self.pinned_list,'w') as f:
                    json.dump(pinned,f,indent=4)
        except:
            pass
        finally:
            self.make_menu()

    def remove_pinned(self,*args):
        key = args[-1]
        pinned = self.get_pinned() 
        if not pinned: return
        cmd_str = "zenity --forms --add-combo Remove --combo-values"
        vals = "|".join(pinned[key])
        cmd = cmd_str.split() + [vals]
        item = self.run_cmd(cmd)
        if item: 
            path = item.decode().strip()
            index = pinned[key].index(path)
            pinned[key].pop(index)
            with open(self.pinned_list,'w') as f:
                json.dump(pinned,f,indent=4)
            self.make_menu()

    def add_recent(self,*args):
        cmd = "zenity --file-selection --separator || --multiple "
        files = self.run_cmd(cmd.split())
        file_list = []
        if not files: return
        file_list = files.decode().strip().split("||")
        items = ['file://' + f for f in file_list]
        for f in items: gtk.RecentManager().get_default().add_item(f)

    def clear_recent(self,*args):
        try:
            gtk.RecentManager.get_default().purge_items()
            self.make_menu()
        except:
            pass

    def open_item(self,*args):
        #self.run_cmd(['xdg-open',args[-1]]) 
        if args[-1].endswith('.desktop'):
            desk_file = Gio.DesktopAppInfo.new_from_filename(args[-1])
            return desk_file.launch_uris()
        return subprocess.Popen(['xdg-open',args[-1]])

    def quit(self,*args):
        gtk.main_quit()

    def run_cmd(self, cmdlist):
        """ utility: reusable function for running external commands """
        #new_env = dict(os.environ)
        #new_env['LC_ALL'] = 'C'
        try:
            stdout = subprocess.check_output(cmdlist) #env=new_env)
        except subprocess.CalledProcessError:
            pass
        else:
            if stdout:
                return stdout

    def run(self):
        """ Launches the indicator """
        try:
            gtk.main()
        except KeyboardInterrupt:
            pass

    def quit(self, *args):
        """ closes indicator """
        gtk.main_quit()


def main():
    """ defines program entry point """
    indicator = FilesIndicator()
    indicator.run()

if __name__ == '__main__':
  try:
    main()
  except  KeyboardInterrupt:
    gtk.main_quit()

Konfigurationen

Der Indikator wird über zwei JSON-Dateien konfiguriert, die im Home-Verzeichnis des Benutzers gespeichert sind.

~/.files_indicator.json Steuert die Benutzeroberfläche, die Länge der Menüeinträge und die maximale Anzahl im Menü "Zuletzt verwendete Dateien".

{
    "name_length": 30,
    "max_items": 10
}

Das ~/.pinned_files.jsonsteuert die Listen der angehefteten Dateien und Ordner. Jedes Element ist eine Liste / ein Array.

{
    "dirs": [
        "/home/xieerqi/\u56fe\u7247/Wallpapers"
    ],
    "files": [
        "/home/xieerqi/work_in_progress/videonauth_code.py",
        "/home/xieerqi/work_in_progress/spin_button.py"
    ]
}
Sergiy Kolodyazhnyy
quelle
Wow, beeindruckt, dass Sie auch für dieses Problem eine Lösung gefunden haben! : D
Ads20000
@ Ads20000 Danke :) Dieser Indikator war ursprünglich nur für aktuelle Dateien gedacht. Als ich die Frage sah, dachte ich, das Feature wäre auch schön, um es dem Indikator hinzuzufügen, und es war sehr einfach zu implementieren - ich
brauchte fast
Ihre Arbeit hat es auch zu einem OMG gemacht! Ubuntu! Artikel ! : D
Ads20000
Ja, das habe ich gesehen :)
Sergiy Kolodyazhnyy
0

Okay Leute, ich habe nur Ubuntu-Gnome installiert und die 'Places'-Erweiterung im Tweak-Tool aktiviert und verstanden. Ich muss sagen, Ubuntu Gnome sieht viel besser aus als Unity

Siehe die Registerkarte "Lugares"

Ulises CT
quelle
Weise Entscheidung. Es war von Anfang an klar, dass Sie sich für die Verwendung von GNOME interessieren, da es Ihnen von CentOS besser bekannt ist. Was sie in CentOS verwenden, ist übrigens GNOME Flashback. Es soll der vorherigen Version optisch ähnlich sein, jedoch neuere Technologien verwenden. Unity ist möglicherweise nicht jedermanns Sache, obwohl ich GNOME persönlich nicht mag, weil es ständig Features entfernt und die Entwicklung komplex macht.
Sergiy Kolodyazhnyy
Ja genau, ich bin ein bisschen "noob" in Linux oder "veraltet", wie Sie es lieber sagen. Ich meine, ich habe immer ein Terminal für Server unter CentOS verwendet, und nicht viel Grafikmaterial. Ich wusste nicht, dass es verschiedene grafische Optionen wie Unity und Gnome gibt. Ich dachte nur, Ubuntu kann nur so aussehen, wie es aussieht Das Ubuntu.com-Download-Paket, CentOS wie auf der offiziellen Webseite usw. Wussten Sie nicht, dass Sie verschiedene grafische Optionen haben können? Gut, weiter zu lernen. @ Serg
Ulises CT
Lassen Sie mich folgende Frage stellen: Wenn Sie unbedingt Unity Desktop verwenden müssten, welche anderen Dinge hätten Sie sich gewünscht? (Offensichtlich versuche ich, Ideen für zukünftige Verwendungen zu recherchieren :)
Sergiy Kolodyazhnyy
Das einzige, woran ich denken kann, ist die Registerkarte "Orte" oder "Anwendungen" (die ich nicht wirklich benutze). Der Rest ist auch in Unity verfügbar. Ich denke, was mir von gnome nicht gefällt, ist das für das Anwendungsmenü müssen bei den meisten Programmen (dem typischen Menü für Datei, Bearbeitung usw.) auf eine Schaltfläche klicken
Ulises CT