~gnome-zeitgeist/gnome-activity-journal/minimal

« back to all changes in this revision

Viewing changes to src/view.py

  • Committer: tehk
  • Date: 2010-05-04 05:27:03 UTC
  • mfrom: (843.1.42 journal-rewrite)
  • Revision ID: tehk@tehk-desktop-20100504052703-pqp9o4yuewaoc9lv
new-core branch was merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -.- coding: utf-8 -.-
2
 
#
3
 
# GNOME Activity Journal
4
 
#
5
 
# Copyright © 2009-2010 Seif Lotfy <seif@lotfy.com>
6
 
# Copyright © 2010 Siegfried Gevatter <siegfried@gevatter.com>
7
 
#
8
 
# This program is free software: you can redistribute it and/or modify
9
 
# it under the terms of the GNU General Public License as published by
10
 
# the Free Software Foundation, either version 3 of the License, or
11
 
# (at your option) any later version.
12
 
#
13
 
# This program is distributed in the hope that it will be useful,
14
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
# GNU General Public License for more details.
17
 
#
18
 
# You should have received a copy of the GNU General Public License
19
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 
 
21
 
import time
22
 
import datetime
23
 
import gc
24
 
 
25
 
from widgets import *
26
 
from daywidgets import *
27
 
from eventgatherer import datelist
28
 
from config import settings
29
 
 
30
 
 
31
 
def get_seconds_remaining_in_day():
32
 
    return int(86400 - ((time.time()-time.timezone-time.daylight*(60*60)) % 86400) + 4)
33
 
 
34
 
 
35
 
class ActivityView(gtk.VBox):
36
 
    __gsignals__ = {
37
 
        # Sent when date is updated. Sends a start time in seconds, end time in seconds
38
 
        # and a bool that si true if we are in single day view
39
 
        "date-updated" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
40
 
                          (gobject.TYPE_INT, gobject.TYPE_INT, gobject.TYPE_BOOLEAN)),
41
 
        }
42
 
    def __init__(self, cal):
43
 
 
44
 
        gtk.VBox.__init__(self)
45
 
 
46
 
        self.cal = cal
47
 
 
48
 
        self.days = {}
49
 
 
50
 
        self.daysbox = None
51
 
        self.daybox = None
52
 
        self.__first_run = True
53
 
        self.set_num_days(3)
54
 
 
55
 
        self._set_searchbox()
56
 
        self._set_today_timestamp()
57
 
        self._set_view_type()
58
 
        self._set_timeline()
59
 
 
60
 
        def new_day_updater():
61
 
            self.set_views()
62
 
            seconds = get_seconds_remaining_in_day()
63
 
            gobject.timeout_add_seconds(seconds, new_day_updater)
64
 
            return False
65
 
        new_day_updater()
66
 
 
67
 
    def set_num_days(self, dayrange):
68
 
        self.dayrange = dayrange
69
 
        self.cal.histogram.set_selected_range(dayrange)
70
 
        self.set_views()
71
 
 
72
 
    def _set_searchbox(self):
73
 
        self.searchbox = searchbox
74
 
        self.pack_start(self.searchbox, False, False)
75
 
        self.searchbox.connect("search", self._handle_search_results)
76
 
        self.searchbox.connect("clear", self._clear_search_results)
77
 
 
78
 
    def _clear_search_results(self, widget):
79
 
        self.cal.histogram.clear_highlighted()
80
 
        for item in ITEMS:
81
 
            item.highlight()
82
 
 
83
 
    def _handle_search_results(self, widget, results):
84
 
        datastore = self.cal.histogram.get_datastore()
85
 
        keys = []
86
 
        t = time.time()
87
 
        offset =time.mktime(time.gmtime(t)) - time.mktime(time.localtime(t))
88
 
 
89
 
        for r in results:
90
 
            timestamp = int(time.mktime(time.localtime(r[0]))) / 86400
91
 
            keys.append(offset + timestamp*86400)
92
 
 
93
 
        dates = []
94
 
        for i, (date, nitems) in enumerate(datastore):
95
 
            if int(date) in keys:
96
 
                dates.append(i)
97
 
        self.cal.histogram.set_highlighted(dates)
98
 
        for item in ITEMS:
99
 
            item.highlight()
100
 
 
101
 
    def _set_timeline(self):
102
 
        def selection_callback(widget, i):
103
 
            datastore = widget.get_datastore()
104
 
            if i < len(datastore):
105
 
                selection_date = datastore[i][0]
106
 
                end = selection_date  + 86399
107
 
                start = selection_date - (self.dayrange - 1) * 86400
108
 
                self.set_dayrange(start, end)
109
 
        datelist(90, self.cal.histogram.set_datastore)
110
 
        self.cal.histogram.connect("column_clicked", selection_callback)
111
 
 
112
 
    def _set_view_type(self, refresh=False):
113
 
 
114
 
        for w in self:
115
 
            if w != self.searchbox:
116
 
                self.remove(w)
117
 
        self.daysbox = gtk.HBox(True)
118
 
        self.daybox = SingleDayWidget()
119
 
        self.thumbbox = ThumbnailDayWidget()
120
 
        hbox  = gtk.HBox()
121
 
        hbox.pack_start(self.daybox, True, True, 3)
122
 
        hbox2  = gtk.HBox()
123
 
        hbox2.pack_start(self.thumbbox, True, True, 3)
124
 
        self.daybox.connect("unfocus-day", self._zoom_out_day)
125
 
        self.thumbbox.connect("unfocus-day", self._zoom_out_day)
126
 
 
127
 
        self.notebook = gtk.Notebook()
128
 
        self.notebook.set_show_tabs(False)
129
 
        self.notebook.set_show_border(False)
130
 
 
131
 
        self.notebook.append_page(self.daysbox, gtk.Label("Group View"))
132
 
        self.notebook.append_page(hbox, gtk.Label("Day View"))
133
 
        self.notebook.append_page(hbox2, gtk.Label("Thumbnail View"))
134
 
 
135
 
        self.pack_start(self.notebook, True, True, 0)
136
 
        if refresh:
137
 
            self.set_views()
138
 
        self.daysbox.show_all()
139
 
 
140
 
        def change_style(widget, style):
141
 
            rc_style = self.style
142
 
            #color = rc_style.bg[gtk.STATE_NORMAL]
143
 
            self.notebook.set_style(rc_style)
144
 
 
145
 
        self.notebook.connect("style-set", change_style)
146
 
 
147
 
    def jump(self, offset):
148
 
        self.start = self.start + offset
149
 
 
150
 
        if time.time() > self.start:
151
 
            model = self.cal.histogram.get_datastore()
152
 
            if len(model) < 1:
153
 
                return
154
 
            diff = self.start - model[0][0]
155
 
            self.cal.histogram.set_selected(diff / 86400)
156
 
            self.set_dayrange(self.start, self.end+offset)
157
 
 
158
 
    def set_dayrange(self, start, end):
159
 
        self.start = start
160
 
        self.end = end
161
 
        notebook_page = self.notebook.get_current_page()
162
 
        self.dayrange = int(int((end - start)) / 86400) + 1
163
 
        self.set_views()
164
 
        widget = self.daysbox.get_children()[self.dayrange -1]
165
 
        if notebook_page == 1:
166
 
            self.daybox.set_day(widget.day_start, widget.day_end)
167
 
        elif notebook_page == 2:
168
 
            self.thumbbox.set_day(widget.day_start, widget.day_end)
169
 
        if notebook_page in (1, 2):
170
 
            val = True
171
 
        else: val = False
172
 
        self.emit("date-updated", start, end, val)
173
 
 
174
 
    def _set_today_timestamp(self, dayinfocus=None):
175
 
        """
176
 
        Return the dayrange of seconds between the min_timestamp and max_timestamp
177
 
        """
178
 
        # For the local timezone
179
 
        if not dayinfocus:
180
 
            dayinfocus = int(time.mktime(time.strptime(
181
 
                time.strftime("%d %B %Y") , "%d %B %Y")))
182
 
        self.end = dayinfocus + 86399
183
 
        self.start = dayinfocus - (self.dayrange - 1) * 86400
184
 
        self.set_views()
185
 
 
186
 
    def _zoom_out_day(self, widget):
187
 
        offset = self._prezoom_position*86400
188
 
        #_t = (86400 - (time.time() % 86400)) + time.time() + time.timezone
189
 
        #while offset + self.end > _t - 2:
190
 
        #    offset -=86400
191
 
        self.jump(offset)
192
 
        self.notebook.set_current_page(0)
193
 
        self.cal.histogram.set_single_day(False)
194
 
        self.emit("date-updated", self.start, self.end, False)
195
 
 
196
 
    def _zoom_in_day(self, widget, page):
197
 
        i = self.dayrange - 1
198
 
        for w in self.daysbox:
199
 
            if w == widget: break
200
 
            i -= 1
201
 
        self._prezoom_position = i
202
 
        self.notebook.set_current_page(page)
203
 
        self.jump(i*-86400)
204
 
        self.cal.histogram.set_single_day(True)
205
 
        if page == 1:
206
 
            self.daybox.set_day(widget.day_start, widget.day_end)
207
 
        elif page == 2:
208
 
            self.thumbbox.set_day(widget.day_start, widget.day_end)
209
 
 
210
 
 
211
 
    def set_views(self):
212
 
        if not self.daysbox:
213
 
            return # nothing to do - TODO: should this be allowed to happen?
214
 
 
215
 
        new_days = []
216
 
 
217
 
        for i in xrange(self.dayrange):
218
 
            if not settings.get("view", "Journal") == "Journal":
219
 
                i = (self.dayrange - 1) - i
220
 
            ptime =  datetime.datetime.fromtimestamp(
221
 
                self.start + i*86400).strftime("%A, %d %B %Y")
222
 
            if not self.days.has_key(ptime):
223
 
                dayview = DayWidget(self.start + i*86400,
224
 
                    self.start + i*86400 + 86400)
225
 
                dayview.connect("focus-day", self._zoom_in_day)
226
 
                self.days[ptime] = dayview
227
 
            new_days.append(self.days[ptime])
228
 
 
229
 
        widgets = self.daysbox.get_children()
230
 
 
231
 
        diff = 0
232
 
        if len(widgets) > 0:
233
 
            first_day = widgets[0]
234
 
            diff = (new_days[0].day_start - first_day.day_start) / 86400
235
 
 
236
 
        old_days = self.daysbox.get_children()
237
 
 
238
 
        if abs(diff) >= self.dayrange or diff == 0:
239
 
            for w in self.daysbox:
240
 
                self.daysbox.remove(w)
241
 
            for day in new_days:
242
 
                self.daysbox.pack_start(day, True, True, 3)
243
 
                day.refresh()
244
 
 
245
 
        elif diff > 0:
246
 
            for i in xrange(len(new_days)):
247
 
                self.daysbox.pack_start(new_days[i], True, True, 3)
248
 
                new_days[i].refresh()
249
 
 
250
 
            for i in xrange(diff):
251
 
                self.daysbox.remove(old_days[i])
252
 
                old_days[i].unparent()
253
 
 
254
 
        elif diff < 0:
255
 
            old_days.reverse()
256
 
            new_days.reverse()
257
 
            for i in xrange(len(new_days)):
258
 
                self.daysbox.pack_start(new_days[i], True, True, 3)
259
 
                self.daysbox.reorder_child(new_days[i], 0)
260
 
                new_days[i].refresh()
261
 
 
262
 
            # SCROLL HERE to new_days[i]
263
 
 
264
 
            for i in xrange(abs(diff)):
265
 
                self.daysbox.remove(old_days[i])
266
 
                old_days[i].unparent()
267
 
 
268
 
        pinbox.get_events()
269
 
        for day in self.daysbox:
270
 
            day._init_pinbox()
271
 
 
272
 
        del new_days, old_days, diff
273
 
        gc.collect()