Чи існує меню "Місця" для Ubuntu Unity?


11

Мені хотілося б знати, чи можна поставити вкладку "Місця" у верхньому меню Ubuntu, наприклад CentOS, Debian тощо.

Спасибі


Легко, але що саме воно повинно показувати?
Яків Влійм

основні папки (домашня, завантаження, документ тощо) та ті, що мають закладки, такі як debian та centos
Ulises CT

Я бачу, напишу сьогодні сьогодні чи завтра, якщо ніхто до цього не зробив :), або, можливо, такий вже існує (ви маєте на увазі показник, правда?)
Яків Влійм

шукайте "Меню місць Debian" в Google Images, і ви побачите, що я маю на увазі.
Ulises CT

Ні, це було класичне меню. Все, що я знайшов, - це застарілі речі з дюймом пилу. Я можу досить швидко написати базовий (і заповіт). Я хотів би об'єднати його з цим: askubuntu.com/questions/803869/… , що зробить його цікавим проектом. Перший кадр сьогодні чи завтра не буде остаточним. Приємне запитання.
Яків Влійм

Відповіді:


12

Я спробував кілька існуючих, але не зміг знайти робочий індикатор Місця . Ті, кого я знайшов, застаріли, Ppa вже не підтримувались.

Модульне меню Місця

Отже, нижче щойно написаного індикатора : Місця та файли для Ubuntu .

введіть тут опис зображення 2

Версія ppa - модульна ; ви можете вибрати, що відображати в меню:

[ введіть тут опис зображення]

У повній версії:

введіть тут опис зображення

... або найменший, лише показаний нещодавно використаний:

введіть тут опис зображення

Установка з ppa

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

Спрощена версія для відображення меню місць, закладок та нещодавно використаних файлів

Опис та (початковий) код

Сценарій

#!/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()

Як користуватися (якщо не встановлено з ppa)

  1. Скопіюйте скрипт у порожній файл, збережіть його як places_indicator.py
  2. Збережіть піктограму (клацніть правою кнопкою миші> зберегти як) точно названою:

    dir_icon.png
    

    введіть тут опис зображення

    ..в одному і тому ж каталозі , що і сценарій.

  3. Тест - запустіть скрипт командою:

    python3 /path/to/places_indicator.py
    
  4. Якщо все працює добре, додайте його до програм запуску: тире> програми запуску> Додати. Додайте команду:

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

Про показник

Індикатор показує:

  1. Домашній каталог
  2. Усі каталоги (локальні закладки та SMB) в
    • ~/.config/gtk-3.0/bookmarks
    • ~/.config/user-dirs.dirs
  3. Мережа
  4. Підключення до мережі
  5. Комп'ютер
  6. Нещодавно використані файли (багато 10, як є, можна легко змінити)

Зміна / додавання / видалення закладок оновлюється динамічно


досить добре, я спробував це на Unity і працює спасибі! Але я вирішив використати Gnome, хоча це виглядає красивіше, але я також використаю цю для останньої бездротової функції! дякую
Ulises CT

@UlisesCT О, дякую за те, що приміряв Unity, незважаючи на те, що ти перейшов!
Яків Влійм

так! проблема в тому, що я прийшов з Windows для настільних ПК, і ніколи не використовував графічні речі в Linux, просто термінал на CentOS для серверів і подібних, і коли я встановив ubuntu з ubuntu.es, я подумав, що його GUI був саме таким, і не знав є Gnome та Unity, які ви можете вибрати (я пропустив вкладку "Місця", тому що це було на CentOS, яке я спробував спробувати як на робочому столі, але він начебто відстій). Приємно продовжувати вчитися
Ulises CT

Нічого собі, що зобов'язання - написання нової програми для задоволення цієї потреби! Дуже вражений, молодець @JacobVlijm! Чому це версія 0.5.1-1, якщо ви тільки що це написали?
Оголошення20000

@ Ads20000 Дякую! Кілька поліпшень; (пере) перенесені або перейменовані файли тепер позначені, відображається повідомлення, якщо ви (намагаєтесь) їх відкрити, різні нещодавні піктограми, тепер також працює 14.04, незначна оптимізація коду (фільтрація спеціальних символів у назви файлів) тощо.
Яків Влійм

8

Оновлення лютого / 24/2017 : індикатор тепер має можливість для закріплення веб-посилань

Вступ

ПРИМІТКА. Попередню версію цієї відповіді можна знайти в історії редагування, але вона більше не стосується.

Індикатор, представлений нижче, призначений для іншого питання, але оскільки представлена ​​можливість, я вирішив відпустити його тут. Індикатор файлів - це простий індикатор доступу до файлів і папок користувача. Це дозволяє перевіряти нещодавно використані файли, файли закладок та каталоги. Зокрема, меню Місця на місцях особливо стосується цього питання.

введіть тут опис зображення

введіть тут опис зображення

Як видно із скріншоту, індикатор також підтримує локалі, крім англійської, тому якщо ваша система використовує щось інше, ніж англійська, вона буде працювати.

Оновлення : індикатор тепер також підтримує запуск файлів .desktop, які були закріплені. Наприклад, якщо ви закріпили firefox.desktop, він запустить firefox. Таким чином, індикатор може бути використаний як швидкий запуск програм. Ця функція перебуває на шляху до PPA під час написання (19 листопада, 19:53 GMT, обробка повинна зайняти близько 24 годин), але вона вже є в github, як і тут, в оновленому вихідному коді.

введіть тут опис зображення

Отримання показника

Індикатор доступний у мого особистого PPA, а також у GitHub . Для його отримання виконайте такі дії:

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

Вихідний код

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

#
# Author: Serg Kolo , contact: 1047481448@qq.com
# 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()

Конфігурації

Індикатор налаштовано за допомогою двох файлів json, що зберігаються в домашньому каталозі користувача.

~/.files_indicator.json керує користувальницьким інтерфейсом, довжиною записів у меню та максимальними числами у меню Останні файли.

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

~/.pinned_files.jsonКонтролює списки покладали файлів і папок. Кожен елемент - це список / масив.

{
    "dirs": [
        "/home/xieerqi/\u56fe\u7247/Wallpapers"
    ],
    "files": [
        "/home/xieerqi/work_in_progress/videonauth_code.py",
        "/home/xieerqi/work_in_progress/spin_button.py"
    ]
}

Вау, вражений, що ви створили рішення і для цієї проблеми! : D
Реклама20000

@ Ads20000 Спасибі :) Спочатку цей показник мав бути лише для останніх файлів. Коли я побачив це питання, я подумав, що цю функцію було б непогано додати до індикатора, плюс це було дуже просто здійснити - взяв мене досить одного ранку та 2 чашки кави :)
Сергій Колодяжний

Ваша робота також перетворилася на OMG! Ubuntu! стаття ! : D
Реклама20000

Так, я це бачив :)
Сергій Колодяжний

0

Добре, хлопці, я тільки що встановив Ubuntu-Gnome і включив розширення "Місця" в інструмент Tweak і отримав його. Треба сказати, що Ubuntu Gnome виглядає набагато краще, ніж Unity

Дивіться вкладку "Лугарес"


Мудрий вибір. З самого початку це було зрозуміло, що ви схиляєтесь до використання GNOME, оскільки це вам більше знайоме від CentOS. До речі, вони використовують у CentOS - це GNOME Flashback. Це повинно бути візуально схожим на попередню версію, але використовувати новішу технологію. Що стосується Unity, то це може бути не для всіх, хоча мені особисто дуже не подобається GNOME за постійне видалення функцій і ускладнення розробки.
Сергій Колодяжний

Так, я неначе "нооб" в Linux або "застарілий", як ви вважаєте за краще. Я маю на увазі, я завжди використовував термінал для серверів на CentOS, і не багато графічних речей, я не знав, що існують різні графічні параметри, такі як Unity та Gnome, я просто думав, що Ubuntu може виглядати лише так, як це робиться з пакет завантаження ubuntu.com, CentOS так, як це робиться з офіційної веб-сторінки тощо. Не знав, що у вас можуть бути різні графічні варіанти. Добре продовжувати вчитися. @Serg
Ulises CT

Дозвольте мені задати вам це запитання: Якщо вам абсолютно довелося використовувати робочий стіл Unity, які ще речі ви хотіли б мати? (Очевидно, я намагаюся дослідити ідеї для майбутнього використання :)
Сергій Колодяжний

Єдине, про що я можу придумати - це вкладка "Місця" або "Програми" (якими я не дуже користуюся), решта доступна в Unity теж, мабуть, те, що мені не подобається в gnome, це те, що для меню додатків ви доведеться натискати на кнопку більшості програм (типовий файл, редагувати тощо) меню
Ulises CT
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.