มีเมนู "สถานที่" สำหรับ Ubuntu Unity หรือไม่


11

ฉันต้องการทราบว่าเป็นไปได้หรือไม่ที่จะวางแท็บ "สถานที่" ในเมนูด้านบนของ Ubuntu เช่น CentOS, Debian เป็นต้น

ขอบคุณ


ได้อย่างง่ายดาย แต่มันควรจะแสดงอะไรกันแน่?
Jacob Vlijm

โฟลเดอร์หลัก (โฮมดาวน์โหลดเอกสาร ฯลฯ ) และโฟลเดอร์ที่มีบุ๊กมาร์กเช่น debian และ centos
Ulises CT

ฉันเห็นจะเขียนหนึ่งวันนี้หรือพรุ่งนี้ถ้าไม่มีใครทำมาก่อน :) หรืออาจมีอยู่แล้ว (คุณหมายถึงตัวบ่งชี้ใช่มั้ย)
Jacob Vlijm

ค้นหา "เมนูสถานที่ Debian" ใน Google Images และคุณจะเห็นว่าฉันหมายถึงอะไร
Ulises CT

ไม่นี่เป็นเมนูคลาสสิค ทั้งหมดที่ฉันค้นพบนั้นเป็นสิ่งที่ล้าสมัยโดยมีฝุ่นอยู่เพียงนิ้วเดียว ฉันสามารถเขียนแบบพื้นฐานได้อย่างรวดเร็ว (และจะ) ฉันต้องการที่จะรวมเข้ากับสิ่งนี้แม้ว่า: askubuntu.com/questions/803869//ซึ่งจะทำให้มันเป็นโครงการที่น่าสนใจ นัดแรกในวันนี้หรือพรุ่งนี้จะไม่เป็นนัดสุดท้าย เป็นคำถามที่ดี
Jacob Vlijm

คำตอบ:


12

ฉันลองใช้หลายตัวที่มีอยู่แล้ว แต่ไม่พบตัวบ่งชี้สถานที่ทำงาน สิ่งที่ฉันพบนั้นล้าสมัยแล้ว ppa ไม่ได้รับการบำรุงรักษาอีกต่อไป

เมนูสถานที่แบบแยกส่วน

ดังนั้นด้านล่างหนึ่งเขียนสด: สถานที่และตัวบ่งชี้ที่ไฟล์อูบุนตู

ป้อนคำอธิบายรูปภาพที่นี่ 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. หากใช้งานได้ดีให้เพิ่มลงในแอปพลิเคชันเริ่มต้น: Dash> แอปพลิเคชันเริ่มต้น> เพิ่ม เพิ่มคำสั่ง:

    /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 แต่เพราะมันดูสวยกว่านี้ แต่ฉันจะใช้อันนี้กับฟีเจอร์ filess ล่าสุดด้วย! ขอบคุณ
Ulises CT

@Utises CT Ah ขอบคุณที่ทดลองใช้ Unity แม้ว่าคุณจะเปลี่ยนไป!
Jacob Vlijm

ใช่! ปัญหาคือฉันมาจาก Windows สำหรับเดสก์ท็อปพีซีและไม่เคยใช้สิ่งกราฟิกบน Linux เพียงแค่เทอร์มินัลบน CentOS สำหรับเซิร์ฟเวอร์และเช่นนั้นและเมื่อฉันติดตั้ง Ubuntu จาก ubuntu.es ฉันคิดว่า GUI ของมันเป็นแบบนั้นและไม่รู้ มี Gnome และ Unity ที่คุณสามารถเลือกได้ (ฉันพลาดแท็บ Places เพราะมันอยู่บน CentOS ซึ่งฉันพยายามจะลองเป็นเดสก์ท็อป แต่มันแย่มาก) เป็นการดีที่จะเรียนรู้อย่างต่อเนื่อง
Ulises CT

ว้าวความมุ่งมั่นนั้น - เขียนโปรแกรมใหม่เพื่อตอบสนองความต้องการนี้! ประทับใจมากทำได้ดีมาก @JacobVlijm! ทำไมมันถึงเป็นเวอร์ชั่น 0.5.1-1 ถ้าคุณเพิ่งเขียนมันไป?
โฆษณา 20000

@ Ads20000 ขอบคุณ! การปรับปรุงเล็กน้อย; (ใหม่) ไฟล์ที่ถูกย้ายหรือเปลี่ยนชื่อจะถูกทำเครื่องหมายตอนนี้การแจ้งเตือนจะปรากฏขึ้นหากคุณ (ลอง) เพื่อเปิดพวกเขาไอคอนล่าสุดที่แตกต่างกันตอนนี้ยังใช้งานได้ 14.04, การปรับให้เหมาะสมเล็กน้อยของรหัส (กรองอักขระพิเศษในชื่อไฟล์) เป็นต้น
Jacob Vlijm

8

Update Feb / 24/2017 : ตัวบ่งชี้ในขณะนี้มีตัวเลือกสำหรับการตรึงลิงก์ของเว็บ

บทนำ

หมายเหตุ: รุ่นก่อนหน้าของคำตอบนี้สามารถพบได้ในประวัติการแก้ไขแม้ว่ามันจะไม่เกี่ยวข้องอีกต่อไป

ตัวบ่งชี้ที่นำเสนอด้านล่างนี้มีวัตถุประสงค์สำหรับคำถามที่แตกต่างกัน แต่เนื่องจากโอกาสที่นำเสนอด้วยตนเองฉันจึงตัดสินใจที่จะเผยแพร่ที่นี่ ตัวบ่งชี้ไฟล์เป็นตัวบ่งชี้ที่ง่ายสำหรับการเข้าถึงไฟล์และโฟลเดอร์ของผู้ใช้ จะช่วยให้การตรวจสอบไฟล์ที่ใช้เมื่อเร็ว ๆ นี้ไฟล์ที่คั่นหน้าและไดเรกทอรี โดยเฉพาะอย่างยิ่งเมนูสถานที่มีความเกี่ยวข้องกับคำถามนี้โดยเฉพาะ

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

ดังที่คุณเห็นจากภาพหน้าจอตัวบ่งชี้ยังสนับสนุนตำแหน่งอื่นนอกเหนือจากภาษาอังกฤษดังนั้นหากระบบของคุณใช้อย่างอื่นที่ไม่ใช่ภาษาอังกฤษจะทำงานได้

อัปเดต : ขณะนี้ตัวบ่งชี้สนับสนุนการเรียกใช้ไฟล์ .desktop ที่ถูกตรึงไว้ ตัวอย่างเช่นหากคุณติดไฟ firefox.desktop มันจะเปิดตัว firefox ดังนั้นตัวบ่งชี้สามารถใช้เป็นตัวเรียกใช้ด่วนสำหรับโปรแกรม ฟีเจอร์นี้กำลังจะเข้าสู่ PPA ในขณะที่เขียน (19 พ.ย. , 7: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
Ads20000

@ Ads20000 ขอบคุณ :) ตัวบ่งชี้นี้เดิมตั้งใจให้เป็นไฟล์ล่าสุดเท่านั้น เมื่อฉันเห็นคำถามที่ฉันคิดว่าฟีเจอร์นี้น่าจะเพิ่มไปยังตัวบ่งชี้ได้เช่นกันบวกกับมันง่ายมากที่จะติดตั้ง - เอาตัวฉันไปเช้าวันหนึ่งและกาแฟ 2 ถ้วย :) :)
Sergiy Kolodyazhnyy

งานของคุณทำให้มันกลายเป็นOMG! อูบุนตู! บทความ ! : D
Ads20000

อ๋อฉันเห็นแล้วว่า :)
Sergiy Kolodyazhnyy

0

โอเคสิ่งที่ฉันทำก็แค่ติดตั้ง Ubuntu-Gnome และเปิดใช้งานส่วนขยาย 'สถานที่' ในเครื่องมือ Tweak และรับมัน ต้องบอกว่า Ubuntu Gnome นั้นดูดีกว่า Unity มากกว่าเยอะ

ดูแท็บ "Lugares"


ฉลาดเลือก. เห็นได้ชัดตั้งแต่เริ่มต้นที่คุณพึ่งพาการใช้ GNOME เนื่องจากคุณคุ้นเคยกับ CentOS มากกว่า สิ่งที่พวกเขาใช้ใน CentOS ก็คือ GNOME Flashback มันคล้ายกับรุ่นก่อนหน้า แต่ใช้เทคโนโลยีที่ใหม่กว่า สำหรับ Unity นั้นอาจไม่ใช่สำหรับทุกคนแม้ว่าฉันจะไม่ชอบ GNOME มากนักสำหรับการลบคุณลักษณะและการพัฒนาที่ซับซ้อน
Sergiy Kolodyazhnyy

ใช่ฉันว่า "noob" ใน Linux หรือ "ล้าสมัย" ตามที่คุณต้องการจะพูด ฉันหมายความว่าฉันใช้เทอร์มินัลสำหรับเซิร์ฟเวอร์บน CentOS เสมอและไม่ได้มีเนื้อหากราฟิกมากนักฉันไม่ทราบว่ามีตัวเลือกกราฟิกที่แตกต่างกันเช่น Unity และ Gnome ฉันแค่คิดว่าอูบุนตูสามารถดูได้อย่างที่มันเป็น แพคเกจดาวน์โหลด ubuntu.com, CentOS แบบที่มันทำจากหน้าเว็บอย่างเป็นทางการและอื่น ๆ ไม่ทราบว่ามีตัวเลือกกราฟิกที่แตกต่างกันที่คุณมี ดีต่อการเรียนรู้ @Serg
Ulises CT

ให้ฉันถามคำถามนี้กับคุณ: หากคุณต้องใช้เดสก์ท็อป Unity อย่างอื่นคุณต้องการใช้อะไรอีก (เห็นได้ชัดว่าฉันกำลังพยายามค้นหาแนวคิดสำหรับการใช้ในอนาคต :)
Sergiy Kolodyazhnyy

สิ่งเดียวที่ฉันคิดได้ก็คือแท็บ "สถานที่" หรือ "แอปพลิเคชัน" (ซึ่งฉันไม่ได้ใช้จริง ๆ ) ส่วนที่เหลือก็มีใน Unity ด้วยฉันเดาว่าสิ่งที่ฉันไม่ชอบจาก gnome คือสำหรับเมนูแอปพลิเคชันคุณ ต้องคลิกที่ปุ่มบนโปรแกรมส่วนใหญ่ (ไฟล์ทั่วไป, แก้ไข, เมนู ฯลฯ )
Ulises CT
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.