Ubuntu Unity에 대한“장소”메뉴가 있습니까?


11

CentOS, Debian 등과 같은 우분투의 상단 메뉴에 "장소"탭을 넣을 수 있는지 알고 싶습니다.

감사


쉽게, 그러나 정확히 무엇을 보여줘야합니까?
Jacob Vlijm

메인 폴더 (홈, 다운로드, 문서 등)와 데비안 및 centos와 같은 책갈피가있는 폴더
Ulises CT

나는 :) 할, 아니면 하나가 이미 존재하기 전에 아무도 다른 않은 경우 하나 오늘 또는 내일 쓸 것, 볼 (당신이 바로, 지표를 의미하지?)
야곱 Vlijm

Google 이미지에서 "장소 메뉴 데비안"을 검색하면 무슨 뜻인지 알 수 있습니다.
Ulises CT

아니, 클래식 메뉴였습니다. 내가 발견 한 것은 먼지가 묻어있는 오래된 물건이었습니다. 나는 기본적인 것을 상당히 빨리 쓸 수있다. 나는 이것을 askubuntu.com/questions/803869/… 와 병합하고 싶기 때문에 흥미로운 프로젝트가 될 것입니다. 따라서 오늘이나 내일의 첫 번째 장면은 마지막 장면이 아닙니다. 좋은 질문.
Jacob Vlijm

답변:


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에서 시도해 보았습니다. 감사합니다! 그러나 나는 그놈이 더 아름답게 보이지만 그놈을 사용하기로 결정했지만 최근 파일 기능에도 이것을 사용할 것입니다! 감사
Ulises CT

@UlisesCT Ah, 전환 한 사실에도 불구하고 Unity를 사용해 주셔서 감사합니다!
Jacob Vlijm

네! 문제는 데스크탑 PC 용 Windows에서 왔으며 Linux에서 그래픽을 사용하지 않았으며 CentOS에서 서버 등을 터미널로 사용하지 않았습니다. Gnome과 Unity가 선택할 수 있습니다 (CentOS에서 데스크탑으로 시도했지만 데스크탑으로 시도했지만 장소 탭을 놓쳤습니다). 계속 배우기 좋은
Ulises CT

와우, 그 헌신-이 요구를 충족시키기 위해 새로운 프로그램을 작성하십시오! @JacobVlijm에서 매우 감동을 받았습니다! 방금 작성한 경우 왜 버전 0.5.1-1입니까?
광고 20000

@ Ads20000 감사합니다! 몇 가지 개선 사항; (재) 이동 또는 이름이 바뀐 파일이 이제 표시되고, 파일을 열려면 알림이 표시됩니다. (최근에 다른 아이콘이) 14.04에서 작동합니다. 코드의 작은 최적화 (파일 이름의 특수 문자 필터링) 등
Jacob Vlijm

8

2017 년 2 월 24 일 업데이트 : 표시기에 웹 링크 고정 옵션이 있습니다.

소개

참고 :이 답변의 이전 버전은 더 이상 관련이 없지만 편집 기록에서 찾을 수 있습니다.

아래 제시된 지표는 다른 질문을위한 것이지만 기회가 제시되었으므로 여기서 발표하기로 결정했습니다. 파일 표시기는 사용자의 파일 및 폴더에 액세스하기위한 간단한 표시기입니다. 최근에 사용한 파일을 확인하고 파일 및 디렉토리를 책갈피에 추가 할 수 있습니다. 특히 장소 메뉴는이 질문과 관련이 있습니다.

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

스크린 샷에서 볼 수 있듯이 표시기는 영어 이외의 로케일도 지원하므로 시스템이 영어 이외의 다른 언어를 사용하는 경우 작동합니다.

업데이트 : 표시기는 이제 고정 된 .desktop 파일 실행을 지원합니다. 예를 들어 firefox.desktop이 고정되어 있으면 firefox가 시작됩니다. 따라서이 표시기는 프로그램의 빠른 실행기로 사용할 수 있습니다. 이 기능은 글을 쓰는 시점에 PPA에 들어가고 있지만 (GMT 11 월 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
광고 20000

@ Ads20000 감사합니다 :)이 표시는 원래 최근 파일에 한합니다. 내가 질문을 보았을 때 나는 기능도 표시등에 추가 할 좋은 것이라고 생각, 플러스 구현하기가 매우 간단했다 - 꽤 많은 일 아침 : 커피 2 잔 날 데려 갔어
세르지 Kolodyazhnyy을

당신의 작업은 또한 OMG 로 만들었습니다 ! 우분투! 기사 ! : D
Ads20000

그래, 나는 그것을 보았다 :)
Sergiy Kolodyazhnyy

0

좋아, 내가 한 일은 Ubuntu-Gnome을 설치하고 Tweak 도구에서 '장소'확장을 활성화하고 얻은 것입니다. 우분투 그놈이 유니티보다 훨씬 더 좋아 보인다고 말해야합니다.

"루가 레스"탭 참조


현명한 선택. 그놈의 사용에 대해 기울이고있는 것은 처음부터 분명했습니다. CentOS에서 더 친숙하기 때문입니다. 그런데 CentOS에서 사용하는 것은 그놈 플래시백입니다. 이전 버전과 시각적으로 유사하지만 최신 기술을 사용합니다. Unity의 경우 모든 사람에게 해당되는 것은 아니지만, 그놈은 끊임없이 기능을 제거하고 개발을 복잡하게 만드는 그놈을 많이 싫어합니다.
Sergiy Kolodyazhnyy

네, 정확히 말해서, 저는 리눅스에 "멍청한"사람이거나 "오래된"사람입니다. 나는 CentOS의 서버에 항상 터미널을 사용했지만 그래픽은 많지 않지만 Unity 및 Gnome과 같은 다른 그래픽 옵션이 있다는 것을 몰랐습니다. 우분투는 그 방식을 볼 수 있다고 생각했습니다. ubuntu.com 다운로드 패키지, CentOS 공식 웹 페이지에서와 같은 방식으로 사용할 수있는 그래픽 선택이 무엇인지 몰랐습니다. 계속 배우는 것이 좋습니다. @Serg
Ulises CT

이 질문을하겠습니다 : Unity 데스크탑을 절대적으로 사용해야한다면, 다른 어떤 것들을 원하십니까? (분명히, 나는 미래의 사용을 위해 아이디어를 연구하려고 노력하고 있습니다 :)
Sergiy Kolodyazhnyy

내가 생각할 수있는 유일한 것은 "장소"탭 또는 "응용 프로그램"(실제로 사용하지 않는)입니다. 나머지에서도 나머지를 사용할 수 있다고 생각합니다. 대부분의 프로그램 (일반적인 파일, 편집 등의 메뉴)에서 버튼을 클릭해야합니다
Ulises CT
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.