def statusbar(self):
        if self._statusbar:
            return self._statusbar

        self._statusbar = Statusbar()
        self._statusbar.show()

        return self._statusbar
class ApplicationWindow(Gtk.ApplicationWindow):
    _builder = None
    _statusbar = None
    _toolbar = None
    clients = {
        'jira': None,
        'zimbra': None,
        'your_agenda': None
    }

    def __init__(self, application):
        Gtk.ApplicationWindow.__init__(self, application=application, title="Overview")

        self.set_default_size(1024, 768)
        self.set_title("%s v%s" % (application.package, application.version))

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        box.show()

        self.builder.add_from_file('yourtime_tool/ui/settings.glade')
        settings_dialog1 = self.builder.get_object('settings-dialog1')
        settings_button1 = self.builder.get_object('settings-button1')
        settings_button2 = self.builder.get_object('settings-button2')
        settings_button3 = self.builder.get_object('settings-button3')
        settings_dialog1.connect("show", self.on_settings_show)
        settings_button1.connect("clicked", self.on_settings_save)
        settings_button2.connect("clicked", self.on_settings_close)
        settings_button3.connect("clicked", self.on_settings_reset)

        if not self.is_settings_valid():

            # Show settings if any aren't valid
            self.builder.get_object('settings-dialog1').show()

        treeview = self.builder.get_object('overview-treeview1')

        calendar = self.builder.get_object('overview-calendar1')
        calendar.select_month(datetime.date.today().month-1, datetime.date.today().year)
        calendar.select_day(datetime.date.today().day)
        calendar.connect('day-selected', self.signal_calendar1_day_selected)

        self.builder.get_object('cellrenderertext2').connect('edited', self.signal_cell_edited, 1, treeview.get_model())
        self.builder.get_object('cellrenderertext3').connect('edited', self.signal_cell_edited, 2, treeview.get_model())

        self.progressbar = Gtk.ProgressBar()
        self.progressbar.show()

        box2 = Gtk.Box()
        box2.pack_start(self.progressbar, True, True, 12)
        box2.show()

        box.pack_start(self.toolbar, False, False, 0)
        box.pack_start(self.builder.get_object('overview-box1'), False, True, 0)
        box.pack_end(box2, False, False, 12)

        self.builder.get_object('overview-calendar1').emit('day-selected')

        self.add(box)

    @property
    def builder(self):
        if self._builder:
            return self._builder

        self._builder = Gtk.Builder()
        self._builder.add_from_file('yourtime_tool/ui/overview.glade')

        return self._builder

    @property
    def statusbar(self):
        if self._statusbar:
            return self._statusbar

        self._statusbar = Statusbar()
        self._statusbar.show()

        return self._statusbar

    @property
    def toolbar(self):
        if self._toolbar:
            return self._toolbar

        toolbar_uimanager = ToolbarUIManager(self)

        self._toolbar = toolbar_uimanager.get_widget('/ToolBar')
        self._toolbar.show()

        return self._toolbar

    def signal_calendar1_day_selected(self, calendar, *args, **kwargs):

        if not self.is_settings_valid():
            return

        year, month, day = calendar.get_date()

        date = datetime.date(year, month+1, day)

        calendar = self._builder.get_object('overview-calendar1')

        model = self._builder.get_object('overview-treeview1').get_model()
        model.clear()

        def callback(events):

            def _inner(event):
                category = GObject.GObject()
                category.chain = event.get_yt_category()

                model.append((
                    EVENT_TYPE_TO_SOURCE_MAP[event.__class__],
                    to_verbose_duration(event.duration),
                    str(event).strip(),
                    category
                ))

            for event in events:
                # Update model in main thread
                GLib.idle_add(_inner, event)

            calendar.set_sensitive(True)

        # Diable controls to prevent multiple async requests
        calendar.set_sensitive(False)

        thread_pool = self.get_application().thread_pool
        thread_pool.apply_async(self.get_for_date, (date,), callback=callback)

    def signal_cell_edited(self, renderer, path, text, column, model):

        model.set_value(model.get_iter(path), column, text)

        self._builder.get_object('overview-treeview1').queue_draw()

    def row_remove(self):

        selection = self._builder.get_object('overview-treeview1').get_selection()

        model, paths = selection.get_selected_rows()

        # Remove in reversed order since the path also updates when removing a tree iter
        map(model.remove, (model.get_iter(path) for path in reversed(paths)))

    def signal_treeview_save(self):
        model = self._builder.get_object('overview-treeview1').get_model()
        calendar = self._builder.get_object('overview-calendar1')

        year, month, day = calendar.get_date()

        date = datetime.date(year, month+1, day)

        self.progressbar.set_show_text(True)

        for index, row in enumerate(model):
            self.progressbar.set_text('Writing to YourTime... ({}/{})'.format(index+1, len(model)))

            (source, duration, description, category) = row

            yourtime_tool.services.your_time.register(
                date=date,
                duration=duration,
                description=description,
                category=category
            )

            self.progressbar.set_fraction(float(index+1) / len(model))

        self.progressbar.set_fraction(0)
        self.progressbar.set_text('')

    def get_for_date(self, date):
        """
        Returns the information for a specific day.
        """

        zimbra = yourtime_tool.services.zimbra.get_client()
        jira = yourtime_tool.services.jira.get_client()
        your_agenda = yourtime_tool.services.your_agenda.get_client()

        self.progressbar.set_show_text(True)
        self.progressbar.set_text('Retreiving Zimbra data...')

        for appointment in zimbra.get_appointments():
            if appointment.is_on_date(date):
                yield appointment

        self.progressbar.set_fraction(float(20) / 100)
        self.progressbar.set_text('Retreiving Jira data...')

        for work_log in jira.get_work_logs(date):
            if work_log.is_on_date(date):
                yield work_log

        self.progressbar.set_fraction(float(80) / 100)
        self.progressbar.set_text('Retreiving YourAgenda data...')

        for mutation in your_agenda.get_mutations(date.year):
            if mutation.is_on_date(date):
                yield mutation

        self.progressbar.set_fraction(0)
        self.progressbar.set_text('')

    def on_settings_save(self, widget):

        entry1 = self.builder.get_object('settings-entry1').get_text()
        entry2 = self.builder.get_object('settings-entry2').get_text()
        entry3 = self.builder.get_object('settings-entry3').get_text()
        entry4 = self.builder.get_object('settings-entry4').get_text()
        entry5 = self.builder.get_object('settings-entry5').get_text()
        entry6 = self.builder.get_object('settings-entry6').get_text()
        entry7 = self.builder.get_object('settings-entry7').get_text()
        entry8 = self.builder.get_object('settings-entry8').get_text()
        entry9 = self.builder.get_object('settings-entry9').get_text()
        entry10 = self.builder.get_object('settings-entry10').get_text()
        entry11 = self.builder.get_object('settings-entry11').get_text()

        settings.set_string('yourtime-username', entry2)
        settings.set_string('yourtime-password', entry1)
        settings.set_string('jira-username', entry4)
        settings.set_string('jira-password', entry3)
        settings.set_string('zimbra-username', entry6)
        settings.set_string('zimbra-password', entry5)
        settings.set_string('youragenda-employee-id', entry8)
        settings.set_string('youragenda-database-host', entry7)
        settings.set_string('youragenda-database-user', entry9)
        settings.set_string('youragenda-database-password', entry10)
        settings.set_string('youragenda-database-name', entry11)

    def on_settings_show(self, widget):

        entry1 = self.builder.get_object('settings-entry1')
        entry2 = self.builder.get_object('settings-entry2')
        entry3 = self.builder.get_object('settings-entry3')
        entry4 = self.builder.get_object('settings-entry4')
        entry5 = self.builder.get_object('settings-entry5')
        entry6 = self.builder.get_object('settings-entry6')
        entry7 = self.builder.get_object('settings-entry7')
        entry8 = self.builder.get_object('settings-entry8')
        entry9 = self.builder.get_object('settings-entry9')
        entry10 = self.builder.get_object('settings-entry10')
        entry11 = self.builder.get_object('settings-entry11')

        entry2.set_text(settings.get_string('yourtime-username'))
        entry1.set_text(settings.get_string('yourtime-password'))
        entry4.set_text(settings.get_string('jira-username'))
        entry3.set_text(settings.get_string('jira-password'))
        entry6.set_text(settings.get_string('zimbra-username'))
        entry5.set_text(settings.get_string('zimbra-password'))
        entry8.set_text(settings.get_string('youragenda-employee-id'))
        entry7.set_text(settings.get_string('youragenda-database-host'))
        entry9.set_text(settings.get_string('youragenda-database-user'))
        entry10.set_text(settings.get_string('youragenda-database-password'))
        entry11.set_text(settings.get_string('youragenda-database-name'))

    def on_settings_close(self, widget):
        self.builder.get_object('settings-dialog1').hide()

    def on_settings_reset(self, widget):

        settings.reset('yourtime-username')
        settings.reset('yourtime-password')
        settings.reset('jira-username')
        settings.reset('jira-password')
        settings.reset('zimbra-username')
        settings.reset('zimbra-password')
        settings.reset('youragenda-employee-id')
        settings.reset('youragenda-database-host')
        settings.reset('youragenda-database-user')
        settings.reset('youragenda-database-password')
        settings.reset('youragenda-database-name')

        self.on_settings_show(widget)

    def is_settings_valid(self):
        return all([
            yourtime_tool.services.your_time.is_credentials_valid(),
            yourtime_tool.services.jira.is_credentials_valid(),
            yourtime_tool.services.zimbra.is_credentials_valid(),
            yourtime_tool.services.your_agenda.is_credentials_valid()
        ])