~mhall119/hello-unity/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python

# Used for making text translatable
from gettext import gettext as _

# Import the base UI toolkit modules
from gi.repository import Gdk    
from gi.repository import Gtk

from gi.repository import Dee
# FIXME: Some weird bug in Dee or PyGI makes Dee fail unless we probe
#        it *before* we import the Unity module... ?!
_m = dir(Dee.SequenceModel)

# Import the module for creating Application Indicators
# The AppIndicator3 module is provided by libappindicator3
from gi.repository import AppIndicator3

# Import our base module to access icon paths
import hello_unity

# Pre-defining the things we'll use later
INDICATOR_STATUS_LIST = ['Active', 'Attention', 'Passive']
INDICATOR_STATUS_MAP = {
    "Active": AppIndicator3.IndicatorStatus.ACTIVE,
    "Attention": AppIndicator3.IndicatorStatus.ATTENTION,
    "Passive": AppIndicator3.IndicatorStatus.PASSIVE,
}

class HelloIndicator(hello_unity.HelloUnitySection):
    '''
    Adds a section for integrating with Application Indicators
    '''

    def __init__(self, window):

        # Create the AppIndicator for Hello Unity
        self.app_indicator = AppIndicator3.Indicator.new(
                            "hello-unity",
                            hello_unity.get_icon_path(hello_unity.MONO_ICON_PATH),
                            AppIndicator3.IndicatorCategory.APPLICATION_STATUS)

        # Set it to Active by default
        self.app_indicator.set_status (AppIndicator3.IndicatorStatus.ACTIVE)

        # Define an Attention icon for when we change the status
        self.app_indicator.set_attention_icon(hello_unity.get_icon_path(hello_unity.ATTENTION_ICON_PATH))

        # Not displayed in the indicator, but used by HUD
        self.app_indicator.set_title(_('Hello Unity'))

        # Indicators have menus, so we need to make at least a simple one
        self.indicator_menu = Gtk.Menu()

        # Our menu will have only one item, used to display the current status
        # by name
        self.indicator_status = Gtk.MenuItem(_('Active'))
        self.indicator_menu.append(self.indicator_status)
        self.indicator_status.show()

        # Attach this simple menu to the indicator
        self.app_indicator.set_menu(self.indicator_menu)

    def get_controls(self):
        '''
        Creates and returns a Gtk widgets containing the controls for this
        section of Hello Unity
        '''

        # Use a GtkTable to layout the controls
        controls = Gtk.Table(1, 2, False)

        # This will contain out list of indicator status values
        status_changer = Gtk.ComboBoxText.new()

        # Populate the list from our pre-defined variables
        for name in INDICATOR_STATUS_LIST:
            status_changer.append_text(name)

        # Set it to the first status (Active)
        status_changer.set_active(0)

        # Bind changes to the GtkComboBox to a callback function
        status_changer.connect("changed", self.change_indicator_status_from_control)

        # Attach the GtkComboBox along with a label to the controls table
        controls.attach(Gtk.Label(_("Status")), 0, 1, 0, 1)
        controls.attach(status_changer, 1, 2, 0, 1)
        return controls
        
    def change_indicator_status_from_control(self, combo):
        '''
        Callback to handle changes to the indicator status
        '''
        
        # Get the text of the new status from the GtkComboBox
        new_status = combo.get_active_text()

        # Using the pre-defined mapping of status names to variables,
        # set the indicator's status to the new one
        self.app_indicator.set_status(INDICATOR_STATUS_MAP[new_status])

        # Since our indicator's menu shows the text of the status,
        # update it as well
        self.indicator_status.set_label(_(new_status))

    def get_code(self):
        '''
        Gets the code for this section to display in Hello Unity.

        In this case, it will  just read this file's contents
        '''
        
        codefilename = __file__
        if codefilename.endswith('.pyc'):
            codefilename = codefilename[:-1]
        codefile = open(codefilename)
        code = codefile.read()
        codefile.close()
        return code