calendar-management: Move code to GcalNewCalendarPage
This commit is contained in:
@@ -28,117 +28,6 @@
|
|||||||
<property name="vhomogeneous">False</property>
|
<property name="vhomogeneous">False</property>
|
||||||
<property name="transition_type">crossfade</property>
|
<property name="transition_type">crossfade</property>
|
||||||
<signal name="notify::visible-child-name" handler="stack_visible_child_name_changed" object="GcalCalendarManagementDialog" swapped="no"/>
|
<signal name="notify::visible-child-name" handler="stack_visible_child_name_changed" object="GcalCalendarManagementDialog" swapped="no"/>
|
||||||
<child>
|
|
||||||
<object class="GtkGrid" id="web_source_grid">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="border_width">18</property>
|
|
||||||
<property name="row_spacing">16</property>
|
|
||||||
<property name="column_spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="web_description_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label" translatable="yes">Enter the address of the calendar that you want to add. If the calendar belongs to one of your online accounts, you can add it through the <a href="GOA">online account settings</a>.</property>
|
|
||||||
<property name="use_markup">True</property>
|
|
||||||
<property name="wrap">True</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<signal name="activate-link" handler="description_label_link_activated" object="GcalCalendarManagementDialog" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
<property name="width">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="calendar_address_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label" translatable="yes">Calendar Address</property>
|
|
||||||
<property name="xalign">1</property>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkEntry" id="calendar_address_entry">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<signal name="notify::text" handler="url_entry_text_changed" object="GcalCalendarManagementDialog" swapped="no"/>
|
|
||||||
<signal name="activate" handler="calendar_address_activated" object="GcalCalendarManagementDialog" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkRevealer" id="web_sources_revealer">
|
|
||||||
<property name="transition_type">crossfade</property>
|
|
||||||
<property name="transition_duration">200</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox" id="web_sources_listbox_box">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="spacing">6</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="web_sources_calendar_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label" translatable="yes">Calendars</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<attributes>
|
|
||||||
<attribute name="weight" value="bold"/>
|
|
||||||
</attributes>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkScrolledWindow" id="web_list_scrolledwindow">
|
|
||||||
<property name="height_request">100</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="vexpand">True</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkViewport" id="viewport">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="shadow_type">none</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkListBox" id="web_sources_listbox">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="activate_on_single_click">False</property>
|
|
||||||
<property name="selection_mode">none</property>
|
|
||||||
<style>
|
|
||||||
<class name="calendar-list"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">2</property>
|
|
||||||
<property name="width">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="name">create</property>
|
|
||||||
<property name="title" translatable="yes">Add Calendar</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@@ -196,109 +85,4 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
<object class="GtkDialog" id="credentials_dialog">
|
|
||||||
<property name="type_hint">dialog</property>
|
|
||||||
<property name="transient_for">GcalCalendarManagementDialog</property>
|
|
||||||
<child internal-child="vbox">
|
|
||||||
<object class="GtkBox" id="credentials-dialog-vbox1">
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkGrid" id="credentials_grid">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="border_width">12</property>
|
|
||||||
<property name="row_spacing">6</property>
|
|
||||||
<property name="column_spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="credentials_user_dim_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label" translatable="yes">User</property>
|
|
||||||
<property name="xalign">1</property>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="credentials_password_dim_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label" translatable="yes">Password</property>
|
|
||||||
<property name="xalign">1</property>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkEntry" id="credentials_user_entry">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<signal name="activate" handler="credential_entry_activate" object="credentials_dialog" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkEntry" id="credentials_password_entry">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="visibility">False</property>
|
|
||||||
<signal name="activate" handler="credential_entry_activate" object="credentials_dialog" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child type="titlebar">
|
|
||||||
<object class="GtkHeaderBar" id="credentials_headerbar">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="title" translatable="yes">Enter your credentials</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="credentials_cancel_button">
|
|
||||||
<property name="label" translatable="yes">Cancel</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<signal name="clicked" handler="credential_button_clicked" object="GcalCalendarManagementDialog" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="credentials_connect_button">
|
|
||||||
<property name="label" translatable="yes">Connect</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<signal name="clicked" handler="credential_button_clicked" object="GcalCalendarManagementDialog" swapped="no"/>
|
|
||||||
<style>
|
|
||||||
<class name="suggested-action"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="pack_type">end</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</interface>
|
</interface>
|
||||||
|
|||||||
@@ -2,5 +2,213 @@
|
|||||||
<interface>
|
<interface>
|
||||||
<template class="GcalNewCalendarPage" parent="GtkBox">
|
<template class="GcalNewCalendarPage" parent="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkGrid">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="border_width">18</property>
|
||||||
|
<property name="row_spacing">16</property>
|
||||||
|
<property name="column_spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="web_description_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Enter the address of the calendar that you want to add. If the calendar belongs to one of your online accounts, you can add it through the <a href="GOA">online account settings</a>.</property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
<property name="wrap">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<signal name="activate-link" handler="description_label_link_activated" object="GcalNewCalendarPage" swapped="no" />
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
<property name="width">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="calendar_address_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Calendar Address</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label" />
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="calendar_address_entry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<signal name="notify::text" handler="on_url_entry_text_changed_cb" object="GcalNewCalendarPage" swapped="no" />
|
||||||
|
<signal name="activate" handler="on_calendar_address_activated_cb" object="GcalNewCalendarPage" swapped="no" />
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkRevealer" id="web_sources_revealer">
|
||||||
|
<property name="transition_type">crossfade</property>
|
||||||
|
<property name="transition_duration">200</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="web_sources_listbox_box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="web_sources_calendar_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Calendars</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="weight" value="bold" />
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="height_request">100</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkViewport" id="viewport">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="shadow_type">none</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBox" id="web_sources_listbox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="activate_on_single_click">False</property>
|
||||||
|
<property name="selection_mode">none</property>
|
||||||
|
<style>
|
||||||
|
<class name="calendar-list" />
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">2</property>
|
||||||
|
<property name="width">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- Credentials dialog -->
|
||||||
|
<object class="GtkDialog" id="credentials_dialog">
|
||||||
|
<property name="type_hint">dialog</property>
|
||||||
|
<property name="transient_for">GcalNewCalendarPage</property>
|
||||||
|
<child type="titlebar">
|
||||||
|
<object class="GtkHeaderBar" id="credentials_headerbar">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="title" translatable="yes">Enter your credentials</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="credentials_cancel_button">
|
||||||
|
<property name="label" translatable="yes">Cancel</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<signal name="clicked" handler="on_credential_button_clicked_cb" object="GcalNewCalendarPage" swapped="no" />
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="credentials_connect_button">
|
||||||
|
<property name="label" translatable="yes">Connect</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<signal name="clicked" handler="on_credential_button_clicked_cb" object="GcalNewCalendarPage" swapped="no" />
|
||||||
|
<style>
|
||||||
|
<class name="suggested-action" />
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkBox" id="credentials-dialog-vbox1">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkGrid" id="credentials_grid">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="border_width">12</property>
|
||||||
|
<property name="row_spacing">6</property>
|
||||||
|
<property name="column_spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="credentials_user_dim_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">User</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label" />
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="credentials_password_dim_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Password</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label" />
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="credentials_user_entry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<signal name="activate" handler="on_credential_entry_activate_cb" object="credentials_dialog" swapped="no" />
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="credentials_password_entry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="visibility">False</property>
|
||||||
|
<signal name="activate" handler="on_credential_entry_activate_cb" object="credentials_dialog" swapped="no" />
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
|
||||||
</interface>
|
</interface>
|
||||||
|
|||||||
@@ -63,31 +63,12 @@ struct _GcalCalendarManagementDialog
|
|||||||
GtkWidget *headerbar;
|
GtkWidget *headerbar;
|
||||||
GtkWidget *notebook;
|
GtkWidget *notebook;
|
||||||
GtkWidget *stack;
|
GtkWidget *stack;
|
||||||
GtkWidget *web_source_grid;
|
|
||||||
|
|
||||||
/* new source details */
|
|
||||||
GtkWidget *calendar_address_entry;
|
|
||||||
GtkWidget *web_sources_listbox;
|
|
||||||
GtkWidget *web_sources_revealer;
|
|
||||||
|
|
||||||
/* credentials dialog */
|
|
||||||
GtkWidget *credentials_cancel_button;
|
|
||||||
GtkWidget *credentials_connect_button;
|
|
||||||
GtkWidget *credentials_dialog;
|
|
||||||
GtkWidget *credentials_password_entry;
|
|
||||||
GtkWidget *credentials_user_entry;
|
|
||||||
|
|
||||||
gint calendar_address_id;
|
|
||||||
gint validate_url_resource_id;
|
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
GcalCalendarManagementDialogMode mode;
|
GcalCalendarManagementDialogMode mode;
|
||||||
ESource *source;
|
ESource *source;
|
||||||
GList *remote_sources;
|
|
||||||
GcalCalendar *removed_calendar;
|
|
||||||
ESource *old_default_source;
|
ESource *old_default_source;
|
||||||
GBinding *title_bind;
|
GBinding *title_bind;
|
||||||
gboolean prompt_password;
|
|
||||||
|
|
||||||
/* auxiliary */
|
/* auxiliary */
|
||||||
GSimpleActionGroup *action_group;
|
GSimpleActionGroup *action_group;
|
||||||
@@ -105,8 +86,6 @@ typedef enum
|
|||||||
GCAL_ACCOUNT_TYPE_NOT_SUPPORTED
|
GCAL_ACCOUNT_TYPE_NOT_SUPPORTED
|
||||||
} GcalAccountType;
|
} GcalAccountType;
|
||||||
|
|
||||||
#define ENTRY_PROGRESS_TIMEOUT 100
|
|
||||||
|
|
||||||
static void add_button_clicked (GtkWidget *button,
|
static void add_button_clicked (GtkWidget *button,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
@@ -126,18 +105,6 @@ static void calendar_visible_check_toggled (GObject *ob
|
|||||||
static void cancel_button_clicked (GtkWidget *button,
|
static void cancel_button_clicked (GtkWidget *button,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
static void clear_pages (GcalCalendarManagementDialog *dialog);
|
|
||||||
|
|
||||||
static void color_set (GtkColorButton *button,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static void default_check_toggled (GObject *object,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static gboolean description_label_link_activated (GtkWidget *widget,
|
|
||||||
gchar *uri,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static void on_file_activated (GSimpleAction *action,
|
static void on_file_activated (GSimpleAction *action,
|
||||||
GVariant *param,
|
GVariant *param,
|
||||||
@@ -155,22 +122,6 @@ static void response_signal (GtkDialog *di
|
|||||||
gint response_id,
|
gint response_id,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
static gboolean pulse_web_entry (GcalCalendarManagementDialog *dialog);
|
|
||||||
|
|
||||||
static void url_entry_text_changed (GObject *object,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static gboolean validate_url_cb (GcalCalendarManagementDialog *dialog);
|
|
||||||
|
|
||||||
static gint prompt_credentials (GcalCalendarManagementDialog *dialog,
|
|
||||||
gchar **username,
|
|
||||||
gchar **password);
|
|
||||||
|
|
||||||
static void discover_sources_cb (GObject *source,
|
|
||||||
GAsyncResult *result,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GcalCalendarManagementDialog, gcal_calendar_management_dialog, GTK_TYPE_DIALOG)
|
G_DEFINE_TYPE (GcalCalendarManagementDialog, gcal_calendar_management_dialog, GTK_TYPE_DIALOG)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@@ -216,7 +167,7 @@ add_button_clicked (GtkWidget *button,
|
|||||||
gcal_calendar_management_dialog_set_mode (GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data),
|
gcal_calendar_management_dialog_set_mode (GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data),
|
||||||
GCAL_CALENDAR_MANAGEMENT_MODE_NORMAL);
|
GCAL_CALENDAR_MANAGEMENT_MODE_NORMAL);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
if (self->remote_sources != NULL)
|
if (self->remote_sources != NULL)
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
@@ -232,6 +183,7 @@ add_button_clicked (GtkWidget *button,
|
|||||||
gcal_calendar_management_dialog_set_mode (GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data),
|
gcal_calendar_management_dialog_set_mode (GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data),
|
||||||
GCAL_CALENDAR_MANAGEMENT_MODE_NORMAL);
|
GCAL_CALENDAR_MANAGEMENT_MODE_NORMAL);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -276,90 +228,7 @@ cancel_button_clicked (GtkWidget *button,
|
|||||||
{
|
{
|
||||||
GcalCalendarManagementDialog *self = GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data);
|
GcalCalendarManagementDialog *self = GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data);
|
||||||
|
|
||||||
/* Destroy the ongoing created source */
|
gcal_calendar_management_dialog_set_mode (self, GCAL_CALENDAR_MANAGEMENT_MODE_NORMAL);
|
||||||
g_clear_object (&self->source);
|
|
||||||
|
|
||||||
/* Cleanup detected remote sources that weren't added */
|
|
||||||
if (self->remote_sources != NULL)
|
|
||||||
{
|
|
||||||
g_list_free_full (self->remote_sources, g_object_unref);
|
|
||||||
self->remote_sources = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
gcal_calendar_management_dialog_set_mode (GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data), GCAL_CALENDAR_MANAGEMENT_MODE_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
clear_pages (GcalCalendarManagementDialog *dialog)
|
|
||||||
{
|
|
||||||
GList *list;
|
|
||||||
|
|
||||||
gtk_entry_set_text (GTK_ENTRY (dialog->calendar_address_entry), "");
|
|
||||||
gtk_widget_set_sensitive (dialog->add_button, FALSE);
|
|
||||||
|
|
||||||
/* Remove discovered web sources (if any) */
|
|
||||||
list = gtk_container_get_children (GTK_CONTAINER (dialog->web_sources_listbox));
|
|
||||||
g_list_free_full (list, (GDestroyNotify) gtk_widget_destroy);
|
|
||||||
|
|
||||||
gtk_revealer_set_reveal_child (GTK_REVEALER (dialog->web_sources_revealer), FALSE);
|
|
||||||
gtk_widget_hide (dialog->web_sources_revealer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
color_set (GtkColorButton *button,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GcalCalendarManagementDialog *self;
|
|
||||||
ESourceSelectable *extension;
|
|
||||||
GdkRGBA color;
|
|
||||||
|
|
||||||
self = GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data);
|
|
||||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (button), &color);
|
|
||||||
|
|
||||||
extension = E_SOURCE_SELECTABLE (e_source_get_extension (self->source, E_SOURCE_EXTENSION_CALENDAR));
|
|
||||||
e_source_selectable_set_color (extension, gdk_rgba_to_string (&color));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
default_check_toggled (GObject *object,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GcalCalendarManagementDialog *self = GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data);
|
|
||||||
GcalManager *manager;
|
|
||||||
ESource *new_default_source;
|
|
||||||
|
|
||||||
manager = gcal_context_get_manager (self->context);
|
|
||||||
|
|
||||||
/* Retrieve the current default source */
|
|
||||||
if (self->old_default_source == NULL)
|
|
||||||
{
|
|
||||||
GcalCalendar *default_calendar = gcal_manager_get_default_calendar (manager);
|
|
||||||
self->old_default_source = gcal_calendar_get_source (default_calendar);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Keeps toggling between the
|
|
||||||
* current source and the previous
|
|
||||||
* default source.
|
|
||||||
*/
|
|
||||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object)))
|
|
||||||
new_default_source = self->source;
|
|
||||||
else
|
|
||||||
new_default_source = self->old_default_source;
|
|
||||||
|
|
||||||
gcal_manager_set_default_calendar (manager,
|
|
||||||
gcal_manager_get_calendar_from_source (manager, new_default_source));
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
description_label_link_activated (GtkWidget *widget,
|
|
||||||
gchar *uri,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GApplication *app = g_application_get_default ();
|
|
||||||
gcal_utils_launch_online_accounts_panel (g_application_get_dbus_connection (app), NULL, NULL);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -378,7 +247,7 @@ response_signal (GtkDialog *dialog,
|
|||||||
gcal_manager_save_source (manager, self->source);
|
gcal_manager_save_source (manager, self->source);
|
||||||
g_clear_object (&self->source);
|
g_clear_object (&self->source);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
/* Commit the new source; save the current page's source */
|
/* Commit the new source; save the current page's source */
|
||||||
if (self->mode == GCAL_CALENDAR_MANAGEMENT_MODE_NORMAL && response_id == GTK_RESPONSE_APPLY && self->remote_sources != NULL)
|
if (self->mode == GCAL_CALENDAR_MANAGEMENT_MODE_NORMAL && response_id == GTK_RESPONSE_APPLY && self->remote_sources != NULL)
|
||||||
{
|
{
|
||||||
@@ -398,43 +267,10 @@ response_signal (GtkDialog *dialog,
|
|||||||
g_list_free_full (self->remote_sources, g_object_unref);
|
g_list_free_full (self->remote_sources, g_object_unref);
|
||||||
self->remote_sources = NULL;
|
self->remote_sources = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
gtk_widget_hide (GTK_WIDGET (dialog));
|
gtk_widget_hide (GTK_WIDGET (dialog));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void
|
|
||||||
stack_visible_child_name_changed (GObject *object,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GcalCalendarManagementDialog *self;
|
|
||||||
GcalCalendar *calendar;
|
|
||||||
GcalManager *manager;
|
|
||||||
GtkWidget *visible_child;
|
|
||||||
|
|
||||||
self = GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data);
|
|
||||||
manager = gcal_context_get_manager (self->context);
|
|
||||||
calendar = gcal_manager_get_calendar_from_source (manager, self->source);
|
|
||||||
visible_child = gtk_stack_get_visible_child (GTK_STACK (object));
|
|
||||||
|
|
||||||
if (visible_child == self->main_scrolledwindow)
|
|
||||||
{
|
|
||||||
gtk_header_bar_set_title (GTK_HEADER_BAR (self->headerbar), _("Calendar Settings"));
|
|
||||||
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (self->headerbar), NULL);
|
|
||||||
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (self->headerbar), TRUE);
|
|
||||||
gtk_widget_set_visible (self->add_button, FALSE);
|
|
||||||
gtk_widget_set_visible (self->cancel_button, FALSE);
|
|
||||||
gtk_widget_set_visible (self->back_button, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* calendar_path_to_name_suggestion:
|
|
||||||
* @file: a calendar file reference.
|
|
||||||
*
|
|
||||||
* Returns: (transfer full): A calendar name.
|
|
||||||
*/
|
|
||||||
static gchar*
|
static gchar*
|
||||||
calendar_path_to_name_suggestion (GFile *file)
|
calendar_path_to_name_suggestion (GFile *file)
|
||||||
{
|
{
|
||||||
@@ -507,62 +343,6 @@ calendar_file_selected (GtkFileChooser *button,
|
|||||||
gtk_widget_set_sensitive (self->add_button, TRUE);
|
gtk_widget_set_sensitive (self->add_button, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
pulse_web_entry (GcalCalendarManagementDialog *dialog)
|
|
||||||
{
|
|
||||||
gtk_entry_progress_pulse (GTK_ENTRY (dialog->calendar_address_entry));
|
|
||||||
|
|
||||||
dialog->calendar_address_id = g_timeout_add (ENTRY_PROGRESS_TIMEOUT, (GSourceFunc) pulse_web_entry, dialog);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
url_entry_text_changed (GObject *object,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GcalCalendarManagementDialog *self;
|
|
||||||
const gchar* text;
|
|
||||||
|
|
||||||
self = GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data);
|
|
||||||
text = gtk_entry_get_text (GTK_ENTRY (self->calendar_address_entry));
|
|
||||||
|
|
||||||
if (self->calendar_address_id != 0)
|
|
||||||
{
|
|
||||||
g_source_remove (self->calendar_address_id);
|
|
||||||
self->calendar_address_id = 0;
|
|
||||||
|
|
||||||
gtk_entry_set_progress_fraction (GTK_ENTRY (self->calendar_address_entry), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->validate_url_resource_id != 0)
|
|
||||||
{
|
|
||||||
g_source_remove (self->validate_url_resource_id);
|
|
||||||
self->validate_url_resource_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_utf8_strlen (text, -1) != 0)
|
|
||||||
{
|
|
||||||
/* Remove any previous unreleased resource */
|
|
||||||
if (self->validate_url_resource_id != 0)
|
|
||||||
g_source_remove (self->validate_url_resource_id);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* At first, don't bother the user with
|
|
||||||
* the login prompt. Only prompt it when
|
|
||||||
* it fails.
|
|
||||||
*/
|
|
||||||
self->prompt_password = FALSE;
|
|
||||||
|
|
||||||
self->validate_url_resource_id = g_timeout_add (500, (GSourceFunc) validate_url_cb, user_data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gtk_entry_set_progress_fraction (GTK_ENTRY (self->calendar_address_entry), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_file_activated (GSimpleAction *action,
|
on_file_activated (GSimpleAction *action,
|
||||||
GVariant *param,
|
GVariant *param,
|
||||||
@@ -635,407 +415,6 @@ on_web_activated (GSimpleAction *action,
|
|||||||
gcal_calendar_management_dialog_set_mode (GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data), GCAL_CALENDAR_MANAGEMENT_MODE_CREATE_WEB);
|
gcal_calendar_management_dialog_set_mode (GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data), GCAL_CALENDAR_MANAGEMENT_MODE_CREATE_WEB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
calendar_address_activated (GtkEntry *entry,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
g_assert (GCAL_IS_CALENDAR_MANAGEMENT_DIALOG (user_data));
|
|
||||||
|
|
||||||
validate_url_cb (GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data));
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
validate_url_cb (GcalCalendarManagementDialog *dialog)
|
|
||||||
{
|
|
||||||
ESourceAuthentication *auth;
|
|
||||||
ENamedParameters *credentials;
|
|
||||||
ESourceExtension *ext;
|
|
||||||
ESourceWebdav *webdav;
|
|
||||||
ESource *source;
|
|
||||||
g_autoptr (SoupURI) soup_uri;
|
|
||||||
const gchar *uri;
|
|
||||||
const gchar *host, *path;
|
|
||||||
gboolean is_file;
|
|
||||||
|
|
||||||
dialog->validate_url_resource_id = 0;
|
|
||||||
soup_uri = NULL;
|
|
||||||
host = path = NULL;
|
|
||||||
is_file = FALSE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove any reminescent ESources
|
|
||||||
* cached before.
|
|
||||||
*/
|
|
||||||
if (dialog->remote_sources != NULL)
|
|
||||||
{
|
|
||||||
g_list_free_full (dialog->remote_sources, g_object_unref);
|
|
||||||
dialog->remote_sources = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove previous results */
|
|
||||||
g_list_free_full (gtk_container_get_children (GTK_CONTAINER (dialog->web_sources_listbox)),
|
|
||||||
(GDestroyNotify) gtk_widget_destroy);
|
|
||||||
gtk_revealer_set_reveal_child (GTK_REVEALER (dialog->web_sources_revealer), FALSE);
|
|
||||||
|
|
||||||
/* Clear the entry icon */
|
|
||||||
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (dialog->calendar_address_entry), GTK_ENTRY_ICON_SECONDARY, NULL);
|
|
||||||
|
|
||||||
/* Get the hostname and file path from the server */
|
|
||||||
uri = gtk_entry_get_text (GTK_ENTRY (dialog->calendar_address_entry));
|
|
||||||
soup_uri = soup_uri_new (uri);
|
|
||||||
if (!soup_uri)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
host = soup_uri_get_host (soup_uri);
|
|
||||||
path = soup_uri_get_path (soup_uri);
|
|
||||||
|
|
||||||
if (soup_uri_get_scheme (soup_uri) == SOUP_URI_SCHEME_FILE)
|
|
||||||
is_file = TRUE;
|
|
||||||
|
|
||||||
g_debug ("Detected host: '%s', path: '%s'", host, path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the new source and add the needed
|
|
||||||
* extensions.
|
|
||||||
*/
|
|
||||||
source = e_source_new (NULL, NULL, NULL);
|
|
||||||
e_source_set_parent (source, "webcal-stub");
|
|
||||||
|
|
||||||
ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
|
|
||||||
e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "webcal");
|
|
||||||
|
|
||||||
/* Authentication */
|
|
||||||
auth = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
|
|
||||||
e_source_authentication_set_host (auth, host);
|
|
||||||
|
|
||||||
/* Webdav */
|
|
||||||
webdav = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
|
|
||||||
e_source_webdav_set_soup_uri (webdav, soup_uri);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we're dealing with an absolute file path,
|
|
||||||
* there is no need to check the server for more
|
|
||||||
* sources.
|
|
||||||
*/
|
|
||||||
if (is_file)
|
|
||||||
{
|
|
||||||
/* Set the private source so it saves at closing */
|
|
||||||
dialog->remote_sources = g_list_append (dialog->remote_sources, source);
|
|
||||||
|
|
||||||
/* Update buttons */
|
|
||||||
gtk_widget_set_sensitive (dialog->add_button, source != NULL);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pulse the entry while it performs the check */
|
|
||||||
dialog->calendar_address_id = g_timeout_add (ENTRY_PROGRESS_TIMEOUT, (GSourceFunc) pulse_web_entry, dialog);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to retrieve the sources without prompting
|
|
||||||
* username and password. If we get any error,
|
|
||||||
* then it prompts and retry.
|
|
||||||
*/
|
|
||||||
credentials = e_named_parameters_new ();
|
|
||||||
|
|
||||||
if (!dialog->prompt_password)
|
|
||||||
{
|
|
||||||
g_debug ("Trying to connect without credentials...");
|
|
||||||
|
|
||||||
/* NULL credentials */
|
|
||||||
e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_USERNAME, NULL);
|
|
||||||
e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_PASSWORD, NULL);
|
|
||||||
|
|
||||||
e_webdav_discover_sources (source,
|
|
||||||
uri,
|
|
||||||
E_WEBDAV_DISCOVER_SUPPORTS_EVENTS,
|
|
||||||
credentials,
|
|
||||||
NULL,
|
|
||||||
discover_sources_cb,
|
|
||||||
dialog);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gint response;
|
|
||||||
gchar *user, *password;
|
|
||||||
|
|
||||||
g_debug ("No credentials failed, retrying with user credentials...");
|
|
||||||
|
|
||||||
user = password = NULL;
|
|
||||||
response = prompt_credentials (dialog, &user, &password);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User entered username and password, let's try
|
|
||||||
* with it.
|
|
||||||
*/
|
|
||||||
if (response == GTK_RESPONSE_OK)
|
|
||||||
{
|
|
||||||
/* User inputted credentials */
|
|
||||||
e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_USERNAME, user);
|
|
||||||
e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_PASSWORD, password);
|
|
||||||
|
|
||||||
e_webdav_discover_sources (source,
|
|
||||||
uri,
|
|
||||||
E_WEBDAV_DISCOVER_SUPPORTS_EVENTS,
|
|
||||||
credentials,
|
|
||||||
NULL,
|
|
||||||
discover_sources_cb,
|
|
||||||
dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (user);
|
|
||||||
g_free (password);
|
|
||||||
}
|
|
||||||
|
|
||||||
e_named_parameters_free (credentials);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
credential_button_clicked (GtkWidget *button,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GcalCalendarManagementDialog *self = GCAL_CALENDAR_MANAGEMENT_DIALOG(user_data);
|
|
||||||
|
|
||||||
if (button == self->credentials_cancel_button)
|
|
||||||
gtk_dialog_response (GTK_DIALOG (self->credentials_dialog), GTK_RESPONSE_CANCEL);
|
|
||||||
else
|
|
||||||
gtk_dialog_response (GTK_DIALOG (self->credentials_dialog), GTK_RESPONSE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
credential_entry_activate (GtkEntry *entry,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
gtk_dialog_response (GTK_DIALOG (user_data), GTK_RESPONSE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gint
|
|
||||||
prompt_credentials (GcalCalendarManagementDialog *dialog,
|
|
||||||
gchar **username,
|
|
||||||
gchar **password)
|
|
||||||
{
|
|
||||||
gint response;
|
|
||||||
|
|
||||||
/* Cleanup last credentials */
|
|
||||||
gtk_entry_set_text (GTK_ENTRY (dialog->credentials_password_entry), "");
|
|
||||||
gtk_entry_set_text (GTK_ENTRY (dialog->credentials_user_entry), "");
|
|
||||||
|
|
||||||
gtk_widget_grab_focus (dialog->credentials_user_entry);
|
|
||||||
|
|
||||||
/* Show the dialog, then destroy it */
|
|
||||||
response = gtk_dialog_run (GTK_DIALOG (dialog->credentials_dialog));
|
|
||||||
|
|
||||||
if (response == GTK_RESPONSE_OK)
|
|
||||||
{
|
|
||||||
if (username != NULL)
|
|
||||||
*username = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->credentials_user_entry)));
|
|
||||||
|
|
||||||
if (password != NULL)
|
|
||||||
*password = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->credentials_password_entry)));
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_hide (dialog->credentials_dialog);
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ESource*
|
|
||||||
duplicate_source (ESource *source)
|
|
||||||
{
|
|
||||||
ESourceExtension *ext;
|
|
||||||
ESource *new_source;
|
|
||||||
|
|
||||||
g_assert (source && E_IS_SOURCE (source));
|
|
||||||
|
|
||||||
new_source = e_source_new (NULL, NULL, NULL);
|
|
||||||
e_source_set_parent (new_source, "local");
|
|
||||||
|
|
||||||
ext = e_source_get_extension (new_source, E_SOURCE_EXTENSION_CALENDAR);
|
|
||||||
e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "local");
|
|
||||||
|
|
||||||
/* Copy Authentication data */
|
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION))
|
|
||||||
{
|
|
||||||
ESourceAuthentication *new_auth, *parent_auth;
|
|
||||||
|
|
||||||
parent_auth = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
|
|
||||||
new_auth = e_source_get_extension (new_source, E_SOURCE_EXTENSION_AUTHENTICATION);
|
|
||||||
|
|
||||||
e_source_authentication_set_host (new_auth, e_source_authentication_get_host (parent_auth));
|
|
||||||
e_source_authentication_set_method (new_auth, e_source_authentication_get_method (parent_auth));
|
|
||||||
e_source_authentication_set_port (new_auth, e_source_authentication_get_port (parent_auth));
|
|
||||||
e_source_authentication_set_user (new_auth, e_source_authentication_get_user (parent_auth));
|
|
||||||
e_source_authentication_set_proxy_uid (new_auth, e_source_authentication_get_proxy_uid (parent_auth));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy Webdav data */
|
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND))
|
|
||||||
{
|
|
||||||
ESourceWebdav *new_webdav, *parent_webdav;
|
|
||||||
|
|
||||||
parent_webdav = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
|
|
||||||
new_webdav = e_source_get_extension (new_source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
|
|
||||||
|
|
||||||
e_source_webdav_set_display_name (new_webdav, e_source_webdav_get_display_name (parent_webdav));
|
|
||||||
e_source_webdav_set_resource_path (new_webdav, e_source_webdav_get_resource_path (parent_webdav));
|
|
||||||
e_source_webdav_set_resource_query (new_webdav, e_source_webdav_get_resource_query (parent_webdav));
|
|
||||||
e_source_webdav_set_email_address (new_webdav, e_source_webdav_get_email_address (parent_webdav));
|
|
||||||
e_source_webdav_set_ssl_trust (new_webdav, e_source_webdav_get_ssl_trust (parent_webdav));
|
|
||||||
|
|
||||||
e_source_set_parent (new_source, "webcal-stub");
|
|
||||||
e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "webcal");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new_source;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_activated_cb (GtkWidget *check,
|
|
||||||
GParamSpec *spec,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GcalCalendarManagementDialog *self;
|
|
||||||
GtkWidget *row;
|
|
||||||
ESource *source;
|
|
||||||
|
|
||||||
self = GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data);
|
|
||||||
|
|
||||||
row = gtk_widget_get_parent (check);
|
|
||||||
source = g_object_get_data (G_OBJECT (row), "source");
|
|
||||||
|
|
||||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)))
|
|
||||||
self->remote_sources = g_list_prepend (self->remote_sources, source);
|
|
||||||
else
|
|
||||||
self->remote_sources = g_list_remove (self->remote_sources, source);
|
|
||||||
|
|
||||||
gtk_widget_set_sensitive (self->add_button, g_list_length (self->remote_sources) > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
discover_sources_cb (GObject *source,
|
|
||||||
GAsyncResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GcalCalendarManagementDialog *self;
|
|
||||||
GSList *discovered_sources, *user_addresses, *aux;
|
|
||||||
GError *error;
|
|
||||||
|
|
||||||
self = GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data);
|
|
||||||
error = NULL;
|
|
||||||
|
|
||||||
/* Stop the pulsing entry */
|
|
||||||
if (self->calendar_address_id != 0)
|
|
||||||
{
|
|
||||||
gtk_entry_set_progress_fraction (GTK_ENTRY (self->calendar_address_entry), 0);
|
|
||||||
g_source_remove (self->calendar_address_id);
|
|
||||||
self->calendar_address_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!e_webdav_discover_sources_finish (E_SOURCE (source), result, NULL, NULL, &discovered_sources, &user_addresses,
|
|
||||||
&error))
|
|
||||||
{
|
|
||||||
/* Don't add an source with errors */
|
|
||||||
gtk_widget_set_sensitive (self->add_button, FALSE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If it's the first try and things went wrong,
|
|
||||||
* retry with the user credentials. Also, it
|
|
||||||
* checks for the error code, since we don't
|
|
||||||
* really want to retry things on unavailable
|
|
||||||
* servers.
|
|
||||||
*/
|
|
||||||
if (!self->prompt_password &&
|
|
||||||
(error->code == 14 ||
|
|
||||||
error->code == 401 ||
|
|
||||||
error->code == 403 ||
|
|
||||||
error->code == 405))
|
|
||||||
{
|
|
||||||
self->prompt_password = TRUE;
|
|
||||||
|
|
||||||
validate_url_cb (GCAL_CALENDAR_MANAGEMENT_DIALOG (user_data));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_debug ("Error: %s", error->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_error_free (error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a success icon to the entry */
|
|
||||||
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (self->calendar_address_entry), GTK_ENTRY_ICON_SECONDARY,
|
|
||||||
"emblem-ok-symbolic");
|
|
||||||
|
|
||||||
/* Remove previous results */
|
|
||||||
g_list_free_full (gtk_container_get_children (GTK_CONTAINER (self->web_sources_listbox)),
|
|
||||||
(GDestroyNotify) gtk_widget_destroy);
|
|
||||||
|
|
||||||
/* Show the list of calendars */
|
|
||||||
gtk_revealer_set_reveal_child (GTK_REVEALER (self->web_sources_revealer), TRUE);
|
|
||||||
gtk_widget_show (self->web_sources_revealer);
|
|
||||||
|
|
||||||
/* TODO: show a list of calendars */
|
|
||||||
for (aux = discovered_sources; aux != NULL; aux = aux->next)
|
|
||||||
{
|
|
||||||
g_autoptr (SoupURI) soup_uri = NULL;
|
|
||||||
EWebDAVDiscoveredSource *discovered_source;
|
|
||||||
const gchar *resource_path = NULL;
|
|
||||||
|
|
||||||
discovered_source = aux->data;
|
|
||||||
|
|
||||||
soup_uri = soup_uri_new (discovered_source->href);
|
|
||||||
|
|
||||||
/* Get the new resource path from the uri */
|
|
||||||
resource_path = soup_uri_get_path (soup_uri);
|
|
||||||
|
|
||||||
if (soup_uri)
|
|
||||||
{
|
|
||||||
ESourceSelectable *selectable;
|
|
||||||
ESourceWebdav *webdav;
|
|
||||||
GtkWidget *row, *check;
|
|
||||||
ESource *new_source;
|
|
||||||
|
|
||||||
|
|
||||||
/* build up the new source */
|
|
||||||
new_source = duplicate_source (E_SOURCE (source));
|
|
||||||
e_source_set_display_name (E_SOURCE (new_source), discovered_source->display_name);
|
|
||||||
|
|
||||||
webdav = e_source_get_extension (new_source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
|
|
||||||
e_source_webdav_set_resource_path (webdav, resource_path);
|
|
||||||
e_source_webdav_set_display_name (webdav, discovered_source->display_name);
|
|
||||||
|
|
||||||
if (user_addresses)
|
|
||||||
e_source_webdav_set_email_address (webdav, user_addresses->data);
|
|
||||||
|
|
||||||
/* Setup the color */
|
|
||||||
selectable = e_source_get_extension (new_source, E_SOURCE_EXTENSION_CALENDAR);
|
|
||||||
e_source_selectable_set_color (selectable, discovered_source->color);
|
|
||||||
|
|
||||||
/* create the new row */
|
|
||||||
row = gtk_list_box_row_new ();
|
|
||||||
|
|
||||||
check = gtk_check_button_new ();
|
|
||||||
gtk_button_set_label (GTK_BUTTON (check), discovered_source->display_name);
|
|
||||||
g_signal_connect (check, "notify::active", G_CALLBACK (check_activated_cb), user_data);
|
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (row), check);
|
|
||||||
gtk_container_add (GTK_CONTAINER (self->web_sources_listbox), row);
|
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (row), "parent-source", source);
|
|
||||||
g_object_set_data (G_OBJECT (row), "source", new_source);
|
|
||||||
|
|
||||||
gtk_widget_show_all (row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free things up */
|
|
||||||
e_webdav_discover_free_discovered_sources (discovered_sources);
|
|
||||||
g_slist_free_full (user_addresses, g_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_page (GcalCalendarManagementDialog *self,
|
set_page (GcalCalendarManagementDialog *self,
|
||||||
const gchar *page_name,
|
const gchar *page_name,
|
||||||
@@ -1221,34 +600,17 @@ gcal_calendar_management_dialog_class_init (GcalCalendarManagementDialogClass *k
|
|||||||
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, add_button);
|
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, add_button);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, back_button);
|
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, back_button);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, calendar_address_entry);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, cancel_button);
|
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, cancel_button);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, credentials_cancel_button);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, credentials_connect_button);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, credentials_dialog);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, credentials_password_entry);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, credentials_user_entry);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, headerbar);
|
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, headerbar);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, stack);
|
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, stack);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, web_source_grid);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, web_sources_listbox);
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalCalendarManagementDialog, web_sources_revealer);
|
|
||||||
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, add_button_clicked);
|
gtk_widget_class_bind_template_callback (widget_class, add_button_clicked);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, action_widget_activated);
|
gtk_widget_class_bind_template_callback (widget_class, action_widget_activated);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, back_button_clicked);
|
gtk_widget_class_bind_template_callback (widget_class, back_button_clicked);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, calendar_address_activated);
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, calendar_file_selected);
|
gtk_widget_class_bind_template_callback (widget_class, calendar_file_selected);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, calendar_visible_check_toggled);
|
gtk_widget_class_bind_template_callback (widget_class, calendar_visible_check_toggled);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, cancel_button_clicked);
|
gtk_widget_class_bind_template_callback (widget_class, cancel_button_clicked);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, credential_button_clicked);
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, credential_entry_activate);
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, color_set);
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, default_check_toggled);
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, description_label_link_activated);
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, response_signal);
|
gtk_widget_class_bind_template_callback (widget_class, response_signal);
|
||||||
//gtk_widget_class_bind_template_callback (widget_class, stack_visible_child_name_changed);
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, url_entry_text_changed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1270,26 +632,19 @@ void
|
|||||||
gcal_calendar_management_dialog_set_mode (GcalCalendarManagementDialog *dialog,
|
gcal_calendar_management_dialog_set_mode (GcalCalendarManagementDialog *dialog,
|
||||||
GcalCalendarManagementDialogMode mode)
|
GcalCalendarManagementDialogMode mode)
|
||||||
{
|
{
|
||||||
GcalCalendarManagementDialogMode previous_mode = dialog->mode;
|
|
||||||
|
|
||||||
dialog->mode = mode;
|
|
||||||
|
|
||||||
/* Cleanup old data */
|
|
||||||
clear_pages (dialog);
|
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case GCAL_CALENDAR_MANAGEMENT_MODE_CREATE:
|
case GCAL_CALENDAR_MANAGEMENT_MODE_CREATE:
|
||||||
gtk_header_bar_set_title (GTK_HEADER_BAR (dialog->headerbar), _("Add Calendar"));
|
gtk_header_bar_set_title (GTK_HEADER_BAR (dialog->headerbar), _("Add Calendar"));
|
||||||
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (dialog->headerbar), NULL);
|
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (dialog->headerbar), NULL);
|
||||||
gtk_stack_set_visible_child (GTK_STACK (dialog->stack), GTK_WIDGET (dialog->pages[GCAL_PAGE_EDIT_CALENDAR]));
|
gtk_stack_set_visible_child (GTK_STACK (dialog->stack), GTK_WIDGET (dialog->pages[GCAL_PAGE_NEW_CALENDAR]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GCAL_CALENDAR_MANAGEMENT_MODE_CREATE_WEB:
|
case GCAL_CALENDAR_MANAGEMENT_MODE_CREATE_WEB:
|
||||||
gtk_header_bar_set_title (GTK_HEADER_BAR (dialog->headerbar), _("Add Calendar"));
|
gtk_header_bar_set_title (GTK_HEADER_BAR (dialog->headerbar), _("Add Calendar"));
|
||||||
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (dialog->headerbar), NULL);
|
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (dialog->headerbar), NULL);
|
||||||
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (dialog->headerbar), FALSE);
|
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (dialog->headerbar), FALSE);
|
||||||
gtk_stack_set_visible_child (GTK_STACK (dialog->stack), dialog->web_source_grid);
|
gtk_stack_set_visible_child (GTK_STACK (dialog->stack), GTK_WIDGET (dialog->pages[GCAL_PAGE_NEW_CALENDAR]));
|
||||||
gtk_widget_set_visible (dialog->add_button, TRUE);
|
gtk_widget_set_visible (dialog->add_button, TRUE);
|
||||||
gtk_widget_set_visible (dialog->cancel_button, TRUE);
|
gtk_widget_set_visible (dialog->cancel_button, TRUE);
|
||||||
break;
|
break;
|
||||||
@@ -1310,9 +665,6 @@ gcal_calendar_management_dialog_set_mode (GcalCalendarManagementDialog *dial
|
|||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (previous_mode == mode)
|
|
||||||
// stack_visible_child_name_changed (G_OBJECT (dialog->stack), NULL, dialog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,15 +24,35 @@
|
|||||||
|
|
||||||
#include "gcal-context.h"
|
#include "gcal-context.h"
|
||||||
#include "gcal-calendar-management-page.h"
|
#include "gcal-calendar-management-page.h"
|
||||||
|
#include "gcal-debug.h"
|
||||||
#include "gcal-new-calendar-page.h"
|
#include "gcal-new-calendar-page.h"
|
||||||
|
|
||||||
|
#define ENTRY_PROGRESS_TIMEOUT 100 // ms
|
||||||
|
|
||||||
struct _GcalNewCalendarPage
|
struct _GcalNewCalendarPage
|
||||||
{
|
{
|
||||||
GtkBox parent;
|
GtkBox parent;
|
||||||
|
|
||||||
|
GtkEntry *calendar_address_entry;
|
||||||
|
GtkWidget *credentials_cancel_button;
|
||||||
|
GtkWidget *credentials_connect_button;
|
||||||
|
GtkWidget *credentials_dialog;
|
||||||
|
GtkEntry *credentials_password_entry;
|
||||||
|
GtkEntry *credentials_user_entry;
|
||||||
|
GtkWidget *web_sources_listbox;
|
||||||
|
GtkWidget *web_sources_revealer;
|
||||||
|
|
||||||
|
guint calendar_address_id;
|
||||||
|
gboolean prompt_password;
|
||||||
|
GList *remote_sources;
|
||||||
|
guint validate_url_resource_id;
|
||||||
|
|
||||||
GcalContext *context;
|
GcalContext *context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean validate_url_cb (GcalNewCalendarPage *self);
|
||||||
|
|
||||||
static void gcal_calendar_management_page_iface_init (GcalCalendarManagementPageInterface *iface);
|
static void gcal_calendar_management_page_iface_init (GcalCalendarManagementPageInterface *iface);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GcalNewCalendarPage, gcal_new_calendar_page, GTK_TYPE_BOX,
|
G_DEFINE_TYPE_WITH_CODE (GcalNewCalendarPage, gcal_new_calendar_page, GTK_TYPE_BOX,
|
||||||
@@ -46,6 +66,442 @@ enum
|
|||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auxiliary methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
static ESource*
|
||||||
|
duplicate_source (ESource *source)
|
||||||
|
{
|
||||||
|
ESourceExtension *ext;
|
||||||
|
ESource *new_source;
|
||||||
|
|
||||||
|
g_assert (source && E_IS_SOURCE (source));
|
||||||
|
|
||||||
|
new_source = e_source_new (NULL, NULL, NULL);
|
||||||
|
e_source_set_parent (new_source, "local");
|
||||||
|
|
||||||
|
ext = e_source_get_extension (new_source, E_SOURCE_EXTENSION_CALENDAR);
|
||||||
|
e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "local");
|
||||||
|
|
||||||
|
/* Copy Authentication data */
|
||||||
|
if (e_source_has_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION))
|
||||||
|
{
|
||||||
|
ESourceAuthentication *new_auth, *parent_auth;
|
||||||
|
|
||||||
|
parent_auth = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
|
||||||
|
new_auth = e_source_get_extension (new_source, E_SOURCE_EXTENSION_AUTHENTICATION);
|
||||||
|
|
||||||
|
e_source_authentication_set_host (new_auth, e_source_authentication_get_host (parent_auth));
|
||||||
|
e_source_authentication_set_method (new_auth, e_source_authentication_get_method (parent_auth));
|
||||||
|
e_source_authentication_set_port (new_auth, e_source_authentication_get_port (parent_auth));
|
||||||
|
e_source_authentication_set_user (new_auth, e_source_authentication_get_user (parent_auth));
|
||||||
|
e_source_authentication_set_proxy_uid (new_auth, e_source_authentication_get_proxy_uid (parent_auth));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy Webdav data */
|
||||||
|
if (e_source_has_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND))
|
||||||
|
{
|
||||||
|
ESourceWebdav *new_webdav, *parent_webdav;
|
||||||
|
|
||||||
|
parent_webdav = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
|
||||||
|
new_webdav = e_source_get_extension (new_source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
|
||||||
|
|
||||||
|
e_source_webdav_set_display_name (new_webdav, e_source_webdav_get_display_name (parent_webdav));
|
||||||
|
e_source_webdav_set_resource_path (new_webdav, e_source_webdav_get_resource_path (parent_webdav));
|
||||||
|
e_source_webdav_set_resource_query (new_webdav, e_source_webdav_get_resource_query (parent_webdav));
|
||||||
|
e_source_webdav_set_email_address (new_webdav, e_source_webdav_get_email_address (parent_webdav));
|
||||||
|
e_source_webdav_set_ssl_trust (new_webdav, e_source_webdav_get_ssl_trust (parent_webdav));
|
||||||
|
|
||||||
|
e_source_set_parent (new_source, "webcal-stub");
|
||||||
|
e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "webcal");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
prompt_credentials (GcalNewCalendarPage *self,
|
||||||
|
gchar **username,
|
||||||
|
gchar **password)
|
||||||
|
{
|
||||||
|
gint response;
|
||||||
|
|
||||||
|
/* Cleanup last credentials */
|
||||||
|
gtk_entry_set_text (self->credentials_password_entry, "");
|
||||||
|
gtk_entry_set_text (self->credentials_user_entry, "");
|
||||||
|
|
||||||
|
gtk_widget_grab_focus (GTK_WIDGET (self->credentials_user_entry));
|
||||||
|
|
||||||
|
/* Show the dialog, then destroy it */
|
||||||
|
response = gtk_dialog_run (GTK_DIALOG (self->credentials_dialog));
|
||||||
|
|
||||||
|
if (response == GTK_RESPONSE_OK)
|
||||||
|
{
|
||||||
|
if (username)
|
||||||
|
*username = g_strdup (gtk_entry_get_text (self->credentials_user_entry));
|
||||||
|
|
||||||
|
if (password)
|
||||||
|
*password = g_strdup (gtk_entry_get_text (self->credentials_password_entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_hide (self->credentials_dialog);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callbacks
|
||||||
|
*/
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
pulse_web_entry (GcalNewCalendarPage *self)
|
||||||
|
{
|
||||||
|
gtk_entry_progress_pulse (self->calendar_address_entry);
|
||||||
|
|
||||||
|
self->calendar_address_id = g_timeout_add (ENTRY_PROGRESS_TIMEOUT, (GSourceFunc) pulse_web_entry, self);
|
||||||
|
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_check_activated_cb (GtkWidget *check,
|
||||||
|
GParamSpec *spec,
|
||||||
|
GcalNewCalendarPage *self)
|
||||||
|
{
|
||||||
|
GtkWidget *row;
|
||||||
|
ESource *source;
|
||||||
|
|
||||||
|
row = gtk_widget_get_parent (check);
|
||||||
|
source = g_object_get_data (G_OBJECT (row), "source");
|
||||||
|
|
||||||
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)))
|
||||||
|
self->remote_sources = g_list_prepend (self->remote_sources, source);
|
||||||
|
else
|
||||||
|
self->remote_sources = g_list_remove (self->remote_sources, source);
|
||||||
|
|
||||||
|
//gtk_widget_set_sensitive (self->add_button, g_list_length (self->remote_sources) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
discover_sources_cb (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GcalNewCalendarPage *self;
|
||||||
|
GSList *discovered_sources;
|
||||||
|
GSList *user_addresses;
|
||||||
|
GSList *aux;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
self = GCAL_NEW_CALENDAR_PAGE (user_data);
|
||||||
|
error = NULL;
|
||||||
|
|
||||||
|
/* Stop the pulsing entry */
|
||||||
|
if (self->calendar_address_id != 0)
|
||||||
|
{
|
||||||
|
gtk_entry_set_progress_fraction (GTK_ENTRY (self->calendar_address_entry), 0);
|
||||||
|
g_source_remove (self->calendar_address_id);
|
||||||
|
self->calendar_address_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!e_webdav_discover_sources_finish (E_SOURCE (source), result, NULL, NULL, &discovered_sources, &user_addresses,
|
||||||
|
&error))
|
||||||
|
{
|
||||||
|
/* Don't add an source with errors */
|
||||||
|
//gtk_widget_set_sensitive (self->add_button, FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it's the first try and things went wrong, retry with the user
|
||||||
|
* credentials. Also, it checks for the error code, since we don't
|
||||||
|
* really want to retry things on unavailable servers.
|
||||||
|
*/
|
||||||
|
if (!self->prompt_password &&
|
||||||
|
(error->code == 14 ||
|
||||||
|
error->code == 401 ||
|
||||||
|
error->code == 403 ||
|
||||||
|
error->code == 405))
|
||||||
|
{
|
||||||
|
self->prompt_password = TRUE;
|
||||||
|
validate_url_cb (self);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_debug ("Error: %s", error->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a success icon to the entry */
|
||||||
|
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (self->calendar_address_entry), GTK_ENTRY_ICON_SECONDARY,
|
||||||
|
"emblem-ok-symbolic");
|
||||||
|
|
||||||
|
/* Remove previous results */
|
||||||
|
g_list_free_full (gtk_container_get_children (GTK_CONTAINER (self->web_sources_listbox)),
|
||||||
|
(GDestroyNotify) gtk_widget_destroy);
|
||||||
|
|
||||||
|
/* Show the list of calendars */
|
||||||
|
gtk_revealer_set_reveal_child (GTK_REVEALER (self->web_sources_revealer), TRUE);
|
||||||
|
gtk_widget_show (self->web_sources_revealer);
|
||||||
|
|
||||||
|
/* TODO: show a list of calendars */
|
||||||
|
for (aux = discovered_sources; aux != NULL; aux = aux->next)
|
||||||
|
{
|
||||||
|
g_autoptr (SoupURI) soup_uri = NULL;
|
||||||
|
EWebDAVDiscoveredSource *discovered_source;
|
||||||
|
const gchar *resource_path = NULL;
|
||||||
|
|
||||||
|
discovered_source = aux->data;
|
||||||
|
|
||||||
|
soup_uri = soup_uri_new (discovered_source->href);
|
||||||
|
|
||||||
|
/* Get the new resource path from the uri */
|
||||||
|
resource_path = soup_uri_get_path (soup_uri);
|
||||||
|
|
||||||
|
if (soup_uri)
|
||||||
|
{
|
||||||
|
ESourceSelectable *selectable;
|
||||||
|
ESourceWebdav *webdav;
|
||||||
|
GtkWidget *row, *check;
|
||||||
|
ESource *new_source;
|
||||||
|
|
||||||
|
|
||||||
|
/* build up the new source */
|
||||||
|
new_source = duplicate_source (E_SOURCE (source));
|
||||||
|
e_source_set_display_name (E_SOURCE (new_source), discovered_source->display_name);
|
||||||
|
|
||||||
|
webdav = e_source_get_extension (new_source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
|
||||||
|
e_source_webdav_set_resource_path (webdav, resource_path);
|
||||||
|
e_source_webdav_set_display_name (webdav, discovered_source->display_name);
|
||||||
|
|
||||||
|
if (user_addresses)
|
||||||
|
e_source_webdav_set_email_address (webdav, user_addresses->data);
|
||||||
|
|
||||||
|
/* Setup the color */
|
||||||
|
selectable = e_source_get_extension (new_source, E_SOURCE_EXTENSION_CALENDAR);
|
||||||
|
e_source_selectable_set_color (selectable, discovered_source->color);
|
||||||
|
|
||||||
|
/* create the new row */
|
||||||
|
row = gtk_list_box_row_new ();
|
||||||
|
|
||||||
|
check = gtk_check_button_new ();
|
||||||
|
gtk_button_set_label (GTK_BUTTON (check), discovered_source->display_name);
|
||||||
|
g_signal_connect (check, "notify::active", G_CALLBACK (on_check_activated_cb), self);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (row), check);
|
||||||
|
gtk_container_add (GTK_CONTAINER (self->web_sources_listbox), row);
|
||||||
|
|
||||||
|
g_object_set_data (G_OBJECT (row), "parent-source", source);
|
||||||
|
g_object_set_data (G_OBJECT (row), "source", new_source);
|
||||||
|
|
||||||
|
gtk_widget_show_all (row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free things up */
|
||||||
|
e_webdav_discover_free_discovered_sources (discovered_sources);
|
||||||
|
g_slist_free_full (user_addresses, g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
validate_url_cb (GcalNewCalendarPage *self)
|
||||||
|
{
|
||||||
|
ESourceAuthentication *auth;
|
||||||
|
ENamedParameters *credentials;
|
||||||
|
ESourceExtension *ext;
|
||||||
|
ESourceWebdav *webdav;
|
||||||
|
ESource *source;
|
||||||
|
g_autoptr (SoupURI) soup_uri;
|
||||||
|
const gchar *uri;
|
||||||
|
const gchar *host, *path;
|
||||||
|
gboolean is_file;
|
||||||
|
|
||||||
|
self->validate_url_resource_id = 0;
|
||||||
|
soup_uri = NULL;
|
||||||
|
host = path = NULL;
|
||||||
|
is_file = FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove any reminescent ESources
|
||||||
|
* cached before.
|
||||||
|
*/
|
||||||
|
if (self->remote_sources)
|
||||||
|
{
|
||||||
|
g_list_free_full (self->remote_sources, g_object_unref);
|
||||||
|
self->remote_sources = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove previous results */
|
||||||
|
g_list_free_full (gtk_container_get_children (GTK_CONTAINER (self->web_sources_listbox)),
|
||||||
|
(GDestroyNotify) gtk_widget_destroy);
|
||||||
|
gtk_revealer_set_reveal_child (GTK_REVEALER (self->web_sources_revealer), FALSE);
|
||||||
|
|
||||||
|
/* Clear the entry icon */
|
||||||
|
gtk_entry_set_icon_from_icon_name (self->calendar_address_entry, GTK_ENTRY_ICON_SECONDARY, NULL);
|
||||||
|
|
||||||
|
/* Get the hostname and file path from the server */
|
||||||
|
uri = gtk_entry_get_text (self->calendar_address_entry);
|
||||||
|
soup_uri = soup_uri_new (uri);
|
||||||
|
if (!soup_uri)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
host = soup_uri_get_host (soup_uri);
|
||||||
|
path = soup_uri_get_path (soup_uri);
|
||||||
|
|
||||||
|
if (soup_uri_get_scheme (soup_uri) == SOUP_URI_SCHEME_FILE)
|
||||||
|
is_file = TRUE;
|
||||||
|
|
||||||
|
g_debug ("Detected host: '%s', path: '%s'", host, path);
|
||||||
|
|
||||||
|
/* Create the new source and add the needed extensions */
|
||||||
|
source = e_source_new (NULL, NULL, NULL);
|
||||||
|
e_source_set_parent (source, "webcal-stub");
|
||||||
|
|
||||||
|
ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
|
||||||
|
e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "webcal");
|
||||||
|
|
||||||
|
/* Authentication */
|
||||||
|
auth = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
|
||||||
|
e_source_authentication_set_host (auth, host);
|
||||||
|
|
||||||
|
/* Webdav */
|
||||||
|
webdav = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
|
||||||
|
e_source_webdav_set_soup_uri (webdav, soup_uri);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're dealing with an absolute file path, there is no need
|
||||||
|
* to check the server for more sources.
|
||||||
|
*/
|
||||||
|
if (is_file)
|
||||||
|
{
|
||||||
|
self->remote_sources = g_list_append (self->remote_sources, source);
|
||||||
|
//gtk_widget_set_sensitive (self->add_button, source != NULL);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pulse the entry while it performs the check */
|
||||||
|
self->calendar_address_id = g_timeout_add (ENTRY_PROGRESS_TIMEOUT, (GSourceFunc) pulse_web_entry, self);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to retrieve the sources without prompting
|
||||||
|
* username and password. If we get any error,
|
||||||
|
* then it prompts and retry.
|
||||||
|
*/
|
||||||
|
credentials = e_named_parameters_new ();
|
||||||
|
|
||||||
|
if (!self->prompt_password)
|
||||||
|
{
|
||||||
|
g_debug ("Trying to connect without credentials...");
|
||||||
|
|
||||||
|
/* NULL credentials */
|
||||||
|
e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_USERNAME, NULL);
|
||||||
|
e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_PASSWORD, NULL);
|
||||||
|
|
||||||
|
e_webdav_discover_sources (source,
|
||||||
|
uri,
|
||||||
|
E_WEBDAV_DISCOVER_SUPPORTS_EVENTS,
|
||||||
|
credentials,
|
||||||
|
NULL,
|
||||||
|
discover_sources_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_autofree gchar *password = NULL;
|
||||||
|
g_autofree gchar *user = NULL;
|
||||||
|
gint response;
|
||||||
|
|
||||||
|
g_debug ("No credentials failed, retrying with user credentials...");
|
||||||
|
|
||||||
|
user = password = NULL;
|
||||||
|
response = prompt_credentials (self, &user, &password);
|
||||||
|
|
||||||
|
if (response == GTK_RESPONSE_OK)
|
||||||
|
{
|
||||||
|
e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_USERNAME, user);
|
||||||
|
e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_PASSWORD, password);
|
||||||
|
|
||||||
|
e_webdav_discover_sources (source,
|
||||||
|
uri,
|
||||||
|
E_WEBDAV_DISCOVER_SUPPORTS_EVENTS,
|
||||||
|
credentials,
|
||||||
|
NULL,
|
||||||
|
discover_sources_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e_named_parameters_free (credentials);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_calendar_address_activated_cb (GtkEntry *entry,
|
||||||
|
GcalNewCalendarPage *self)
|
||||||
|
{
|
||||||
|
validate_url_cb (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_credential_button_clicked_cb (GtkWidget *button,
|
||||||
|
GcalNewCalendarPage *self)
|
||||||
|
{
|
||||||
|
if (button == self->credentials_cancel_button)
|
||||||
|
gtk_dialog_response (GTK_DIALOG (self->credentials_dialog), GTK_RESPONSE_CANCEL);
|
||||||
|
else
|
||||||
|
gtk_dialog_response (GTK_DIALOG (self->credentials_dialog), GTK_RESPONSE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_credential_entry_activate_cb (GtkEntry *entry,
|
||||||
|
GtkDialog *dialog)
|
||||||
|
{
|
||||||
|
gtk_dialog_response (dialog, GTK_RESPONSE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_url_entry_text_changed_cb (GtkEntry *entry,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
GcalNewCalendarPage *self)
|
||||||
|
{
|
||||||
|
const gchar* text;
|
||||||
|
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
|
text = gtk_entry_get_text (entry);
|
||||||
|
|
||||||
|
if (self->calendar_address_id != 0)
|
||||||
|
{
|
||||||
|
gtk_entry_set_progress_fraction (entry, 0);
|
||||||
|
g_clear_handle_id (&self->calendar_address_id, g_source_remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->validate_url_resource_id != 0)
|
||||||
|
g_clear_handle_id (&self->validate_url_resource_id, g_source_remove);
|
||||||
|
|
||||||
|
if (g_utf8_strlen (text, -1) > 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* At first, don't bother the user with the login prompt. Only prompt it when
|
||||||
|
* it fails.
|
||||||
|
*/
|
||||||
|
self->prompt_password = FALSE;
|
||||||
|
self->validate_url_resource_id = g_timeout_add (500, (GSourceFunc) validate_url_cb, self);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_entry_set_progress_fraction (self->calendar_address_entry, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GCAL_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GcalCalendarManagementPage iface
|
* GcalCalendarManagementPage iface
|
||||||
*/
|
*/
|
||||||
@@ -62,11 +518,26 @@ gcal_new_calendar_page_get_title (GcalCalendarManagementPage *page)
|
|||||||
return _("New Calendar");
|
return _("New Calendar");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_new_calendar_page_deactivate (GcalCalendarManagementPage *page)
|
||||||
|
{
|
||||||
|
GcalNewCalendarPage *self = GCAL_NEW_CALENDAR_PAGE (page);
|
||||||
|
|
||||||
|
//g_clear_object (&self->source);
|
||||||
|
|
||||||
|
if (self->remote_sources)
|
||||||
|
{
|
||||||
|
g_list_free_full (self->remote_sources, g_object_unref);
|
||||||
|
self->remote_sources = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gcal_calendar_management_page_iface_init (GcalCalendarManagementPageInterface *iface)
|
gcal_calendar_management_page_iface_init (GcalCalendarManagementPageInterface *iface)
|
||||||
{
|
{
|
||||||
iface->get_name = gcal_new_calendar_page_get_name;
|
iface->get_name = gcal_new_calendar_page_get_name;
|
||||||
iface->get_title = gcal_new_calendar_page_get_title;
|
iface->get_title = gcal_new_calendar_page_get_title;
|
||||||
|
iface->deactivate = gcal_new_calendar_page_deactivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -135,6 +606,20 @@ gcal_new_calendar_page_class_init (GcalNewCalendarPageClass *klass)
|
|||||||
g_object_class_override_property (object_class, PROP_CONTEXT, "context");
|
g_object_class_override_property (object_class, PROP_CONTEXT, "context");
|
||||||
|
|
||||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/new-calendar-page.ui");
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/new-calendar-page.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, calendar_address_entry);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_cancel_button);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_connect_button);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_dialog);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_password_entry);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_user_entry);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, web_sources_listbox);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, web_sources_revealer);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, on_calendar_address_activated_cb);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, on_credential_button_clicked_cb);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, on_credential_entry_activate_cb);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, on_url_entry_text_changed_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
Reference in New Issue
Block a user